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