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
15BSoundFile::BSoundFile()
16{
17	_init_raw_stats();
18}
19
20
21BSoundFile::BSoundFile(const entry_ref *ref,
22					   uint32 open_mode)
23{
24	_init_raw_stats();
25	SetTo(ref,open_mode);
26}
27
28/* virtual */
29BSoundFile::~BSoundFile()
30{
31	delete fSoundFile;
32	delete fMediaFile;
33		// fMediaTrack will be deleted by the BMediaFile destructor
34}
35
36
37status_t
38BSoundFile::InitCheck() const
39{
40	if (!fSoundFile) {
41		return B_NO_INIT;
42	}
43	return fSoundFile->InitCheck();
44}
45
46
47status_t
48BSoundFile::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
75int32
76BSoundFile::FileFormat() const
77{
78	return fFileFormat;
79}
80
81
82int32
83BSoundFile::SamplingRate() const
84{
85	return fSamplingRate;
86}
87
88
89int32
90BSoundFile::CountChannels() const
91{
92	return fChannelCount;
93}
94
95
96int32
97BSoundFile::SampleSize() const
98{
99	return fSampleSize;
100}
101
102
103int32
104BSoundFile::ByteOrder() const
105{
106	return fByteOrder;
107}
108
109
110int32
111BSoundFile::SampleFormat() const
112{
113	return fSampleFormat;
114}
115
116
117int32
118BSoundFile::FrameSize() const
119{
120	return fSampleSize * fChannelCount;
121}
122
123
124off_t
125BSoundFile::CountFrames() const
126{
127	return fFrameCount;
128}
129
130
131bool
132BSoundFile::IsCompressed() const
133{
134	return fIsCompressed;
135}
136
137
138int32
139BSoundFile::CompressionType() const
140{
141	return fCompressionType;
142}
143
144
145char *
146BSoundFile::CompressionName() const
147{
148	return fCompressionName;
149}
150
151
152/* virtual */ int32
153BSoundFile::SetFileFormat(int32 format)
154{
155	fFileFormat = format;
156	return fFileFormat;
157}
158
159
160/* virtual */ int32
161BSoundFile::SetSamplingRate(int32 fps)
162{
163	fSamplingRate = fps;
164	return fSamplingRate;
165}
166
167
168/* virtual */ int32
169BSoundFile::SetChannelCount(int32 spf)
170{
171	fChannelCount = spf;
172	return fChannelCount;
173}
174
175
176/* virtual */ int32
177BSoundFile::SetSampleSize(int32 bps)
178{
179	fSampleSize = bps;
180	return fSampleSize;
181}
182
183
184/* virtual */ int32
185BSoundFile::SetByteOrder(int32 bord)
186{
187	fByteOrder = bord;
188	return fByteOrder;
189}
190
191
192/* virtual */ int32
193BSoundFile::SetSampleFormat(int32 fmt)
194{
195	fSampleFormat = fmt;
196	return fSampleFormat;
197}
198
199
200/* virtual */ int32
201BSoundFile::SetCompressionType(int32 type)
202{
203	return 0;
204}
205
206
207/* virtual */ char *
208BSoundFile::SetCompressionName(char *name)
209{
210	return NULL;
211}
212
213
214/* virtual */ bool
215BSoundFile::SetIsCompressed(bool tf)
216{
217	return false;
218}
219
220
221/* virtual */ off_t
222BSoundFile::SetDataLocation(off_t offset)
223{
224	UNIMPLEMENTED();
225
226	return 0;
227}
228
229
230/* virtual */ off_t
231BSoundFile::SetFrameCount(off_t count)
232{
233	fFrameCount = count;
234	return fFrameCount;
235}
236
237
238size_t
239BSoundFile::ReadFrames(char *buf,
240					   size_t count)
241{
242	UNIMPLEMENTED();
243
244	return 0;
245}
246
247
248size_t
249BSoundFile::WriteFrames(char *buf,
250						size_t count)
251{
252	UNIMPLEMENTED();
253
254	return 0;
255}
256
257
258/* virtual */ off_t
259BSoundFile::SeekToFrame(off_t n)
260{
261	UNIMPLEMENTED();
262
263	return 0;
264}
265
266
267off_t
268BSoundFile::FrameIndex() const
269{
270	return fFrameIndex;
271}
272
273
274off_t
275BSoundFile::FramesRemaining() const
276{
277	return fFrameCount - FrameIndex();
278}
279
280/*************************************************************
281 * private BSoundFile
282 *************************************************************/
283
284
285void BSoundFile::_ReservedSoundFile1() {}
286void BSoundFile::_ReservedSoundFile2() {}
287void BSoundFile::_ReservedSoundFile3() {}
288
289void
290BSoundFile::_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
309status_t
310BSoundFile::_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