xref: /haiku/src/kits/media/SoundFile.cpp (revision b0acb3febf47d9ae3adf6388001d91ae28fa2505)
152a38012Sejakowatz /***********************************************************************
252a38012Sejakowatz  * AUTHOR: Marcus Overhagen
352a38012Sejakowatz  *   FILE: SoundFile.cpp
452a38012Sejakowatz  *  DESCR:
552a38012Sejakowatz  ***********************************************************************/
67e0c41c1Sshatty #include <MediaFile.h>
77e0c41c1Sshatty #include <MediaTrack.h>
852a38012Sejakowatz #include <SoundFile.h>
952a38012Sejakowatz #include "debug.h"
1052a38012Sejakowatz 
1152a38012Sejakowatz /*************************************************************
1252a38012Sejakowatz  * public BSoundFile
1352a38012Sejakowatz  *************************************************************/
1452a38012Sejakowatz 
1552a38012Sejakowatz BSoundFile::BSoundFile()
1652a38012Sejakowatz {
177e0c41c1Sshatty 	_init_raw_stats();
1852a38012Sejakowatz }
1952a38012Sejakowatz 
2052a38012Sejakowatz 
2152a38012Sejakowatz BSoundFile::BSoundFile(const entry_ref *ref,
2252a38012Sejakowatz 					   uint32 open_mode)
2352a38012Sejakowatz {
247e0c41c1Sshatty 	_init_raw_stats();
257e0c41c1Sshatty 	SetTo(ref,open_mode);
2652a38012Sejakowatz }
2752a38012Sejakowatz 
2852a38012Sejakowatz /* virtual */
2952a38012Sejakowatz BSoundFile::~BSoundFile()
3052a38012Sejakowatz {
317e0c41c1Sshatty 	delete fSoundFile;
32*b0acb3feSStefano Ceccherini 	delete fMediaFile;
33*b0acb3feSStefano Ceccherini 		// fMediaTrack will be deleted by the BMediaFile destructor
3452a38012Sejakowatz }
3552a38012Sejakowatz 
3652a38012Sejakowatz 
3752a38012Sejakowatz status_t
3852a38012Sejakowatz BSoundFile::InitCheck() const
3952a38012Sejakowatz {
407e0c41c1Sshatty 	if (!fSoundFile) {
417e0c41c1Sshatty 		return B_NO_INIT;
427e0c41c1Sshatty 	}
437e0c41c1Sshatty 	return fSoundFile->InitCheck();
4452a38012Sejakowatz }
4552a38012Sejakowatz 
4652a38012Sejakowatz 
4752a38012Sejakowatz status_t
4852a38012Sejakowatz BSoundFile::SetTo(const entry_ref *ref,
4952a38012Sejakowatz 				  uint32 open_mode)
5052a38012Sejakowatz {
517e0c41c1Sshatty 	if (fMediaTrack) {
527e0c41c1Sshatty 		BMediaTrack * track = fMediaTrack;
537e0c41c1Sshatty 		fMediaTrack = 0;
547e0c41c1Sshatty 		fMediaFile->ReleaseTrack(track);
557e0c41c1Sshatty 	}
567e0c41c1Sshatty 	if (fMediaFile) {
577e0c41c1Sshatty 		BMediaFile * file = fMediaFile;
587e0c41c1Sshatty 		fMediaFile = 0;
597e0c41c1Sshatty 		delete file;
607e0c41c1Sshatty 	}
617e0c41c1Sshatty 	if (fSoundFile) {
627e0c41c1Sshatty 		BFile * file = fSoundFile;
637e0c41c1Sshatty 		fSoundFile = 0;
647e0c41c1Sshatty 		delete file;
657e0c41c1Sshatty 	}
667e0c41c1Sshatty 	if (open_mode == B_READ_ONLY) {
677e0c41c1Sshatty 		return _ref_to_file(ref);
687e0c41c1Sshatty 	} else {
6952a38012Sejakowatz 		UNIMPLEMENTED();
7048ff964fSbeveloper 		return B_ERROR;
7152a38012Sejakowatz 	}
727e0c41c1Sshatty }
7352a38012Sejakowatz 
7452a38012Sejakowatz 
7552a38012Sejakowatz int32
7652a38012Sejakowatz BSoundFile::FileFormat() const
7752a38012Sejakowatz {
787e0c41c1Sshatty 	return fFileFormat;
7952a38012Sejakowatz }
8052a38012Sejakowatz 
8152a38012Sejakowatz 
8252a38012Sejakowatz int32
8352a38012Sejakowatz BSoundFile::SamplingRate() const
8452a38012Sejakowatz {
857e0c41c1Sshatty 	return fSamplingRate;
8652a38012Sejakowatz }
8752a38012Sejakowatz 
8852a38012Sejakowatz 
8952a38012Sejakowatz int32
9052a38012Sejakowatz BSoundFile::CountChannels() const
9152a38012Sejakowatz {
927e0c41c1Sshatty 	return fChannelCount;
9352a38012Sejakowatz }
9452a38012Sejakowatz 
9552a38012Sejakowatz 
9652a38012Sejakowatz int32
9752a38012Sejakowatz BSoundFile::SampleSize() const
9852a38012Sejakowatz {
997e0c41c1Sshatty 	return fSampleSize;
10052a38012Sejakowatz }
10152a38012Sejakowatz 
10252a38012Sejakowatz 
10352a38012Sejakowatz int32
10452a38012Sejakowatz BSoundFile::ByteOrder() const
10552a38012Sejakowatz {
1067e0c41c1Sshatty 	return fByteOrder;
10752a38012Sejakowatz }
10852a38012Sejakowatz 
10952a38012Sejakowatz 
11052a38012Sejakowatz int32
11152a38012Sejakowatz BSoundFile::SampleFormat() const
11252a38012Sejakowatz {
1137e0c41c1Sshatty 	return fSampleFormat;
11452a38012Sejakowatz }
11552a38012Sejakowatz 
11652a38012Sejakowatz 
11752a38012Sejakowatz int32
11852a38012Sejakowatz BSoundFile::FrameSize() const
11952a38012Sejakowatz {
1207e0c41c1Sshatty 	return fSampleSize * fChannelCount;
12152a38012Sejakowatz }
12252a38012Sejakowatz 
12352a38012Sejakowatz 
12452a38012Sejakowatz off_t
12552a38012Sejakowatz BSoundFile::CountFrames() const
12652a38012Sejakowatz {
1277e0c41c1Sshatty 	return fFrameCount;
12852a38012Sejakowatz }
12952a38012Sejakowatz 
13052a38012Sejakowatz 
13152a38012Sejakowatz bool
13252a38012Sejakowatz BSoundFile::IsCompressed() const
13352a38012Sejakowatz {
1347e0c41c1Sshatty 	return fIsCompressed;
13552a38012Sejakowatz }
13652a38012Sejakowatz 
13752a38012Sejakowatz 
13852a38012Sejakowatz int32
13952a38012Sejakowatz BSoundFile::CompressionType() const
14052a38012Sejakowatz {
1417e0c41c1Sshatty 	return fCompressionType;
14252a38012Sejakowatz }
14352a38012Sejakowatz 
14452a38012Sejakowatz 
14552a38012Sejakowatz char *
14652a38012Sejakowatz BSoundFile::CompressionName() const
14752a38012Sejakowatz {
1487e0c41c1Sshatty 	return fCompressionName;
14952a38012Sejakowatz }
15052a38012Sejakowatz 
15152a38012Sejakowatz 
15252a38012Sejakowatz /* virtual */ int32
15352a38012Sejakowatz BSoundFile::SetFileFormat(int32 format)
15452a38012Sejakowatz {
1557e0c41c1Sshatty 	fFileFormat = format;
1567e0c41c1Sshatty 	return fFileFormat;
15752a38012Sejakowatz }
15852a38012Sejakowatz 
15952a38012Sejakowatz 
16052a38012Sejakowatz /* virtual */ int32
16152a38012Sejakowatz BSoundFile::SetSamplingRate(int32 fps)
16252a38012Sejakowatz {
1637e0c41c1Sshatty 	fSamplingRate = fps;
1647e0c41c1Sshatty 	return fSamplingRate;
16552a38012Sejakowatz }
16652a38012Sejakowatz 
16752a38012Sejakowatz 
16852a38012Sejakowatz /* virtual */ int32
16952a38012Sejakowatz BSoundFile::SetChannelCount(int32 spf)
17052a38012Sejakowatz {
1717e0c41c1Sshatty 	fChannelCount = spf;
1727e0c41c1Sshatty 	return fChannelCount;
17352a38012Sejakowatz }
17452a38012Sejakowatz 
17552a38012Sejakowatz 
17652a38012Sejakowatz /* virtual */ int32
17752a38012Sejakowatz BSoundFile::SetSampleSize(int32 bps)
17852a38012Sejakowatz {
1797e0c41c1Sshatty 	fSampleSize = bps;
1807e0c41c1Sshatty 	return fSampleSize;
18152a38012Sejakowatz }
18252a38012Sejakowatz 
18352a38012Sejakowatz 
18452a38012Sejakowatz /* virtual */ int32
18552a38012Sejakowatz BSoundFile::SetByteOrder(int32 bord)
18652a38012Sejakowatz {
1877e0c41c1Sshatty 	fByteOrder = bord;
1887e0c41c1Sshatty 	return fByteOrder;
18952a38012Sejakowatz }
19052a38012Sejakowatz 
19152a38012Sejakowatz 
19252a38012Sejakowatz /* virtual */ int32
19352a38012Sejakowatz BSoundFile::SetSampleFormat(int32 fmt)
19452a38012Sejakowatz {
1957e0c41c1Sshatty 	fSampleFormat = fmt;
1967e0c41c1Sshatty 	return fSampleFormat;
19752a38012Sejakowatz }
19852a38012Sejakowatz 
19952a38012Sejakowatz 
20052a38012Sejakowatz /* virtual */ int32
20152a38012Sejakowatz BSoundFile::SetCompressionType(int32 type)
20252a38012Sejakowatz {
20348ff964fSbeveloper 	return 0;
20452a38012Sejakowatz }
20552a38012Sejakowatz 
20652a38012Sejakowatz 
20752a38012Sejakowatz /* virtual */ char *
20852a38012Sejakowatz BSoundFile::SetCompressionName(char *name)
20952a38012Sejakowatz {
21052a38012Sejakowatz 	return NULL;
21152a38012Sejakowatz }
21252a38012Sejakowatz 
21352a38012Sejakowatz 
21452a38012Sejakowatz /* virtual */ bool
21552a38012Sejakowatz BSoundFile::SetIsCompressed(bool tf)
21652a38012Sejakowatz {
21748ff964fSbeveloper 	return false;
21852a38012Sejakowatz }
21952a38012Sejakowatz 
22052a38012Sejakowatz 
22152a38012Sejakowatz /* virtual */ off_t
22252a38012Sejakowatz BSoundFile::SetDataLocation(off_t offset)
22352a38012Sejakowatz {
22452a38012Sejakowatz 	UNIMPLEMENTED();
22552a38012Sejakowatz 
22648ff964fSbeveloper 	return 0;
22752a38012Sejakowatz }
22852a38012Sejakowatz 
22952a38012Sejakowatz 
23052a38012Sejakowatz /* virtual */ off_t
23152a38012Sejakowatz BSoundFile::SetFrameCount(off_t count)
23252a38012Sejakowatz {
2337e0c41c1Sshatty 	fFrameCount = count;
2347e0c41c1Sshatty 	return fFrameCount;
23552a38012Sejakowatz }
23652a38012Sejakowatz 
23752a38012Sejakowatz 
23852a38012Sejakowatz size_t
23952a38012Sejakowatz BSoundFile::ReadFrames(char *buf,
24052a38012Sejakowatz 					   size_t count)
24152a38012Sejakowatz {
24252a38012Sejakowatz 	UNIMPLEMENTED();
24352a38012Sejakowatz 
24448ff964fSbeveloper 	return 0;
24552a38012Sejakowatz }
24652a38012Sejakowatz 
24752a38012Sejakowatz 
24852a38012Sejakowatz size_t
24952a38012Sejakowatz BSoundFile::WriteFrames(char *buf,
25052a38012Sejakowatz 						size_t count)
25152a38012Sejakowatz {
25252a38012Sejakowatz 	UNIMPLEMENTED();
25352a38012Sejakowatz 
25448ff964fSbeveloper 	return 0;
25552a38012Sejakowatz }
25652a38012Sejakowatz 
25752a38012Sejakowatz 
25852a38012Sejakowatz /* virtual */ off_t
25952a38012Sejakowatz BSoundFile::SeekToFrame(off_t n)
26052a38012Sejakowatz {
26152a38012Sejakowatz 	UNIMPLEMENTED();
26252a38012Sejakowatz 
26348ff964fSbeveloper 	return 0;
26452a38012Sejakowatz }
26552a38012Sejakowatz 
26652a38012Sejakowatz 
26752a38012Sejakowatz off_t
26852a38012Sejakowatz BSoundFile::FrameIndex() const
26952a38012Sejakowatz {
2707e0c41c1Sshatty 	return fFrameIndex;
27152a38012Sejakowatz }
27252a38012Sejakowatz 
27352a38012Sejakowatz 
27452a38012Sejakowatz off_t
27552a38012Sejakowatz BSoundFile::FramesRemaining() const
27652a38012Sejakowatz {
2777e0c41c1Sshatty 	return fFrameCount - FrameIndex();
27852a38012Sejakowatz }
27952a38012Sejakowatz 
28052a38012Sejakowatz /*************************************************************
28152a38012Sejakowatz  * private BSoundFile
28252a38012Sejakowatz  *************************************************************/
28352a38012Sejakowatz 
28452a38012Sejakowatz 
28552a38012Sejakowatz void BSoundFile::_ReservedSoundFile1() {}
28652a38012Sejakowatz void BSoundFile::_ReservedSoundFile2() {}
28752a38012Sejakowatz void BSoundFile::_ReservedSoundFile3() {}
28852a38012Sejakowatz 
28952a38012Sejakowatz void
29052a38012Sejakowatz BSoundFile::_init_raw_stats()
29152a38012Sejakowatz {
2927e0c41c1Sshatty 	fSoundFile = 0;
2937e0c41c1Sshatty 	fMediaFile = 0;
2947e0c41c1Sshatty 	fMediaTrack = 0;
2957e0c41c1Sshatty 	fFileFormat = B_UNKNOWN_FILE;
2967e0c41c1Sshatty 	fSamplingRate = 44100;
2977e0c41c1Sshatty 	fChannelCount = 2;
2987e0c41c1Sshatty 	fSampleSize = 2;
2997e0c41c1Sshatty 	fByteOrder = B_BIG_ENDIAN;
3007e0c41c1Sshatty 	fSampleFormat = B_LINEAR_SAMPLES;
3017e0c41c1Sshatty 	fFrameCount = 0;
3027e0c41c1Sshatty 	fFrameIndex = 0;
3037e0c41c1Sshatty 	fIsCompressed = false;
3047e0c41c1Sshatty 	fCompressionType = -1;
3057e0c41c1Sshatty 	fCompressionName = NULL;
30652a38012Sejakowatz }
30752a38012Sejakowatz 
30852a38012Sejakowatz 
30952a38012Sejakowatz status_t
31052a38012Sejakowatz BSoundFile::_ref_to_file(const entry_ref *ref)
31152a38012Sejakowatz {
3127e0c41c1Sshatty 	status_t status;
3137e0c41c1Sshatty 	BFile * file = new BFile(ref,B_READ_ONLY);
3147e0c41c1Sshatty 	status = file->InitCheck();
3157e0c41c1Sshatty 	if (status != B_OK) {
3167e0c41c1Sshatty 		fSoundFile = file;
3177e0c41c1Sshatty 		return status;
3187e0c41c1Sshatty 	}
3197e0c41c1Sshatty 	BMediaFile * media = new BMediaFile(file);
3207e0c41c1Sshatty 	status = media->InitCheck();
3217e0c41c1Sshatty 	if (status != B_OK) {
3227e0c41c1Sshatty 		delete media;
3237e0c41c1Sshatty 		delete file;
3247e0c41c1Sshatty 		return status;
3257e0c41c1Sshatty 	}
3267e0c41c1Sshatty 	media_file_format mfi;
3277e0c41c1Sshatty 	media->GetFileFormatInfo(&mfi);
3287e0c41c1Sshatty 	switch (mfi.family) {
3297e0c41c1Sshatty 	case B_AIFF_FORMAT_FAMILY: fFileFormat = B_AIFF_FILE; break;
3307e0c41c1Sshatty 	case B_WAV_FORMAT_FAMILY:  fFileFormat = B_WAVE_FILE; break;
3317e0c41c1Sshatty 	default:                fFileFormat = B_UNKNOWN_FILE; break;
3327e0c41c1Sshatty 	}
3337e0c41c1Sshatty 	int trackNum = 0;
3347e0c41c1Sshatty 	BMediaTrack * track = 0;
3357e0c41c1Sshatty 	media_format mf;
3367e0c41c1Sshatty 	while (trackNum < media->CountTracks()) {
3377e0c41c1Sshatty 		track = media->TrackAt(trackNum);
3387e0c41c1Sshatty 		status = track->EncodedFormat(&mf);
3397e0c41c1Sshatty 		if (status != B_OK) {
3407e0c41c1Sshatty 			media->ReleaseTrack(track);
3417e0c41c1Sshatty 			delete media;
3427e0c41c1Sshatty 			delete file;
3437e0c41c1Sshatty 			return status;
3447e0c41c1Sshatty 		}
3457e0c41c1Sshatty 		if (mf.IsAudio()) {
3467e0c41c1Sshatty 			break;
3477e0c41c1Sshatty 		}
3487e0c41c1Sshatty 		media->ReleaseTrack(track);
3497e0c41c1Sshatty 		track = 0;
3507e0c41c1Sshatty 	}
3517e0c41c1Sshatty 	if (track == 0) {
3527e0c41c1Sshatty 		delete media;
3537e0c41c1Sshatty 		delete file;
35448ff964fSbeveloper 		return B_ERROR;
35552a38012Sejakowatz 	}
3567e0c41c1Sshatty 	media_raw_audio_format * raw = 0;
3577e0c41c1Sshatty 	if (mf.type == B_MEDIA_ENCODED_AUDIO) {
3587e0c41c1Sshatty 		raw = &mf.u.encoded_audio.output;
3597e0c41c1Sshatty 	}
3607e0c41c1Sshatty 	if (mf.type == B_MEDIA_RAW_AUDIO) {
3617e0c41c1Sshatty 		raw = &mf.u.raw_audio;
3627e0c41c1Sshatty 	}
3637e0c41c1Sshatty 	fSamplingRate = (int)raw->frame_rate;
3647e0c41c1Sshatty 	fChannelCount = raw->channel_count;
3657e0c41c1Sshatty 	fSampleSize = raw->format & 0xf;
3667e0c41c1Sshatty 	fByteOrder = raw->byte_order;
3677e0c41c1Sshatty 	switch (raw->format) {
3687e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_FLOAT:
3697e0c41c1Sshatty 		fSampleFormat = B_FLOAT_SAMPLES;
3707e0c41c1Sshatty 		break;
3717e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_INT:
3727e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_SHORT:
3737e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_UCHAR:
3747e0c41c1Sshatty 	case media_raw_audio_format::B_AUDIO_CHAR:
3757e0c41c1Sshatty 		fSampleFormat = B_LINEAR_SAMPLES;
3767e0c41c1Sshatty 		break;
3777e0c41c1Sshatty 	default:
3787e0c41c1Sshatty 		fSampleFormat = B_UNDEFINED_SAMPLES;
3797e0c41c1Sshatty 	}
3807e0c41c1Sshatty 	fByteOffset = 0;
3817e0c41c1Sshatty 	fFrameCount = track->CountFrames();
3827e0c41c1Sshatty 	fFrameIndex = 0;
3837e0c41c1Sshatty 	if (mf.type == B_MEDIA_ENCODED_AUDIO) {
3847e0c41c1Sshatty 		fIsCompressed = true;
3857e0c41c1Sshatty 		fCompressionType = mf.u.encoded_audio.encoding;
3867e0c41c1Sshatty 	}
3877e0c41c1Sshatty 	fMediaFile = media;
3887e0c41c1Sshatty 	fMediaTrack = track;
3897e0c41c1Sshatty 	return B_OK;
3907e0c41c1Sshatty }
39152a38012Sejakowatz 
39252a38012Sejakowatz 
393