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

📄 sound_directsound.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 2 页
字号:
  else 
      PTRACE (4, "dsound\tWriteToDXBuffer Failed : " << DXGetErrorString9 (hr));

  return written;
}

/*
 * DESC:   Reads (len) bytes from the buffer (*buf) from DirectX sound capture device buffer
 * BEHAVIOUR :  Locks the buffer on the requested size; In case buffer was lost, tries to restore it.
 * 	  	Copies the data into the buffer
 * 	  	Unlock the buffer
 * RETURN    : Returns the size actually read
 */
PINDEX 
PSoundChannelDirectSound::ReadFromDXBuffer (const void * buf, 
					    PINDEX len)
{
  HRESULT hr;
  LPVOID lpvRead1, lpvRead2;
  DWORD dwLength1, dwLength2;
  PINDEX read = 0;

  /***  Lock the buffer   ***/
  hr = mAudioCaptureBuffer->Lock (mDXOffset,
				  len,
				  &lpvRead1,
				  &dwLength1,
				  &lpvRead2,
				  &dwLength2,
				  0L);

  if (!FAILED(hr)) 
    {
      /***  Copy memory into buffer  ***/
      memcpy ((BYTE *)buf + lastReadCount, lpvRead1, dwLength1);

      if (lpvRead2 != NULL)
	memcpy ((BYTE *) buf + dwLength1 +  lastReadCount, lpvRead2, dwLength2);

      read = dwLength1 + dwLength2;
      mDXOffset += read;
      mDXOffset %= mDXBufferSize;
      
      /***  Unlock the buffer   ***/
      mAudioCaptureBuffer->Unlock (lpvRead1,
				   dwLength1,
				   lpvRead2,
				   dwLength2);

    } 
  else 
    PTRACE (4, "dsound\tReadFromDXBuffer Lock failed: " << DXGetErrorString9 (hr));

  return read;
}


/*
 * DESC	: 	Suspend the treatment in order to let the buffer flush itself 
 * BEHAVIOUR :	Compute the time needed to play the remaining data in buffer. 
 * 		In case it exceed 600 ms, sleeps for 500 ms.
 * RETURN :	/
 */
void 
PSoundChannelDirectSound::FlushBuffer ()
{
  DWORD sleep_time = (mDXBufferSize - GetDXBufferFreeSpace ()) * 8000 / ( mWFX.wBitsPerSample * mWFX.nSamplesPerSec);

  if (sleep_time > 600) 
      Sleep((DWORD)(sleep_time-500));
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::SetFormat (unsigned numChannels,
					  unsigned sampleRate,
					  unsigned bitsPerSample)
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " SetFormat\n"
          << "   -->  nChannels  :" << mWFX.nChannels << '\n'
          << "   -->  nSamplesPerSec  :" << mWFX.nSamplesPerSec << '\n'
          << "   -->  wBitsPerSample  :" << mWFX.wBitsPerSample << '\n'
          << "   -->  nBlockAlign  :" << mWFX.nBlockAlign << '\n'
          << "   -->  nAvgBytesPerSec  :" << mWFX.nAvgBytesPerSec << '\n'
          << "   -->  mOutburst  :" << mOutburst);
  
  memset (&mWFX, 0, sizeof (mWFX)); 
  mWFX.wFormatTag = WAVE_FORMAT_PCM;
  mWFX.nChannels = (WORD)numChannels;
  mWFX.nSamplesPerSec = sampleRate;
  mWFX.wBitsPerSample = (WORD)bitsPerSample;
  mWFX.nBlockAlign = mWFX.nChannels * (mWFX.wBitsPerSample / 8);
  mWFX.nAvgBytesPerSec = mWFX.nSamplesPerSec * mWFX.nBlockAlign;
  mWFX.cbSize = 0; //ignored

  mOutburst = mWFX.nBlockAlign*8;

  
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

unsigned 
PSoundChannelDirectSound::GetChannels()   const
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " GetChannels");
  return mNumChannels;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

unsigned 
PSoundChannelDirectSound::GetSampleRate() const
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " GetSampleRate");
  return mSampleRate;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

unsigned 
PSoundChannelDirectSound::GetSampleSize() const
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " GetSampleSize");
  return mBitsPerSample;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::SetBuffers (PINDEX size, PINDEX count)
{

  //kept for records
  mBufferCount = count;
  mBufferSize = size; 

  mDXBufferSize = mWFX.nAvgBytesPerSec;

  PTRACE (4, "dsound\tSetBuffers ==>  size = " << size << "  |  count = " << count << "  | DXBufferSize = " << mDXBufferSize);
  if (mDirection == Player)
    InitPlaybackBuffer ();
  else
    InitCaptureBuffer ();
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::GetBuffers(PINDEX & size, PINDEX & count)
{
  count = mBufferCount;
  size = mBufferSize;
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::InitCaptureBuffer() 
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " InitCaptureBuffer");

  if (isInitialised)
    return false;
 
  HRESULT hr; 
  DSCBUFFERDESC dscbdesc;
  LPDIRECTSOUNDCAPTUREBUFFER pDscb = NULL;

  memset(&dscbdesc, 0, sizeof(DSCBUFFERDESC)); 
  dscbdesc.dwSize = sizeof(DSCBUFFERDESC); 
  dscbdesc.dwFlags = DSCBCAPS_WAVEMAPPED; 
  dscbdesc.dwBufferBytes = mDXBufferSize; 
  dscbdesc.lpwfxFormat = &mWFX; 

  hr = sAudioCaptureDevice->CreateCaptureBuffer(&dscbdesc, 
						&pDscb, 
						NULL); 
  if (SUCCEEDED(hr)) 
    { 

      hr = pDscb->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*) &mAudioCaptureBuffer);
      pDscb->Release();
      mDXOffset = 0;
      mAudioCaptureBuffer->Start (DSCBSTART_LOOPING);
      isInitialised = true;
    }
  else
    PTRACE (4, "dsound\tInitCaptureBuffer : Create Sound Buffer Failed " << DXGetErrorString9 (hr));


  return isInitialised;
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::InitPlaybackBuffer() 
{

  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " InitPlaybackBuffer");

  if (isInitialised)
    return false;

  DSBUFFERDESC dsbdesc; 
  HRESULT hr; 
  LPDIRECTSOUNDBUFFER pDsb = NULL;

  memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); 
  dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
  dsbdesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; 
  dsbdesc.dwBufferBytes = mDXBufferSize; 
  dsbdesc.lpwfxFormat = &mWFX; 

  hr = sAudioPlaybackDevice->CreateSoundBuffer(&dsbdesc, 
					       &pDsb, 
					       NULL); 
  if (SUCCEEDED(hr)) 
    { 

      hr = pDsb->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*) &mAudioPlaybackBuffer);
      pDsb->Release();
      mDXOffset = 0;

      //fill buffer with silence
      PBYTEArray silence(mDXBufferSize);
      memset (silence.GetPointer(), (mWFX.wBitsPerSample == 8) ? 128 : 0, mDXBufferSize);
      WriteToDXBuffer (silence, mDXBufferSize);

      mAudioPlaybackBuffer->SetCurrentPosition (0);
      isInitialised = true;
    } 
  else
    PTRACE (4, "dsound\tInitPlaybackBuffer : Create Sound Buffer Failed " << DXGetErrorString9 (hr));

  return isInitialised;
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::PlaySound(const PSound & sound, PBoolean wait)
{
  mStreaming = false;
  if (!Write((const void *)sound, sound.GetSize()))
    return PFalse;

  if (wait)
    return WaitForPlayCompletion();
  return PTrue;
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::PlayFile(const PFilePath & filename, PBoolean wait)
{
  BYTE buffer [512];
  mStreaming = false;

  PFile file (filename, PFile::ReadOnly);

  if (!file.IsOpen())
    return PFalse;

  for (;;) 
    {

    if (!file.Read (buffer, 512))
      break;

    PINDEX len = file.GetLastReadCount();
    if (len == 0)
      break;
    if (!Write(buffer, len))
      break;
  }

  file.Close();

  if (wait)
    return WaitForPlayCompletion();

  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::HasPlayCompleted()
{

  DWORD dwStatus;
  if (mAudioPlaybackBuffer != NULL) 
    {

      mAudioPlaybackBuffer->GetStatus (&dwStatus);
      if (dwStatus & DSBSTATUS_PLAYING)  
	return PFalse;

    }
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::WaitForPlayCompletion()
{
  while (!HasPlayCompleted()) 
    Sleep (50);

  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean 
PSoundChannelDirectSound::RecordSound(PSound & /*sound*/)
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " RecordSound");
  return PFalse;
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::RecordFile(const PFilePath & /*filename*/)
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " RecordFile");
  return PFalse;
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean 
PSoundChannelDirectSound::StartRecording()
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " StartRecording");
  return PFalse;
}

/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean PSoundChannelDirectSound::IsRecordBufferFull()
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " IsRecordBufferFull");
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean PSoundChannelDirectSound::AreAllRecordBuffersFull()
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " AreAllRecordBuffersFull");
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean PSoundChannelDirectSound::WaitForRecordBufferFull()
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " WaitForRecordBufferFull");
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean PSoundChannelDirectSound::WaitForAllRecordBuffersFull()
{

  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " WaitForAllRecordBuffersFull");
  return PFalse;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */
PBoolean 
PSoundChannelDirectSound::Abort()
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " Abort");
  return PTrue;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::SetVolume (unsigned newVal)
{

  PBoolean no_error=PTrue;
  HRESULT hr;
  
  long volume = (long) (log10((double)newVal) * 5000.0) - 10000;
  switch (mDirection) {

  case Player:
    if (mAudioPrimaryPlaybackBuffer) 
      {

	if (FAILED (hr = mAudioPlaybackBuffer->SetVolume( volume ))) 
	  {
	    PTRACE (4, "PSoundChannelDirectSound::SetVolume Failed " << DXGetErrorString9 (hr));
	    no_error = PFalse;
	  }
      }
    else
      PTRACE (4, "PSoundChannelDirectSound::SetVolume Failed mAudioPlaybackBuffer is NULLL (huh?)");
    break;


  case Recorder:
    // DirectX does not let you change the capture buffer volume
    mVolume = newVal;
    break;
  }
  return no_error;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean  
PSoundChannelDirectSound::GetVolume(unsigned &devVol)
{

  PBoolean no_error=PTrue;
  HRESULT hr;
  long volume = 100;
  switch (mDirection) 
    {

    case Player:

      if (mAudioPlaybackBuffer) 
	{

	  if (FAILED (hr = mAudioPlaybackBuffer->GetVolume( &volume ))) 
	    {
	      PTRACE (4, "PSoundChannelDirectSound::GetVolume Failed " << DXGetErrorString9 (hr));
	      no_error = PFalse;
	    }
	  devVol = (unsigned int) pow(10.0, (float)(volume+10000) / 5000.0);
	}
      break;

    case Recorder:
      // DirectX does not let you change the capture buffer volume
      devVol = mVolume;
      break;

    }
  return no_error;
}


/*
 * DESC	:	
 * BEHAVIOUR :
 * RETURN :
 */

PBoolean 
PSoundChannelDirectSound::IsOpen () const
{
  PTRACE (4, "dsound\t" << ((mDirection == Player) ? "Playback" : "Recording") << " IsOpen");
  return isOpen;
}


#endif // P_DIRECTSOUND

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -