在 Windows 驅動模型(WDM)架構下,DirectSound 硬體緩衝區支援所有可由 WAVEFORMATEX 或 WAVEFORMATEXTENSIBLE 結構描述、且為硬體支援的壓縮或非壓縮音訊格式。軟體緩衝區與非 WDM 硬體緩衝區則僅限 8-bit 與 16-bit PCM 非壓縮格式。
WAVEFORMATEXTENSIBLE)WDM 驅動程式允許 DirectSound 緩衝區處理超過兩個輸出聲道的 WAV 格式(如 5.1 環繞聲:前左、中、前右、後左、後右、超低音)。WAVEFORMATEXTENSIBLE 結構擴展了 WAVEFORMATEX,利用其 cbSize 成員新增的位元組來描述通道遮罩、位元深度與子格式 GUID。需要 WAVEFORMATEX 時,該結構可安全向下轉型。
注意:若系統實體喇叭少於 WAV 指定聲道數,音訊會自動混音輸出。DirectSound **不支援** 多聲道緩衝區的 3D 定位與音效(DSBCAPS_CTRL3D、DSBCAPS_CTRLFX),嘗試建立此類緩衝區會失敗。
WAV 檔案採用資源交換檔案格式(RIFF),由多個具名區塊組成,包含格式區塊(採樣率、聲道數等)與資料區塊(實際採樣點)。Win32 API 提供 mmio* 系列函式(mmioOpen、mmioDescend 等)解析 RIFF 結構。
DirectSound API 本身不提供載入音訊的高階方法。SDK 範例通用的 Dsutil.cpp 封裝了核心類別:
CSoundManager:管理裝置初始化與緩衝區建立。CSound:代表靜態緩衝區,適合短小音效,支援多實例同時播放。CStreamingSound:代表串流緩衝區,適合長音樂,邊播放邊更新資料。CWaveFile:底層 RIFF 解析器,受保護成員,通常不直接使用。CSoundManager 實例。CSoundManager::Initialize() 建立 DirectSound 裝置。CSoundManager::Create()(檔案/資源)或 CreateFromMemory() 取得 CSound;或傳遞檔案名給 CStreamingSound 建構子取得串流物件。FillBufferWithSound() 將資料讀入緩衝區。串流緩衡區則填滿初始資料,播放期間透過 CStreamingSound::HandleWaveStreamNotification() 回呼持續補充。播放時長 = 資料大小 / 平均位元組率。可透過 CWaveFile::GetSize() 取得資料位元組數,GetFormat() 取得 WAVEFORMATEX 中的 nAvgBytesPerSec。
DWORD GetSoundLength(LPSTR strFileName)
{
CWaveFile* pWav = new CWaveFile();
DWORD dwLen = 0;
if (SUCCEEDED(pWav->Open(strFileName, NULL, WAVEFILE_READ)))
{
WAVEFORMATEX* wfx = pWav->GetFormat();
DWORD dwSize = pWav->GetSize();
dwLen = (DWORD)(1000.0 * dwSize / wfx->nAvgBytesPerSec); // 毫秒
pWav->Close();
}
delete pWav;
return dwLen;
}
此函式獨立於範例類別,直接展示核心計算邏輯,便於整合至自有專案。