カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

録音位置の挙動

デバイスを初期化した直後、録音用リングバッファの録音位置は、ゼロに初期化されています。処理が始まり、読み出し位置が更新領域の最後のオフセットを横切った瞬間、ノーティファイイベントが発生します。この時、最初の更新領域は録音データで満たされています。

ここで試験のため、いったん録音を停止します。この時点で重要なのは、録音位置が中途半端な場所で止まっているということです。そして録音を再開すると、半端な位置から録音が始まるため、デバイス初期化後とは同じ動作になりません。

次に読み出し位置が更新領域を横切った時、バッファには途中から録音されたデータが残ります。バッファは満たされておらずデータサイズもその時々で異なります。

録音用リングバッファの位置設定コマンドは、なぜか支援されていません。位置の初期化ができれば便利なのですが…

この状態で再生側の更新サイズを固定にしていると不具合となります。1回目は動くが、2回目以降ノイズが入るという症状が出ます。

この対策として以下の方法があります。

読み出し位置をまるめるには、以下のようにします。

    pDSCBuffer->GetCurrentPosition(NULL, &dwNextCaptureOffset);
    dwNextCaptureOffset -= dwNotifySize;

こうすると更新領域全体が有効なデータとして取り込まれます。ただし欠点として、頭に空白のあるデータが取得されるので、録音開始と同時に有効なデータを取得したい用途には向きません。また空白の時間だけレイテンシーが大きくなります。

再生側で任意のデータサイズを受け付ける方法もあります。

この方法の利点は、録音されたデータがすぐ再生側に反映されることです。ただし再生側では、リングバッファを更新領域単位でアクセスできなくなります。バッファをロックする際つなぎ目をまたぐことになるので、以下に示すようにBuffer2を処理するコードを追加する必要があります。

    hr = pDSBuffer->Lock(
        dwNextWriteOffset, dwCaptureSize,
        &pDSLockedBuffer, &dwDSLockedBufferSize,
        &pDSLockedBuffer2, &dwDSLockedBufferSize2,
        0L);
    if (FAILED(hr))         return hr;

    CopyMemory(pDSLockedBuffer, pCaptureData, dwDSLockedBufferSize);

    if (pDSLockedBuffer2)
    {
        CopyMemory(
            pDSLockedBuffer2,
            (LPBYTE)pCaptureData + dwDSLockedBufferSize,
            dwDSLockedBufferSize2);
    }
    hr = pDSBuffer->Unlock(
        pDSLockedBuffer, dwDSLockedBufferSize,
        pDSLockedBuffer2, dwDSLockedBufferSize2);
    if (FAILED(hr))         return hr;
マイクロソフトのサンプルコードは、読み出し位置をまるめる方法を採用しています。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ