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