音訊捕捉核心流程包含:啟動緩衝區 → 等待資料 → 鎖定讀取 → 複製資料 → 解鎖 → 重複 → 停止。本文詳細說明各步驟關鍵 API 與注意事項。
pDSBCapture->Start(DSCBSTART_LOOPING); // 循環模式,避免緩衝區滿即停止
透過通知機制 (參見第六篇) 或輪詢 GetCurrentPosition 判斷讀取游標位置。
DWORD dwReadPos, dwCapturePos;
pDSBCapture->GetCurrentPosition(&dwCapturePos, &dwReadPos);
// dwReadPos:已完整寫入緩衝區的資料末端,可安全讀取至該位置
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 非空)。
使用 memcpy 或直接處理 pvAudioPtr1/2 指向的記憶體區塊。
pDSBCapture->Unlock(pvAudioPtr1, dwAudioBytes1, pvAudioPtr2, dwAudioBytes2);
dwNextCaptureOffset = (dwNextCaptureOffset + dwAudioBytes1 + dwAudioBytes2) % dwBufferSize;
dwReadPos) 分隔兩者,確保不讀取未完成資料pDSBCapture->Stop(); // 停止硬體捕捉,釋放資源
| 錯誤 | 後果 | 正確做法 |
|---|---|---|
| 未用 LOOPING 旗標 | 緩衝區滿即停止,丟失後續音訊 | 啟動時指定 DSCBSTART_LOOPING |
| 未檢查讀取游標直接鎖定 | 可能鎖定正在寫入的區域,資料損毀 | 先 GetCurrentPosition 取得 dwReadPos |
| 忽略環繞情況 | 跨越緩衝區邊界時只複製第一段 | 檢查 pvAudioPtr2,雙段複製 |
| 未更新 dwNextCaptureOffset | 重複讀取或遺漏資料 | 每次解鎖後按實際讀取位元組數更新 |
本文為第八篇,建議按序閱讀:枚舉裝置 → 建立裝置 → 能力查詢 → 建立緩衝區 → 緩衝區資訊 → 通知機制 → 特效 → 使用緩衝區 (本文) → 寫入 WAV。