Microsoft DirectX 8.0 (C++)

ウェーブ ファイルへの書き込み

DirectSound API は、ウェーブ ファイルへの書き込みのためのメソッドを備えていない。ただし、多くの SDK サンプル アプリケーションで使用される Dsutil.cpp ファイルは、次のパブリック メソッドを持つ CWaveFile クラスを実装する。

ウェーブ ファイルを書き込む最初のステップは、CWaveFile::Open メソッドを呼び出すことである。このメソッドは、ファイルを作成し、ウェーブ フォーマット チャンクを書き込む。パラメータは、ファイル名、初期化された WAVEFORMATEX 構造体へのポインタ、および WAVEFILE_WRITE フラグである。このメソッドは HRESULT を返す。

次のコードは、書き込みのためにウェーブ ファイルを開く。

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();
}

これで、アプリケーションはキャプチャ バッファからファイルへのコピーを開始できる。次の関数は、読み込みカーソルが通知位置に到達するたびに呼び出される。次のグローバル変数が使用される。

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;
 
    // プライベート カーソルと読み込みカーソルの間を
    // すべてロックして、ラップアラウンドを可能にする。
 
    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;
 
    // データを書き込む。これは 2 つのステップで行われ、
    // ラップアラウンドが計算される。

    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; 
    }
 
    // キャプチャ バッファをアンロックする。
 
   g_pDSBCapture->Unlock( pbCaptureData, dwCaptureLength, 
            pbCaptureData2, dwCaptureLength2  );
  
    // キャプチャ オフセットを移動する。
 
    g_dwNextCaptureOffset += dwCaptureLength; 
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; 
    g_dwNextCaptureOffset += dwCaptureLength2; 
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; 
 
    return S_OK;
}

キャプチャが終了すると、アプリケーションはウェーブ ファイルを閉じる。

g_pWaveFile->Close();

CWaveFile::Close メソッドは、ファイルを閉じる前に、チャンク サイズをファイルに書き込む。