VC下完成DirectSound
發(fā)表時(shí)間:2023-08-19 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]武漢石化設(shè)計(jì)院電算室周紅漢---- 加入音樂(lè)是增強(qiáng)應(yīng)用程序功能的所有方法中最簡(jiǎn)單的一個(gè)。音樂(lè)可以使用戶心情愉快;在合適的場(chǎng)合播放恰當(dāng)?shù)囊魳?lè)能夠使程序員和他的VC++程序煥發(fā)光彩。---- Micro...
武漢石化設(shè)計(jì)院電算室
周紅漢
---- 加入音樂(lè)是增強(qiáng)應(yīng)用程序功能的所有方法中最簡(jiǎn)單的一個(gè)。音樂(lè)可以使用戶心情
愉快;在合適的場(chǎng)合播放恰當(dāng)?shù)囊魳?lè)能夠使程序員和他的VC++程序煥發(fā)光彩。
---- Microsoft Windows Multimedia API提供了三種方法來(lái)播放WAV文件:
PlaySound()函數(shù)。它可以通過(guò)單行編碼來(lái)播放Wave格式的聲音。此函數(shù)有兩個(gè)限制
:必須將聲音數(shù)據(jù)完整地載入物理內(nèi)存;數(shù)據(jù)格式必須被所配置的某一音頻驅(qū)動(dòng)器支
持。根據(jù)經(jīng)驗(yàn),PlaySound()適用于100K以下的文件。
MCI(The Media Control Interface)。MCI功能強(qiáng)大,不僅可以實(shí)現(xiàn)WAV文件的播放,
而且還可以播放MIDI及CD音頻。
低級(jí)Wave音頻設(shè)備。用這些設(shè)備可以運(yùn)行完全控制Wave數(shù)據(jù)的應(yīng)用文件。
---- 前兩種方法使用簡(jiǎn)單,但無(wú)法實(shí)現(xiàn)兩個(gè)及兩個(gè)以上的WAV文件的播放;第三種方法
實(shí)現(xiàn)起來(lái)非常復(fù)雜,非專業(yè)人員很難完成。DirectSound可以實(shí)現(xiàn)八個(gè)及八個(gè)以上WAV文
件的同時(shí)播放,能使多媒體程序更加生動(dòng),而且簡(jiǎn)單易用,但它僅適合于Windows 95下
的程序,也不支持WAV文件的記錄及存儲(chǔ)""這是唯一讓人遺憾的地方。實(shí)現(xiàn)
DirectSound需要以下幾個(gè)步驟:
1. 創(chuàng)建及初始化DirectSound
LPDIRECTSOUND m_pDirectObject;
if(DirectSoundCreate(NULL,&m_pDirectObject,NULL)==DS_OK)
file://設(shè)定應(yīng)用程序的聲音設(shè)備優(yōu)先級(jí)別方式,一般為DSSCL_NORMAL
m_pDirectObject->SetCooperativeLevel
(this- >m_hWnd,DSSCL_NORMAL);
else
AfxMessageBox("DirectSound Create failed");
2. 將WAV文件讀入內(nèi)存,找到格式塊,數(shù)據(jù)塊位置及數(shù)據(jù)長(zhǎng)度。
m_pMemory,m_pFormat,m_pData,m_dwSize在頭文件中聲明。
BOOL CDirectWave::LoadFile (CString Filename){
CFile File;
DWORD dwSize;
if (!File.Open (Filename,
CFile::modeRead CFile::shareDenyNone))
return FALSE;
dwSize = File.Seek (0, CFile::end);
File.Seek (0, CFile::begin);
file://m_pMemory內(nèi)存存儲(chǔ)塊指針,類型:LPVOID
m_pMemory = GlobalAlloc (GMEM_FIXED, dwSize);
if (File.ReadHuge (m_pMemory, dwSize) != dwSize){
File.Close ();
return FALSE;
}
File.Close ();
LPDWORD pdw,pdwEnd;
DWORD dwRiff,dwType, dwLength, dwLength;
if (m_pFormat) file://格式塊指針,類型:LPWAVEFORMATEX
m_pFormat = NULL;
if (m_pData) file://數(shù)據(jù)塊指針,類型:LPBYTE
m_pData = NULL;
if (m_dwSize) file://數(shù)據(jù)長(zhǎng)度,類型:DWORD
m_dwSize = 0;
pdw = (DWORD *) m_pMemory;
dwRiff = *pdw++;
dwLength = *pdw++;
dwType = *pdw++;
if (dwRiff != mmioFOURCC ('R', 'I', 'F', 'F'))
return FALSE;
if (dwType != mmioFOURCC ('W', 'A', 'V', 'E'))
return FALSE;
file://尋找格式塊,數(shù)據(jù)塊位置及數(shù)據(jù)長(zhǎng)度
pdwEnd = (DWORD *)((BYTE *) pdw + dwLength - 4);
while (pdw < pdwEnd){
dwType = *pdw++;
dwLength = *pdw++;
switch (dwType){
case mmioFOURCC('f', 'm', 't', ' '):
if (!m_pFormat){
if (dwLength < sizeof (WAVEFORMAT))
return FALSE;
m_pFormat = (LPWAVEFORMATEX) pdw;
if (m_pData && m_dwSize)
return TRUE;
}
break;
case mmioFOURCC('d', 'a', 't', 'a'):
if (!m_pData !m_dwSize){
m_pData = (LPBYTE) pdw;
m_dwSize = dwLength;
if (m_pFormat)
return TRUE;
}
break;
}
pdw = (DWORD *)((BYTE *) pdw +
((dwLength + 1) &~ 1));
}
file://未找到,返回FALSE
return FALSE;
}
3. 創(chuàng)建聲音緩沖區(qū)
DSBUFFERDESC BufferDesc;
memset (&BufferDesc, 0, sizeof (BufferDesc));
BufferDesc.lpwfxFormat = (LPWAVEFORMATEX) m_pFormat;
BufferDesc.dwSize = sizeof (DSBUFFERDESC);
BufferDesc.dwBufferBytes = m_dwSize;
BufferDesc.dwFlags = 0;
file://頭文件中聲明m_pDSoundBuffer,類
型:LPDIRECTSOUNDBUFFER
if (pDSoundObject->CreateSoundBuffer
(&BufferDesc, &m_pDSoundBuffer, 0) != DS_OK)
return FALSE;
4. 載入聲音數(shù)據(jù)
BOOL CDirectWave::LoadData (void){
LPVOID lpPtr1, lpPtr2;
DWORD dwLen1, dwLen2;
HRESULT hResult;
TryLoad:
hResult = m_pDSoundBuffer- >Lock
(0, m_dwSize, &lpPtr1, &dwLen1, &lpPtr2, &dwLen2, 0);
if (hResult == DS_OK){
memcpy (lpPtr1, m_pData, dwLen1);
if (lpPtr2)
memcpy (lpPtr2, m_pData + dwLen1, dwLen2);
m_pDSoundBuffer- >Unlock
(lpPtr1, dwLen1, lpPtr2, dwLen2);
return TRUE;
}
else if (hResult == DSERR_BUFFERLOST){
hResult = m_pDSoundBuffer- >Restore ();
if (hResult == DS_OK)
goto TryLoad;
}
return FALSE;
}
5. 播放及停止
void CDirectWave::Play (BOOL bLoop){
DWORD dwFlags = 0;
file://dwFlags= DSBPLAY_LOOPING可實(shí)現(xiàn)循環(huán)播放
TryPlay:
if (m_pDSoundBuffer- >
Play (0, 0, dwFlags) == DSERR_BUFFERLOST){
if (LoadData ())//數(shù)據(jù)丟失,重新裝載
goto TryPlay;
}
}
void CDirectWave::Stop (void){
m_pDSoundBuffer- >Stop ();
}
6. 關(guān)閉。釋放內(nèi)存塊,聲音緩沖區(qū)。
DirectSound需要用到mmsystem.h,dsound.h兩個(gè)頭文件。