輪詢 GetCurrentPosition 效率低且延遲高。DirectSound 提供事件通知機制:在緩衝區預設位置設定通知點,讀取游標到達時觸發事件,實現即時資料處理。
IDirectSoundNotify8 介面
LPDIRECTSOUNDNOTIFY8 pNotify;
pDSCBuffer->QueryInterface(IID_IDirectSoundNotify8, (void**)&pNotify);
HANDLE hEvents[3];
for (int i = 0; i < 3; ++i)
hEvents[i] = CreateEvent(NULL, TRUE, FALSE, NULL); // 手動重置、非訊號初始
DSBPOSITIONNOTIFY 陣列
DSBPOSITIONNOTIFY notifies[3];
notifies[0].dwOffset = buffer_size / 2 - 1; // 中點
notifies[0].hEventNotify = hEvents[0];
notifies[1].dwOffset = buffer_size - 1; // 末端
notifies[1].hEventNotify = hEvents[1];
notifies[2].dwOffset = DSBPN_OFFSETSTOP; // 停止捕捉
notifies[2].hEventNotify = hEvents[2];
pNotify->SetNotificationPositions(3, notifies);
pNotify->Release();
Start() 前完成DSBPN_OFFSETSTOP 特殊值:捕捉停止時觸發while (capturing) {
DWORD idx = WaitForMultipleObjects(3, hEvents, FALSE, INFINITE) - WAIT_OBJECT_0;
if (idx == 0) { // 中點通知
ProcessHalfBuffer();
ResetEvent(hEvents[0]);
}
else if (idx == 1) { // 末端通知
ProcessEndBuffer();
ResetEvent(hEvents[1]);
}
else if (idx == 2) { // 停止通知
capturing = false;
}
}
| 方式 | CPU 佔用 | 延遲 | 複雜度 |
|---|---|---|---|
| 輪詢 GetCurrentPosition | 高 (忙碌等待) | 不定 (視輪詢間隔) | 簡單 |
| 事件通知 | 極低 (核心阻塞) | 極低 (硬體觸發) | 中等 |
第六篇:通知機制 ← 當前 | 第七篇:特效 (AEC/NS) | 第八篇:使用緩衝區