⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beaudio.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:
	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 + -