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

DirectSound 開發指南:WAV 音訊資料的載入與播放

     編輯:關於VC++

WAV 格式與 DirectSound 緩衝區支援

在 Windows 驅動模型(WDM)架構下,DirectSound 硬體緩衝區支援所有可由 WAVEFORMATEX 或 WAVEFORMATEXTENSIBLE 結構描述、且為硬體支援的壓縮或非壓縮音訊格式。軟體緩衝區與非 WDM 硬體緩衝區則僅限 8-bit 與 16-bit PCM 非壓縮格式。

多聲道 WAV 格式(WAVEFORMATEXTENSIBLE)

WDM 驅動程式允許 DirectSound 緩衝區處理超過兩個輸出聲道的 WAV 格式(如 5.1 環繞聲:前左、中、前右、後左、後右、超低音)。WAVEFORMATEXTENSIBLE 結構擴展了 WAVEFORMATEX,利用其 cbSize 成員新增的位元組來描述通道遮罩、位元深度與子格式 GUID。需要 WAVEFORMATEX 時,該結構可安全向下轉型。

注意:若系統實體喇叭少於 WAV 指定聲道數,音訊會自動混音輸出。DirectSound **不支援** 多聲道緩衝區的 3D 定位與音效(DSBCAPS_CTRL3D、DSBCAPS_CTRLFX),嘗試建立此類緩衝區會失敗。

RIFF/WAV 檔案結構與讀取

WAV 檔案採用資源交換檔案格式(RIFF),由多個具名區塊組成,包含格式區塊(採樣率、聲道數等)與資料區塊(實際採樣點)。Win32 API 提供 mmio* 系列函式(mmioOpen、mmioDescend 等)解析 RIFF 結構。

SDK 範例類別架構(Dsutil.cpp)

DirectSound API 本身不提供載入音訊的高階方法。SDK 範例通用的 Dsutil.cpp 封裝了核心類別:

  • CSoundManager:管理裝置初始化與緩衝區建立。
  • CSound:代表靜態緩衝區,適合短小音效,支援多實例同時播放。
  • CStreamingSound:代表串流緩衝區,適合長音樂,邊播放邊更新資料。
  • CWaveFile:底層 RIFF 解析器,受保護成員,通常不直接使用。

初始化與播放標準流程

  1. 建立 CSoundManager 實例。
  2. 呼叫 CSoundManager::Initialize() 建立 DirectSound 裝置。
  3. 呼叫 CSoundManager::Create()(檔案/資源)或 CreateFromMemory() 取得 CSound;或傳遞檔案名給 CStreamingSound 建構子取得串流物件。
  4. 呼叫 FillBufferWithSound() 將資料讀入緩衝區。串流緩衡區則填滿初始資料,播放期間透過 CStreamingSound::HandleWaveStreamNotification() 回呼持續補充。

計算 WAV 音訊長度

播放時長 = 資料大小 / 平均位元組率。可透過 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;
}

此函式獨立於範例類別,直接展示核心計算邏輯,便於整合至自有專案。

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