
DirectSound顧明思義可以讓你控制聲卡播放聲音和音樂. DirectSound由許多模塊和接口組成,編譯時需要庫文檔DSOUND.LIB和頭文檔DSOUND.H
WAV音檔播放演示程式,按+/-鍵控制聲音音量.按Open載入WAV音檔:下載
1.啟動DirectSound
IDirectSound接口:DirectSound的主COM對象.它代表聲卡硬件.若你裝有多個聲卡,則每個DirectSound對象代表一個聲卡.創建主聲卡對象,輸入NULL與默認聲卡鏈接
LPDIRECTSOUND direct_sound;
DirectSoundCreate(NULL,&direct_sound,NULL);
if (direct_sound == NULL)
return false;
2.設置默認協作等級
設定遊戲控制聲卡的等級.一般設定為DSSCL_NORMAL即可.當程式具有焦點時,即可播放聲音.但並不妨礙其它程式. DirectSound自動創建22kHz,立體聲,8bit主緩存(默認).hWnd為當前窗口句柄
direct_sound->SetCooperativeLevel(hWnd,DSSCL_NORMAL);
參數 | 簡介 |
DSSCL_NORMAL | 默認等級 |
DSSCL_PRIORITY | 優先等級.允許設定主緩存數據格式 |
DSSCL_EXCLUSIVE | 當窗口在前臺時擁有優先等級 |
DSSCL_WRITEPRIMARY | 完全控制主緩存 |
3.輔助(二級)音頻緩存
『輔助緩存』即代表你想播放的音頻.但聲卡上SRAM卻容量有限,而且我印象中只在ISA版CREATIVE(創新)聲卡有出現.『輔助緩存』分為『靜態緩存』與『動態緩存』.『靜態緩存』用於存儲經常播放短聲音.『動態緩存』用於存儲較長聲音.DirectSound不斷播放不斷把音頻數據寫入『輔助緩存』.使用稱為Circular Buffering(環形緩存)結構,一個指針寫入音頻數據,另一個指針讀取音頻數據.創建輔助聲音緩衝器
HRESULT IDirectSound::CreateSoundBuffer(
LPCDSBUFFERDESC lpcDSBufferDesc,
LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer,
IUnknown FAR* pUnkOuter
);
4.設置緩存格式描敘,單聲道11kHz,8bit
AVEFORMATEX format;
format.cbSize = 0;//高級,總是0.
format.wFormatTag = WAVE_FORMAT_PCM;//PCM編碼
format.nChannels = 1;//(聲道數目)1為單聲道播放
format.nSamplesPerSec = 11025;// 樣本速度11kHz
//設置字節對齊.
//單聲道乘以1字節(8Bit), 它將是1字節字節對齊.
//立體聲它將是雙聲道8Bit, 它將是2字節字節對齊.
//如果它是立體聲系統和16Bit它將是4字節對齊.
format.nBlockAlign = 1;
format.wBitsPerSample = 8;//聲言位數為8BIT
format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign;// 每秒字節
3.設定聲音緩沖存儲器描敘表
DSBUFFERDESC buffer;// 描述結構
memset(&buffer,0,sizeof(DSBUFFERDESC));// 清零
buffer.dwSize = sizeof(DSBUFFERDESC);// 結構所占空間
//設置DirectSoundBuffer的描述結構的標誌
buffer.dwFlags = DSBCAPS_CTRLPAN | // 緩存擁有總控制功能
DSBCAPS_CTRLVOLUME | // 緩存擁有音量控制功能
DSBCAPS_CTRLFREQUENCY; // 緩存擁有頻率控制功能
buffer.dwBufferBytes = sound_size;//聲音數據大小.
buffer.lpwfxFormat = &format;//”WAV文件格式描述結構”
4.創建輔助(二級)音頻緩存
LPDIRECTSOUNDBUFFER sound_buffer;
direct_sound->CreateSoundBuffer(&buffer, &sound_buffer, NULL);
if (sound_buffer == NULL)
return false;
5.鎖住緩存
UCHAR *audio_ptr_1 = NULL, //指向緩存第一部分
UCHAR *audio_ptr_2 = NULL; //指向緩存第二部分
DWORD audio_len_1 = 0, //第一緩存長度
DWORD audio_len_2 = 0; //第二緩存長度
sound_buffer->Lock(0,//寫入指針指向位置
sound_size,//要鎖定大小,音頻數據長度.
(void **)&audio_ptr_1,//第一個部分開始地址.
&audio_len_1,//第一個部分長度
(void **)&audio_ptr_2,//第二個部分開始地址.
&audio_len_2,//第二個部分長度
DSBLOCK_FROMWRITECURSOR);// 緩存當前寫入點將被鎖住.
6.拷貝到環形緩存第一部分, sound_size為音頻數據
memcpy(audio_ptr_1, sound_data, audio_len_1);
7.拷貝到環形緩存第二段中
memcpy(audio_ptr_2, (sound_data + audio_len_1), audio_len_2);
8.解鎖
sound_buffer->Unlock(audio_ptr_1,audio_len_1,audio_ptr_2,audio_len_2);
9.循環播放聲音
sound_buffer->Play(0,0,DSBPLAY_LOOPING);
10.若單次播放聲音
sound_buffer->Play(0, 0, 0);
11.當退出遊戲時需要釋放緩存和聲卡
sound_buffer->Release();
direct_sound->Release();