xref: /haiku/src/kits/media/SoundFile.cpp (revision 7e0c41c1687c881ab45d763316c160c2ceee21d0)
152a38012Sejakowatz /***********************************************************************
252a38012Sejakowatz  * AUTHOR: Marcus Overhagen
352a38012Sejakowatz  *   FILE: SoundFile.cpp
452a38012Sejakowatz  *  DESCR:
552a38012Sejakowatz  ***********************************************************************/
6*7e0c41c1Sshatty #include <MediaFile.h>
7*7e0c41c1Sshatty #include <MediaTrack.h>
852a38012Sejakowatz #include <SoundFile.h>
952a38012Sejakowatz #include "debug.h"
1052a38012Sejakowatz 
1152a38012Sejakowatz /*************************************************************
1252a38012Sejakowatz  * public BSoundFile
1352a38012Sejakowatz  *************************************************************/
1452a38012Sejakowatz 
1552a38012Sejakowatz BSoundFile::BSoundFile()
1652a38012Sejakowatz {
17*7e0c41c1Sshatty 	_init_raw_stats();
1852a38012Sejakowatz }
1952a38012Sejakowatz 
2052a38012Sejakowatz 
2152a38012Sejakowatz BSoundFile::BSoundFile(const entry_ref *ref,
2252a38012Sejakowatz 					   uint32 open_mode)
2352a38012Sejakowatz {
24*7e0c41c1Sshatty 	_init_raw_stats();
25*7e0c41c1Sshatty 	SetTo(ref,open_mode);
2652a38012Sejakowatz }
2752a38012Sejakowatz 
2852a38012Sejakowatz /* virtual */
2952a38012Sejakowatz BSoundFile::~BSoundFile()
3052a38012Sejakowatz {
31*7e0c41c1Sshatty 	delete fSoundFile;
3252a38012Sejakowatz }
3352a38012Sejakowatz 
3452a38012Sejakowatz 
3552a38012Sejakowatz status_t
3652a38012Sejakowatz BSoundFile::InitCheck() const
3752a38012Sejakowatz {
38*7e0c41c1Sshatty 	if (!fSoundFile) {
39*7e0c41c1Sshatty 		return B_NO_INIT;
40*7e0c41c1Sshatty 	}
41*7e0c41c1Sshatty 	return fSoundFile->InitCheck();
4252a38012Sejakowatz }
4352a38012Sejakowatz 
4452a38012Sejakowatz 
4552a38012Sejakowatz status_t
4652a38012Sejakowatz BSoundFile::SetTo(const entry_ref *ref,
4752a38012Sejakowatz 				  uint32 open_mode)
4852a38012Sejakowatz {
49*7e0c41c1Sshatty 	if (fMediaTrack) {
50*7e0c41c1Sshatty 		BMediaTrack * track = fMediaTrack;
51*7e0c41c1Sshatty 		fMediaTrack = 0;
52*7e0c41c1Sshatty 		fMediaFile->ReleaseTrack(track);
53*7e0c41c1Sshatty 	}
54*7e0c41c1Sshatty 	if (fMediaFile) {
55*7e0c41c1Sshatty 		BMediaFile * file = fMediaFile;
56*7e0c41c1Sshatty 		fMediaFile = 0;
57*7e0c41c1Sshatty 		delete file;
58*7e0c41c1Sshatty 	}
59*7e0c41c1Sshatty 	if (fSoundFile) {
60*7e0c41c1Sshatty 		BFile * file = fSoundFile;
61*7e0c41c1Sshatty 		fSoundFile = 0;
62*7e0c41c1Sshatty 		delete file;
63*7e0c41c1Sshatty 	}
64*7e0c41c1Sshatty 	if (open_mode == B_READ_ONLY) {
65*7e0c41c1Sshatty 		return _ref_to_file(ref);
66*7e0c41c1Sshatty 	} else {
6752a38012Sejakowatz 		UNIMPLEMENTED();
6848ff964fSbeveloper 		return B_ERROR;
6952a38012Sejakowatz 	}
70*7e0c41c1Sshatty }
7152a38012Sejakowatz 
7252a38012Sejakowatz 
7352a38012Sejakowatz int32
7452a38012Sejakowatz BSoundFile::FileFormat() const
7552a38012Sejakowatz {
76*7e0c41c1Sshatty 	return fFileFormat;
7752a38012Sejakowatz }
7852a38012Sejakowatz 
7952a38012Sejakowatz 
8052a38012Sejakowatz int32
8152a38012Sejakowatz BSoundFile::SamplingRate() const
8252a38012Sejakowatz {
83*7e0c41c1Sshatty 	return fSamplingRate;
8452a38012Sejakowatz }
8552a38012Sejakowatz 
8652a38012Sejakowatz 
8752a38012Sejakowatz int32
8852a38012Sejakowatz BSoundFile::CountChannels() const
8952a38012Sejakowatz {
90*7e0c41c1Sshatty 	return fChannelCount;
9152a38012Sejakowatz }
9252a38012Sejakowatz 
9352a38012Sejakowatz 
9452a38012Sejakowatz int32
9552a38012Sejakowatz BSoundFile::SampleSize() const
9652a38012Sejakowatz {
97*7e0c41c1Sshatty 	return fSampleSize;
9852a38012Sejakowatz }
9952a38012Sejakowatz 
10052a38012Sejakowatz 
10152a38012Sejakowatz int32
10252a38012Sejakowatz BSoundFile::ByteOrder() const
10352a38012Sejakowatz {
104*7e0c41c1Sshatty 	return fByteOrder;
10552a38012Sejakowatz }
10652a38012Sejakowatz 
10752a38012Sejakowatz 
10852a38012Sejakowatz int32
10952a38012Sejakowatz BSoundFile::SampleFormat() const
11052a38012Sejakowatz {
111*7e0c41c1Sshatty 	return fSampleFormat;
11252a38012Sejakowatz }
11352a38012Sejakowatz 
11452a38012Sejakowatz 
11552a38012Sejakowatz int32
11652a38012Sejakowatz BSoundFile::FrameSize() const
11752a38012Sejakowatz {
118*7e0c41c1Sshatty 	return fSampleSize * fChannelCount;
11952a38012Sejakowatz }
12052a38012Sejakowatz 
12152a38012Sejakowatz 
12252a38012Sejakowatz off_t
12352a38012Sejakowatz BSoundFile::CountFrames() const
12452a38012Sejakowatz {
125*7e0c41c1Sshatty 	return fFrameCount;
12652a38012Sejakowatz }
12752a38012Sejakowatz 
12852a38012Sejakowatz 
12952a38012Sejakowatz bool
13052a38012Sejakowatz BSoundFile::IsCompressed() const
13152a38012Sejakowatz {
132*7e0c41c1Sshatty 	return fIsCompressed;
13352a38012Sejakowatz }
13452a38012Sejakowatz 
13552a38012Sejakowatz 
13652a38012Sejakowatz int32
13752a38012Sejakowatz BSoundFile::CompressionType() const
13852a38012Sejakowatz {
139*7e0c41c1Sshatty 	return fCompressionType;
14052a38012Sejakowatz }
14152a38012Sejakowatz 
14252a38012Sejakowatz 
14352a38012Sejakowatz char *
14452a38012Sejakowatz BSoundFile::CompressionName() const
14552a38012Sejakowatz {
146*7e0c41c1Sshatty 	return fCompressionName;
14752a38012Sejakowatz }
14852a38012Sejakowatz 
14952a38012Sejakowatz 
15052a38012Sejakowatz /* virtual */ int32
15152a38012Sejakowatz BSoundFile::SetFileFormat(int32 format)
15252a38012Sejakowatz {
153*7e0c41c1Sshatty 	fFileFormat = format;
154*7e0c41c1Sshatty 	return fFileFormat;
15552a38012Sejakowatz }
15652a38012Sejakowatz 
15752a38012Sejakowatz 
15852a38012Sejakowatz /* virtual */ int32
15952a38012Sejakowatz BSoundFile::SetSamplingRate(int32 fps)
16052a38012Sejakowatz {
161*7e0c41c1Sshatty 	fSamplingRate = fps;
162*7e0c41c1Sshatty 	return fSamplingRate;
16352a38012Sejakowatz }
16452a38012Sejakowatz 
16552a38012Sejakowatz 
16652a38012Sejakowatz /* virtual */ int32
16752a38012Sejakowatz BSoundFile::SetChannelCount(int32 spf)
16852a38012Sejakowatz {
169*7e0c41c1Sshatty 	fChannelCount = spf;
170*7e0c41c1Sshatty 	return fChannelCount;
17152a38012Sejakowatz }
17252a38012Sejakowatz 
17352a38012Sejakowatz 
17452a38012Sejakowatz /* virtual */ int32
17552a38012Sejakowatz BSoundFile::SetSampleSize(int32 bps)
17652a38012Sejakowatz {
177*7e0c41c1Sshatty 	fSampleSize = bps;
178*7e0c41c1Sshatty 	return fSampleSize;
17952a38012Sejakowatz }
18052a38012Sejakowatz 
18152a38012Sejakowatz 
18252a38012Sejakowatz /* virtual */ int32
18352a38012Sejakowatz BSoundFile::SetByteOrder(int32 bord)
18452a38012Sejakowatz {
185*7e0c41c1Sshatty 	fByteOrder = bord;
186*7e0c41c1Sshatty 	return fByteOrder;
18752a38012Sejakowatz }
18852a38012Sejakowatz 
18952a38012Sejakowatz 
19052a38012Sejakowatz /* virtual */ int32
19152a38012Sejakowatz BSoundFile::SetSampleFormat(int32 fmt)
19252a38012Sejakowatz {
193*7e0c41c1Sshatty 	fSampleFormat = fmt;
194*7e0c41c1Sshatty 	return fSampleFormat;
19552a38012Sejakowatz }
19652a38012Sejakowatz 
19752a38012Sejakowatz 
19852a38012Sejakowatz /* virtual */ int32
19952a38012Sejakowatz BSoundFile::SetCompressionType(int32 type)
20052a38012Sejakowatz {
20148ff964fSbeveloper 	return 0;
20252a38012Sejakowatz }
20352a38012Sejakowatz 
20452a38012Sejakowatz 
20552a38012Sejakowatz /* virtual */ char *
20652a38012Sejakowatz BSoundFile::SetCompressionName(char *name)
20752a38012Sejakowatz {
20852a38012Sejakowatz 	return NULL;
20952a38012Sejakowatz }
21052a38012Sejakowatz 
21152a38012Sejakowatz 
21252a38012Sejakowatz /* virtual */ bool
21352a38012Sejakowatz BSoundFile::SetIsCompressed(bool tf)
21452a38012Sejakowatz {
21548ff964fSbeveloper 	return false;
21652a38012Sejakowatz }
21752a38012Sejakowatz 
21852a38012Sejakowatz 
21952a38012Sejakowatz /* virtual */ off_t
22052a38012Sejakowatz BSoundFile::SetDataLocation(off_t offset)
22152a38012Sejakowatz {
22252a38012Sejakowatz 	UNIMPLEMENTED();
22352a38012Sejakowatz 
22448ff964fSbeveloper 	return 0;
22552a38012Sejakowatz }
22652a38012Sejakowatz 
22752a38012Sejakowatz 
22852a38012Sejakowatz /* virtual */ off_t
22952a38012Sejakowatz BSoundFile::SetFrameCount(off_t count)
23052a38012Sejakowatz {
231*7e0c41c1Sshatty 	fFrameCount = count;
232*7e0c41c1Sshatty 	return fFrameCount;
23352a38012Sejakowatz }
23452a38012Sejakowatz 
23552a38012Sejakowatz 
23652a38012Sejakowatz size_t
23752a38012Sejakowatz BSoundFile::ReadFrames(char *buf,
23852a38012Sejakowatz 					   size_t count)
23952a38012Sejakowatz {
24052a38012Sejakowatz 	UNIMPLEMENTED();
24152a38012Sejakowatz 
24248ff964fSbeveloper 	return 0;
24352a38012Sejakowatz }
24452a38012Sejakowatz 
24552a38012Sejakowatz 
24652a38012Sejakowatz size_t
24752a38012Sejakowatz BSoundFile::WriteFrames(char *buf,
24852a38012Sejakowatz 						size_t count)
24952a38012Sejakowatz {
25052a38012Sejakowatz 	UNIMPLEMENTED();
25152a38012Sejakowatz 
25248ff964fSbeveloper 	return 0;
25352a38012Sejakowatz }
25452a38012Sejakowatz 
25552a38012Sejakowatz 
25652a38012Sejakowatz /* virtual */ off_t
25752a38012Sejakowatz BSoundFile::SeekToFrame(off_t n)
25852a38012Sejakowatz {
25952a38012Sejakowatz 	UNIMPLEMENTED();
26052a38012Sejakowatz 
26148ff964fSbeveloper 	return 0;
26252a38012Sejakowatz }
26352a38012Sejakowatz 
26452a38012Sejakowatz 
26552a38012Sejakowatz off_t
26652a38012Sejakowatz BSoundFile::FrameIndex() const
26752a38012Sejakowatz {
268*7e0c41c1Sshatty 	return fFrameIndex;
26952a38012Sejakowatz }
27052a38012Sejakowatz 
27152a38012Sejakowatz 
27252a38012Sejakowatz off_t
27352a38012Sejakowatz BSoundFile::FramesRemaining() const
27452a38012Sejakowatz {
275*7e0c41c1Sshatty 	return fFrameCount - FrameIndex();
27652a38012Sejakowatz }
27752a38012Sejakowatz 
27852a38012Sejakowatz /*************************************************************
27952a38012Sejakowatz  * private BSoundFile
28052a38012Sejakowatz  *************************************************************/
28152a38012Sejakowatz 
28252a38012Sejakowatz 
28352a38012Sejakowatz void BSoundFile::_ReservedSoundFile1() {}
28452a38012Sejakowatz void BSoundFile::_ReservedSoundFile2() {}
28552a38012Sejakowatz void BSoundFile::_ReservedSoundFile3() {}
28652a38012Sejakowatz 
28752a38012Sejakowatz void
28852a38012Sejakowatz BSoundFile::_init_raw_stats()
28952a38012Sejakowatz {
290*7e0c41c1Sshatty 	fSoundFile = 0;
291*7e0c41c1Sshatty 	fMediaFile = 0;
292*7e0c41c1Sshatty 	fMediaTrack = 0;
293*7e0c41c1Sshatty 	fFileFormat = B_UNKNOWN_FILE;
294*7e0c41c1Sshatty 	fSamplingRate = 44100;
295*7e0c41c1Sshatty 	fChannelCount = 2;
296*7e0c41c1Sshatty 	fSampleSize = 2;
297*7e0c41c1Sshatty 	fByteOrder = B_BIG_ENDIAN;
298*7e0c41c1Sshatty 	fSampleFormat = B_LINEAR_SAMPLES;
299*7e0c41c1Sshatty 	fFrameCount = 0;
300*7e0c41c1Sshatty 	fFrameIndex = 0;
301*7e0c41c1Sshatty 	fIsCompressed = false;
302*7e0c41c1Sshatty 	fCompressionType = -1;
303*7e0c41c1Sshatty 	fCompressionName = NULL;
30452a38012Sejakowatz }
30552a38012Sejakowatz 
30652a38012Sejakowatz 
30752a38012Sejakowatz status_t
30852a38012Sejakowatz BSoundFile::_ref_to_file(const entry_ref *ref)
30952a38012Sejakowatz {
310*7e0c41c1Sshatty 	status_t status;
311*7e0c41c1Sshatty 	BFile * file = new BFile(ref,B_READ_ONLY);
312*7e0c41c1Sshatty 	status = file->InitCheck();
313*7e0c41c1Sshatty 	if (status != B_OK) {
314*7e0c41c1Sshatty 		fSoundFile = file;
315*7e0c41c1Sshatty 		return status;
316*7e0c41c1Sshatty 	}
317*7e0c41c1Sshatty 	BMediaFile * media = new BMediaFile(file);
318*7e0c41c1Sshatty 	status = media->InitCheck();
319*7e0c41c1Sshatty 	if (status != B_OK) {
320*7e0c41c1Sshatty 		delete media;
321*7e0c41c1Sshatty 		delete file;
322*7e0c41c1Sshatty 		return status;
323*7e0c41c1Sshatty 	}
324*7e0c41c1Sshatty 	media_file_format mfi;
325*7e0c41c1Sshatty 	media->GetFileFormatInfo(&mfi);
326*7e0c41c1Sshatty 	switch (mfi.family) {
327*7e0c41c1Sshatty 	case B_AIFF_FORMAT_FAMILY: fFileFormat = B_AIFF_FILE; break;
328*7e0c41c1Sshatty 	case B_WAV_FORMAT_FAMILY:  fFileFormat = B_WAVE_FILE; break;
329*7e0c41c1Sshatty 	default:                fFileFormat = B_UNKNOWN_FILE; break;
330*7e0c41c1Sshatty 	}
331*7e0c41c1Sshatty 	int trackNum = 0;
332*7e0c41c1Sshatty 	BMediaTrack * track = 0;
333*7e0c41c1Sshatty 	media_format mf;
334*7e0c41c1Sshatty 	while (trackNum < media->CountTracks()) {
335*7e0c41c1Sshatty 		track = media->TrackAt(trackNum);
336*7e0c41c1Sshatty 		status = track->EncodedFormat(&mf);
337*7e0c41c1Sshatty 		if (status != B_OK) {
338*7e0c41c1Sshatty 			media->ReleaseTrack(track);
339*7e0c41c1Sshatty 			delete media;
340*7e0c41c1Sshatty 			delete file;
341*7e0c41c1Sshatty 			return status;
342*7e0c41c1Sshatty 		}
343*7e0c41c1Sshatty 		if (mf.IsAudio()) {
344*7e0c41c1Sshatty 			break;
345*7e0c41c1Sshatty 		}
346*7e0c41c1Sshatty 		media->ReleaseTrack(track);
347*7e0c41c1Sshatty 		track = 0;
348*7e0c41c1Sshatty 	}
349*7e0c41c1Sshatty 	if (track == 0) {
350*7e0c41c1Sshatty 		delete media;
351*7e0c41c1Sshatty 		delete file;
35248ff964fSbeveloper 		return B_ERROR;
35352a38012Sejakowatz 	}
354*7e0c41c1Sshatty 	media_raw_audio_format * raw = 0;
355*7e0c41c1Sshatty 	if (mf.type == B_MEDIA_ENCODED_AUDIO) {
356*7e0c41c1Sshatty 		raw = &mf.u.encoded_audio.output;
357*7e0c41c1Sshatty 	}
358*7e0c41c1Sshatty 	if (mf.type == B_MEDIA_RAW_AUDIO) {
359*7e0c41c1Sshatty 		raw = &mf.u.raw_audio;
360*7e0c41c1Sshatty 	}
361*7e0c41c1Sshatty 	fSamplingRate = (int)raw->frame_rate;
362*7e0c41c1Sshatty 	fChannelCount = raw->channel_count;
363*7e0c41c1Sshatty 	fSampleSize = raw->format & 0xf;
364*7e0c41c1Sshatty 	fByteOrder = raw->byte_order;
365*7e0c41c1Sshatty 	switch (raw->format) {
366*7e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_FLOAT:
367*7e0c41c1Sshatty 		fSampleFormat = B_FLOAT_SAMPLES;
368*7e0c41c1Sshatty 		break;
369*7e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_INT:
370*7e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_SHORT:
371*7e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_UCHAR:
372*7e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_CHAR:
373*7e0c41c1Sshatty 		fSampleFormat = B_LINEAR_SAMPLES;
374*7e0c41c1Sshatty 		break;
375*7e0c41c1Sshatty 	default:
376*7e0c41c1Sshatty 		fSampleFormat = B_UNDEFINED_SAMPLES;
377*7e0c41c1Sshatty 	}
378*7e0c41c1Sshatty 	fByteOffset = 0;
379*7e0c41c1Sshatty 	fFrameCount = track->CountFrames();
380*7e0c41c1Sshatty 	fFrameIndex = 0;
381*7e0c41c1Sshatty 	if (mf.type == B_MEDIA_ENCODED_AUDIO) {
382*7e0c41c1Sshatty 		fIsCompressed = true;
383*7e0c41c1Sshatty 		fCompressionType = mf.u.encoded_audio.encoding;
384*7e0c41c1Sshatty 	}
385*7e0c41c1Sshatty 	fMediaFile = media;
386*7e0c41c1Sshatty 	fMediaTrack = track;
387*7e0c41c1Sshatty 	return B_OK;
388*7e0c41c1Sshatty }
38952a38012Sejakowatz 
39052a38012Sejakowatz 
391