📄 beaudio.cxx
字号:
return (unsigned)mFormat.frame_rate;}unsigned PSoundChannelBeOS::GetSampleSize() const{ return (mFormat.format & 0xF)*8; // return number of BITS}BOOL PSoundChannelBeOS::Read(void *buf, PINDEX len){ PINDEX bufSize = len; // Can only read from a recorder if (mRecorder!=NULL) { // A Read starts the recording, if it's not running already if (!mRecorder->IsRunning()) { mRecorder->Start(); } // Wait until there's a buffer recorded mBuffer->WaitForState(CircularBuffer::NotEmpty);#ifdef FILEDUMP void *dumpbuf=buf; size_t dumpsize=len;#endif lastReadCount = 0; while(lastReadCount < bufSize) { len = bufSize - lastReadCount; if(len <= 0) break; // Get data from the buffer mBuffer->Drain((BYTE**)&buf, (size_t*) &len); lastReadCount += len; } #ifdef FILEDUMP if (recwriter) { recwriter->writewavfile(dumpbuf, dumpsize); }#endif return TRUE; } return FALSE;}BOOL PSoundChannelBeOS::Write(const void *buf, PINDEX len){ // can only write to a player if (mPlayer!=NULL) { // Wait until there is space mBuffer->WaitForState(CircularBuffer::EmptyEnough); // This function needs to update the last write count // Store len before it gets modified lastWriteCount=len;#ifdef FILEDUMP if (playwriter) { playwriter->writewavfile(buf,len); }#endif // Store data into the buffer mBuffer->Fill((const BYTE **)&buf, (size_t*) &len); // Update last write count lastWriteCount-=len; return TRUE; } return FALSE;}BOOL PSoundChannelBeOS::Close(){ PRINT(("")); // Flush the buffer first Abort(); // Stop the player if ((mPlayer!=NULL) && (mPlayer->InitCheck()==B_OK)) { mPlayer->Stop();#ifdef FILEDUMP delete playwriter; playwriter=NULL;#endif } if(mPlayer) { // Destroy the player delete mPlayer; mPlayer=NULL; // make sure that another Close won't crash the system } // Stop the recorder if ((mRecorder!=NULL) && (mRecorder->InitCheck()==B_OK)) { mRecorder->Stop(); // Not really necessary mRecorder->Disconnect(); #ifdef FILEDUMP delete recwriter; recwriter=NULL;#endif } if(mRecorder) { // Destroy the recorder delete mRecorder; mRecorder=NULL; // make sure that another Close won't crash the system } return TRUE;}BOOL PSoundChannelBeOS::SetBuffers(PINDEX size, PINDEX count){ return InternalSetBuffers(size*(mNumBuffers=count),size);}BOOL PSoundChannelBeOS::InternalSetBuffers(PINDEX size, PINDEX threshold){ if (mPlayer) { mPlayer->SetHasData(false); } else if (mRecorder) { mRecorder->Stop(); } // Delete the current buffer if(mBuffer != NULL) { delete mBuffer; mBuffer = NULL; } // Create the new buffer if (size != 0) { if (mRecorder) { if (!mResampler) { PTRACE(TL, "Creating default resampler"); mResampler = new Resampler(1.0,1.0,1,1,0,1); } PTRACE(TL, "Creating resampling buffer, size " << size); mBuffer = new ResamplingBuffer(mResampler, size, threshold, threshold); // In case we use resampler, size must be set to resampled buffer size } else { PTRACE(TL, "Creating playback buffer, size " << size); mBuffer = new CircularBuffer(size, threshold, threshold); } // If we have a player, set the cookie again and restart it if (mPlayer) { mPlayer->SetCookie(mBuffer); PTRACE(TL, "Tried to set player buffer cookie"); mPlayer->SetHasData(true); PTRACE(TL, "Tried to set player has data"); } // If we have a recorder, set the cookie again // Note that the recorder is not restarted, even if it was running. // It's not a good idea for the program to change the buffers during // recording anyway because it would at least lose some data. if (mRecorder) { if(B_OK != mRecorder->SetBufferHook(RecordBuffer, mBuffer)) PTRACE(TL, "Can't set recorder buffer hook"); } return TRUE; } if (IsOpen()) { PTRACE(TL, "Can't continue without buffers - closing channel"); Close(); // should give errors on subsequent read/writes } mBuffer = NULL; return FALSE;}BOOL PSoundChannelBeOS::GetBuffers(PINDEX &size, PINDEX &count){ if (mBuffer) { size=mBuffer->GetSize(); count=mNumBuffers; return TRUE; } return FALSE;}BOOL PSoundChannelBeOS::PlaySound(const PSound &sound, BOOL wait){ PRINT(("wait=%s", wait?"true":"false")); if (mPlayer==NULL) { PRINT(("Playing a sound on a closed (or recording) PSoundChannelBeOS")); return FALSE; }#ifdef FILEDUMP playwriter->writewavfile((void *)(const BYTE*)sound, sound.GetSize());#endif // create a local buffer that references the PSound // NOTE: no conversion between the PSound's format and the // PSoundChannelBeOS's format is done. const BYTE *buf=(const BYTE *)sound; PINDEX size=sound.GetSize(); // Play the sound by doing successive Writes until the sound is done. // Note that write will return when either the buffer is full or the // given data is written. We want to return after the entire sound // has been buffered. So we repeatedly call Write until there is // no data left while (size!=0) { // Wait until there is space mBuffer->WaitForState(CircularBuffer::EmptyEnough); // Write the data mBuffer->Fill(&buf, (size_t*) &size); } // Wait until the sound is finished, if requested if (wait) { PRINT(("Waiting for sound")); mBuffer->WaitForState(CircularBuffer::Empty); } return TRUE;}BOOL PSoundChannelBeOS::PlayFile(const PFilePath &file, BOOL wait){ entry_ref ref; status_t err; // using pointers for these objects so that we don't have to // construct them here but can nevertheless use the if(ok)'s BEntry *pentry = NULL; { // Create BEntry from file name pentry = new BEntry(file, true); err = pentry->InitCheck(); } if (err==B_OK) { // Create entry_ref from BEntry err = pentry->GetRef(&ref); } if (err==B_OK) { // Play the sound. Return value is a handle or a negative value for errors // Errors in BeOS are always negative values err=play_sound(&ref, true, !wait, wait); if (err>=0) { err=B_OK; } } return (err==B_OK);}BOOL PSoundChannelBeOS::HasPlayCompleted(){ if (mPlayer!=NULL) { return mBuffer->IsEmpty(); } return FALSE;}BOOL PSoundChannelBeOS::WaitForPlayCompletion(){ if (mPlayer!=NULL) { mBuffer->WaitForState(CircularBuffer::Empty); } return TRUE;}BOOL PSoundChannelBeOS::RecordSound(PSound &sound){ PRINT(("")); if (mRecorder==NULL) { PRINT(("Recording a sound on a closed (or playing) PSoundChannelBeOS")); return FALSE; } // Flush the buffer first Abort(); // Start recording if (mRecorder->Start()!=B_OK) { PRINT(("BMediaRecorder::Start() returned error")); return FALSE; } // Wait until buffer is filled mBuffer->WaitForState(CircularBuffer::Full); PRINT(("Buffer full: size=%lu",mBuffer->GetSize())); // Stop the recorder if (mRecorder->Stop()!=B_OK) { PRINT(("Uh-oh, recorder is unstoppable!")); //return FALSE; } // Set the sound's format to ours sound.SetFormat(GetChannels(), GetSampleRate(), GetSampleSize()); // Resize the sound and set up local buffer references PINDEX size=mBuffer->GetSize(); BYTE *buf=sound.GetPointer(size);#ifdef FILEDUMP void *dumpbuf=buf; size_t dumpsize=size;#endif // Read the data mBuffer->Drain(&buf, (size_t*) &size);#ifdef FILEDUMP recwriter->writewavfile(dumpbuf, dumpsize);#endif PRINT(("Recording succesful")); return TRUE;}BOOL PSoundChannelBeOS::RecordFile(const PFilePath & filename){ // Not implemented for now return FALSE;}BOOL PSoundChannelBeOS::StartRecording(){ if (mRecorder==NULL) { PRINT(("Recording to a closed (or playing) PSoundChannelBeOS")); return FALSE; } // Flush the buffers Abort(); // Start recording if (mRecorder->Start()!=B_OK) { PRINT(("BMediaRecorder::Start returned error")); return FALSE; } return TRUE;}BOOL PSoundChannelBeOS::IsRecordBufferFull(){ if (mRecorder) { return !mBuffer->IsEmpty(); } return FALSE;}BOOL PSoundChannelBeOS::AreAllRecordBuffersFull(){ if (mRecorder) { return mBuffer->IsFull(); } return FALSE;}BOOL PSoundChannelBeOS::WaitForRecordBufferFull(){ if (mRecorder==NULL) { PRINT(("Waiting for record buffer on playing or closed PSoundChannelBeOS")); return FALSE; } mBuffer->WaitForState(CircularBuffer::FullEnough); return PXSetIOBlock(PXReadBlock, readTimeout);}BOOL PSoundChannelBeOS::WaitForAllRecordBuffersFull(){ if (mRecorder==NULL) { PRINT(("Waiting for record buffers on playing or closed PSoundChannelBeOS")); return FALSE; } mBuffer->WaitForState(CircularBuffer::Full); return TRUE;}BOOL PSoundChannelBeOS::IsOpen() const{ BOOL result=((mPlayer!=NULL) || (mRecorder!=NULL)); PRINT(("returning %s, player 0x%X recorder 0x%X", result?"true":"false", mPlayer, mRecorder)); return result;}BOOL PSoundChannelBeOS::SetVolume(unsigned newVolume){ #ifdef TODO cerr << __FILE__<< "PSoundChannelBeOS :: SetVolume called in error. Please fix" << endl; #endif return TRUE;}BOOL PSoundChannelBeOS::GetVolume(unsigned & volume){ #ifdef TODO cerr << __FILE__<< "PSoundChannelBeOS :: GetVolume called in error. Please fix" << endl; #endif return TRUE;}// End of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -