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