xref: /haiku/src/kits/media/SoundFile.cpp (revision aa94570a34695672df9b47adda2257f75d8da880)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: SoundFile.cpp
4  *  DESCR:
5  ***********************************************************************/
6 #include <MediaFile.h>
7 #include <MediaTrack.h>
8 #include <SoundFile.h>
9 #include "debug.h"
10 
11 /*************************************************************
12  * public BSoundFile
13  *************************************************************/
14 
15 BSoundFile::BSoundFile()
16 {
17 	_init_raw_stats();
18 }
19 
20 
21 BSoundFile::BSoundFile(const entry_ref *ref,
22 					   uint32 open_mode)
23 {
24 	_init_raw_stats();
25 	SetTo(ref,open_mode);
26 }
27 
28 /* virtual */
29 BSoundFile::~BSoundFile()
30 {
31 	delete fSoundFile;
32 }
33 
34 
35 status_t
36 BSoundFile::InitCheck() const
37 {
38 	if (!fSoundFile) {
39 		return B_NO_INIT;
40 	}
41 	return fSoundFile->InitCheck();
42 }
43 
44 
45 status_t
46 BSoundFile::SetTo(const entry_ref *ref,
47 				  uint32 open_mode)
48 {
49 	if (fMediaTrack) {
50 		BMediaTrack * track = fMediaTrack;
51 		fMediaTrack = 0;
52 		fMediaFile->ReleaseTrack(track);
53 	}
54 	if (fMediaFile) {
55 		BMediaFile * file = fMediaFile;
56 		fMediaFile = 0;
57 		delete file;
58 	}
59 	if (fSoundFile) {
60 		BFile * file = fSoundFile;
61 		fSoundFile = 0;
62 		delete file;
63 	}
64 	if (open_mode == B_READ_ONLY) {
65 		return _ref_to_file(ref);
66 	} else {
67 		UNIMPLEMENTED();
68 		return B_ERROR;
69 	}
70 }
71 
72 
73 int32
74 BSoundFile::FileFormat() const
75 {
76 	return fFileFormat;
77 }
78 
79 
80 int32
81 BSoundFile::SamplingRate() const
82 {
83 	return fSamplingRate;
84 }
85 
86 
87 int32
88 BSoundFile::CountChannels() const
89 {
90 	return fChannelCount;
91 }
92 
93 
94 int32
95 BSoundFile::SampleSize() const
96 {
97 	return fSampleSize;
98 }
99 
100 
101 int32
102 BSoundFile::ByteOrder() const
103 {
104 	return fByteOrder;
105 }
106 
107 
108 int32
109 BSoundFile::SampleFormat() const
110 {
111 	return fSampleFormat;
112 }
113 
114 
115 int32
116 BSoundFile::FrameSize() const
117 {
118 	return fSampleSize * fChannelCount;
119 }
120 
121 
122 off_t
123 BSoundFile::CountFrames() const
124 {
125 	return fFrameCount;
126 }
127 
128 
129 bool
130 BSoundFile::IsCompressed() const
131 {
132 	return fIsCompressed;
133 }
134 
135 
136 int32
137 BSoundFile::CompressionType() const
138 {
139 	return fCompressionType;
140 }
141 
142 
143 char *
144 BSoundFile::CompressionName() const
145 {
146 	return fCompressionName;
147 }
148 
149 
150 /* virtual */ int32
151 BSoundFile::SetFileFormat(int32 format)
152 {
153 	fFileFormat = format;
154 	return fFileFormat;
155 }
156 
157 
158 /* virtual */ int32
159 BSoundFile::SetSamplingRate(int32 fps)
160 {
161 	fSamplingRate = fps;
162 	return fSamplingRate;
163 }
164 
165 
166 /* virtual */ int32
167 BSoundFile::SetChannelCount(int32 spf)
168 {
169 	fChannelCount = spf;
170 	return fChannelCount;
171 }
172 
173 
174 /* virtual */ int32
175 BSoundFile::SetSampleSize(int32 bps)
176 {
177 	fSampleSize = bps;
178 	return fSampleSize;
179 }
180 
181 
182 /* virtual */ int32
183 BSoundFile::SetByteOrder(int32 bord)
184 {
185 	fByteOrder = bord;
186 	return fByteOrder;
187 }
188 
189 
190 /* virtual */ int32
191 BSoundFile::SetSampleFormat(int32 fmt)
192 {
193 	fSampleFormat = fmt;
194 	return fSampleFormat;
195 }
196 
197 
198 /* virtual */ int32
199 BSoundFile::SetCompressionType(int32 type)
200 {
201 	return 0;
202 }
203 
204 
205 /* virtual */ char *
206 BSoundFile::SetCompressionName(char *name)
207 {
208 	return NULL;
209 }
210 
211 
212 /* virtual */ bool
213 BSoundFile::SetIsCompressed(bool tf)
214 {
215 	return false;
216 }
217 
218 
219 /* virtual */ off_t
220 BSoundFile::SetDataLocation(off_t offset)
221 {
222 	UNIMPLEMENTED();
223 
224 	return 0;
225 }
226 
227 
228 /* virtual */ off_t
229 BSoundFile::SetFrameCount(off_t count)
230 {
231 	fFrameCount = count;
232 	return fFrameCount;
233 }
234 
235 
236 size_t
237 BSoundFile::ReadFrames(char *buf,
238 					   size_t count)
239 {
240 	UNIMPLEMENTED();
241 
242 	return 0;
243 }
244 
245 
246 size_t
247 BSoundFile::WriteFrames(char *buf,
248 						size_t count)
249 {
250 	UNIMPLEMENTED();
251 
252 	return 0;
253 }
254 
255 
256 /* virtual */ off_t
257 BSoundFile::SeekToFrame(off_t n)
258 {
259 	UNIMPLEMENTED();
260 
261 	return 0;
262 }
263 
264 
265 off_t
266 BSoundFile::FrameIndex() const
267 {
268 	return fFrameIndex;
269 }
270 
271 
272 off_t
273 BSoundFile::FramesRemaining() const
274 {
275 	return fFrameCount - FrameIndex();
276 }
277 
278 /*************************************************************
279  * private BSoundFile
280  *************************************************************/
281 
282 
283 void BSoundFile::_ReservedSoundFile1() {}
284 void BSoundFile::_ReservedSoundFile2() {}
285 void BSoundFile::_ReservedSoundFile3() {}
286 
287 void
288 BSoundFile::_init_raw_stats()
289 {
290 	fSoundFile = 0;
291 	fMediaFile = 0;
292 	fMediaTrack = 0;
293 	fFileFormat = B_UNKNOWN_FILE;
294 	fSamplingRate = 44100;
295 	fChannelCount = 2;
296 	fSampleSize = 2;
297 	fByteOrder = B_BIG_ENDIAN;
298 	fSampleFormat = B_LINEAR_SAMPLES;
299 	fFrameCount = 0;
300 	fFrameIndex = 0;
301 	fIsCompressed = false;
302 	fCompressionType = -1;
303 	fCompressionName = NULL;
304 }
305 
306 
307 status_t
308 BSoundFile::_ref_to_file(const entry_ref *ref)
309 {
310 	status_t status;
311 	BFile * file = new BFile(ref,B_READ_ONLY);
312 	status = file->InitCheck();
313 	if (status != B_OK) {
314 		fSoundFile = file;
315 		return status;
316 	}
317 	BMediaFile * media = new BMediaFile(file);
318 	status = media->InitCheck();
319 	if (status != B_OK) {
320 		delete media;
321 		delete file;
322 		return status;
323 	}
324 	media_file_format mfi;
325 	media->GetFileFormatInfo(&mfi);
326 	switch (mfi.family) {
327 	case B_AIFF_FORMAT_FAMILY: fFileFormat = B_AIFF_FILE; break;
328 	case B_WAV_FORMAT_FAMILY:  fFileFormat = B_WAVE_FILE; break;
329 	default:                fFileFormat = B_UNKNOWN_FILE; break;
330 	}
331 	int trackNum = 0;
332 	BMediaTrack * track = 0;
333 	media_format mf;
334 	while (trackNum < media->CountTracks()) {
335 		track = media->TrackAt(trackNum);
336 		status = track->EncodedFormat(&mf);
337 		if (status != B_OK) {
338 			media->ReleaseTrack(track);
339 			delete media;
340 			delete file;
341 			return status;
342 		}
343 		if (mf.IsAudio()) {
344 			break;
345 		}
346 		media->ReleaseTrack(track);
347 		track = 0;
348 	}
349 	if (track == 0) {
350 		delete media;
351 		delete file;
352 		return B_ERROR;
353 	}
354 	media_raw_audio_format * raw = 0;
355 	if (mf.type == B_MEDIA_ENCODED_AUDIO) {
356 		raw = &mf.u.encoded_audio.output;
357 	}
358 	if (mf.type == B_MEDIA_RAW_AUDIO) {
359 		raw = &mf.u.raw_audio;
360 	}
361 	fSamplingRate = (int)raw->frame_rate;
362 	fChannelCount = raw->channel_count;
363 	fSampleSize = raw->format & 0xf;
364 	fByteOrder = raw->byte_order;
365 	switch (raw->format) {
366 	case media_raw_audio_format::B_AUDIO_FLOAT:
367 		fSampleFormat = B_FLOAT_SAMPLES;
368 		break;
369 	case media_raw_audio_format::B_AUDIO_INT:
370 	case media_raw_audio_format::B_AUDIO_SHORT:
371 	case media_raw_audio_format::B_AUDIO_UCHAR:
372 	case media_raw_audio_format::B_AUDIO_CHAR:
373 		fSampleFormat = B_LINEAR_SAMPLES;
374 		break;
375 	default:
376 		fSampleFormat = B_UNDEFINED_SAMPLES;
377 	}
378 	fByteOffset = 0;
379 	fFrameCount = track->CountFrames();
380 	fFrameIndex = 0;
381 	if (mf.type == B_MEDIA_ENCODED_AUDIO) {
382 		fIsCompressed = true;
383 		fCompressionType = mf.u.encoded_audio.encoding;
384 	}
385 	fMediaFile = media;
386 	fMediaTrack = track;
387 	return B_OK;
388 }
389 
390 
391