首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

DirectSound 波形捕捉系列(八):使用捕捉緩衝區

     編輯:關於C++

DirectSound 捕捉緩衝區完整操作流程

音訊捕捉核心流程包含:啟動緩衝區 → 等待資料 → 鎖定讀取 → 複製資料 → 解鎖 → 重複 → 停止。本文詳細說明各步驟關鍵 API 與注意事項。

六步驟標準流程

  1. 啟動捕捉
    pDSBCapture->Start(DSCBSTART_LOOPING);  // 循環模式,避免緩衝區滿即停止
  2. 等待足夠資料

    透過通知機制 (參見第六篇) 或輪詢 GetCurrentPosition 判斷讀取游標位置。

  3. 取得讀取游標位置
    DWORD dwReadPos, dwCapturePos;
    pDSBCapture->GetCurrentPosition(&dwCapturePos, &dwReadPos);
    // dwReadPos:已完整寫入緩衝區的資料末端,可安全讀取至該位置
  4. 鎖定緩衝區
    LONG lLockSize = dwReadPos - dwNextCaptureOffset;
    if (lLockSize < 0) lLockSize += dwBufferSize;  // 處理環繞
    
    void* pvAudioPtr1; DWORD dwAudioBytes1;
    void* pvAudioPtr2; DWORD dwAudioBytes2;
    pDSBCapture->Lock(dwNextCaptureOffset, lLockSize,
        &pvAudioPtr1, &dwAudioBytes1,
        &pvAudioPtr2, &dwAudioBytes2, 0);

    若鎖定區域跨越緩衝區末尾,返回兩段指標 (pvAudioPtr2 非空)。

  5. 複製資料

    使用 memcpy 或直接處理 pvAudioPtr1/2 指向的記憶體區塊。

  6. 解鎖並更新位移
    pDSBCapture->Unlock(pvAudioPtr1, dwAudioBytes1, pvAudioPtr2, dwAudioBytes2);
    dwNextCaptureOffset = (dwNextCaptureOffset + dwAudioBytes1 + dwAudioBytes2) % dwBufferSize;

關鍵設計模式:生產者-消費者

  • 生產者:音訊驅動程式持續寫入硬體緩衝區 (捕捉游標推進)
  • 消費者:應用程式定期讀取已就緒資料 (讀取游標推進)
  • 同步機制:讀取游標 (dwReadPos) 分隔兩者,確保不讀取未完成資料

停止捕捉

pDSBCapture->Stop();  // 停止硬體捕捉,釋放資源

常見錯誤避坑

錯誤後果正確做法
未用 LOOPING 旗標緩衝區滿即停止,丟失後續音訊啟動時指定 DSCBSTART_LOOPING
未檢查讀取游標直接鎖定可能鎖定正在寫入的區域,資料損毀先 GetCurrentPosition 取得 dwReadPos
忽略環繞情況跨越緩衝區邊界時只複製第一段檢查 pvAudioPtr2,雙段複製
未更新 dwNextCaptureOffset重複讀取或遺漏資料每次解鎖後按實際讀取位元組數更新

完整系列導覽

本文為第八篇,建議按序閱讀:枚舉裝置 → 建立裝置 → 能力查詢 → 建立緩衝區 → 緩衝區資訊 → 通知機制 → 特效 → 使用緩衝區 (本文) → 寫入 WAV。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved