波形捕获:(9)写入到WAV文件
当前位置:以往代写 > C/C++ 教程 >波形捕获:(9)写入到WAV文件
2019-06-13

波形捕获:(9)写入到WAV文件

波形捕获:(9)写入到WAV文件

副标题#e#

WAV文件为资源互换文件名目(RIFF),包罗若干数量的定名块,个中包括头 信息(如声音采样名目)或数据(如样本自己)。Win 32 API提供了打开封锁 FIFF文件、查找块等函数。这些函数的名字都以“mmio”开头。

DirectSound API 不包罗写入WAV文件的要领。可是 DXUTsound.cpp 文 件实现了一个 CWaveFile 类,这个类具有以下打点捕获文件的方 法:

·Open 要领。打开一个文件而且写入头部块。

·Write 要领。将数据从缓冲区写入到数据块中而且提高写指针 。

·Close 要领。将数据块的巨细写入到头部而且封锁文件。

写入到一个WAV文件的第一步是挪用 CWaveFile::Open 要领。这样会创 建一个文件而且写WAV名目块。参数为文件名,一个指向初始化后的 WAVEFORMATEX 布局体的指针和 WAVEFILE_WRITE 符号。这个要领返回一个 HRESULT。

下面的代码为写入打开了一个WAV文件:

Code

CWaveFile  g_pWaveFile;
WAVEFORMATEX wfxInput;

ZeroMemory( &wfxInput, sizeof(wfxInput));
wfxInput.wFormatTag = WAVE_FORMAT_PCM;
wfxInput.nSamplesPerSec = 22050
wfxInput.wBitsPerSample = 8;
wfxInput.nChannels = 1;
wfxInput.nBlockAlign =
wfxInput.nChannels * (wfxInput.wBitsPerSample / 8);
wfxInput.nAvgBytesPerSec =
 wfxInput.nBlockAlign * wfxInput.nSamplesPerSec;

g_pWaveFile = new CWaveFile;
if (FAILED(g_pWaveFile->Open("mywave.wav", &wfxInput,WAVEFILE_WRITE)))
{
 g_pWaveFile->Close();
}


#p#副标题#e#

应用措施此刻可以开始从捕获缓冲区复制数据到这个文件了。

下面的 示例函数将在每次读指针达到通知位置时被挪用。在这个函数内,将利用如下全 局变量:

·g_pDSBCapture 是一个指向缓冲区中的 IDirectSoundCaptureBuffer8 接口的指针。

·g_dwNextCaptureOffset 跟踪缓冲区中下一个将要被复制到文 件的数据块的偏移量。

·g_dwCaptureBufferSize 暗示缓冲区大 小,被用在计较"环抱"。

Code

HRESULT RecordCapturedData()
  {
   HRESULT hr;
    VOID* pbCaptureData = NULL;
   DWORD dwCaptureLength;
    VOID* pbCaptureData2 = NULL;
   DWORD dwCaptureLength2;
   VOID* pbPlayData  = NULL;
   UINT dwDataWrote;
   DWORD dwReadPos;
   LONG lLockSize;

   if (NULL == g_pDSBCapture)
     return S_FALSE;
   if (NULL == g_pWaveFile)
     return S_FALSE;

    if (FAILED (hr = g_pDSBCapture->GetCurrentPosition(
     NULL, &dwReadPos)))
     return hr;

   // Lock everything between the private cursor
   // and the read cursor, allowing for wraparound.

   lLockSize = dwReadPos - g_dwNextCaptureOffset;
   if( lLockSize < 0 ) lLockSize += g_dwCaptureBufferSize;

   if( lLockSize == 0 ) return S_FALSE;

   if (FAILED(hr = g_pDSBCapture- >Lock(
      g_dwNextCaptureOffset, lLockSize,
       &pbCaptureData, &dwCaptureLength,
       &pbCaptureData2, &dwCaptureLength2, 0L)))
    return hr;

   // Write the data. This is done in two steps
   // to account for wraparound.

   if (FAILED( hr = g_pWaveFile->Write( dwCaptureLength,
     (BYTE*) pbCaptureData, &dwDataWrote)))
    return hr;

   if (pbCaptureData2 != NULL)
   {
    if (FAILED(hr = g_pWaveFile->Write(
      dwCaptureLength2, (BYTE*)pbCaptureData2,
      &dwDataWrote)))
      return hr;
   }

   // Unlock the capture buffer.

   g_pDSBCapture->Unlock( pbCaptureData, dwCaptureLength,
    pbCaptureData2, dwCaptureLength2 );

   // Move the capture offset forward.

    g_dwNextCaptureOffset += dwCaptureLength;
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize;
    g_dwNextCaptureOffset += dwCaptureLength2;
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize;

    return S_OK;
  }

When capturing is finished, the application closes the WAV file.

  g_pWaveFile->Close ();

    关键字:

在线提交作业