|
发表于 2004-7-20 01:29:00
|
显示全部楼层
Re:急!救助!DirectSound的声音播放问题!
使用多个后台缓冲就行了,
相关代码如下:
//sound.h
#include "windows.h"
#include "dsound.h"
#pragma comment(lib, "dsound")
#pragma once
template <typename T>
void Release(T object)
{
if (NULL != object)
{
object->Release ();
object = NULL;
}
}
template <typename T>
void ErrorExit(HWND hWindow,T describe)
{
MessageBox(hWindow, describe, "错误", MB_OK);
exit(1);
}
typedef struct _WAVE_HEADER_
{
BYTE RIFF[4];
DWORD dwSize;
BYTE WAVE[4];
BYTE fmt_[4];
DWORD dw16;
WORD wOne_0;
WORD wChnls;
DWORD dwSRate;
DWORD BytesPerSec;
WORD wBlkAlign;
WORD BitsPerSample;
BYTE DATA[4];
DWORD dwDSize;
} WaveHeader, * pWaveHeader;
class fdSound
{
public:
fdSound();
~fdSound();
bool Init(HWND hWindow);
bool LoadFile(int bufferIndex, LPSTR szFileName);
bool Play(int bufferIndex, bool iLoop);
bool Stop(void);
bool SetVolume(LONG iVolume);
protected:
LPDIRECTSOUND8 m_lpkDSound;
LPDIRECTSOUNDBUFFER m_lpkPSound;
LPDIRECTSOUNDBUFFER m_lpkSound[16];
HWND m_hWindow;
};
//sound.cpp
#include "sound.h"
#include "iostream"
using namespace std;
fdSound::fdSound()
{
ZeroMemory(m_lpkSound, sizeof(LPDIRECTSOUNDBUFFER) * 16);
m_lpkPSound = NULL;
m_lpkDSound = NULL;
}
fdSound::~fdSound()
{
Stop();
for(int i = 0; i < 15; i++)
{
Release(m_lpkSound);
}
Release(m_lpkPSound);
Release(m_lpkDSound);
}
bool fdSound::Init(HWND hWindow)
{
m_hWindow = hWindow;
DirectSoundCreate8(NULL, &m_lpkDSound, NULL);
if (NULL == m_lpkDSound)
{
ErrorExit(m_hWindow,"创建音频设备失败!");
}
if (FAILED (m_lpkDSound->SetCooperativeLevel(m_hWindow, DSSCL_PRIORITY)))
{
ErrorExit(m_hWindow,"创建音频设备失败!");
}
DSBUFFERDESC dsbdesc;
memset( &dsbdesc, 0, sizeof( DSBUFFERDESC ));
dsbdesc.dwSize = sizeof( DSBUFFERDESC );
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME ;
dsbdesc.dwBufferBytes = 0;
dsbdesc.lpwfxFormat = NULL;
if (FAILED (m_lpkDSound->CreateSoundBuffer( &dsbdesc, &m_lpkPSound, NULL )))
{
ErrorExit(m_hWindow,"创建音频缓存失败!");
}
WAVEFORMATEX wfm;
memset( &wfm, 0, sizeof( WAVEFORMATEX ) );
wfm.wFormatTag = WAVE_FORMAT_PCM;
wfm.nChannels = 2;
wfm.nSamplesPerSec = 44100;
wfm.wBitsPerSample = 16;
wfm.nBlockAlign = wfm.wBitsPerSample / 8 * wfm.nChannels;
wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign;
m_lpkPSound->SetFormat(&wfm);
return true;
}
bool fdSound::SetVolume(LONG iVolume)
{
if (FAILED (m_lpkPSound->SetVolume( -(100 - iVolume) * 100)))
{
return false;
}
return true;
}
bool fdSound: lay(int bufferIndex, bool iLoop)
{
if (bufferIndex < 0 || bufferIndex > 15)
{
return false;
}
if(FAILED (m_lpkSound[bufferIndex]->SetCurrentPosition(0)))
{
return false;
}
if (FAILED (m_lpkSound[bufferIndex]-> lay(0, NULL, iLoop ? DSBPLAY_LOOPING : 0)))
{
return false;
}
return true;
}
bool fdSound::Stop(void)
{
if (!m_lpkSound)
{
return false;
}
for (int i = 0; i < 15; i++)
{
if(m_lpkSound)
{
if(FAILED (m_lpkSound->Stop()))
{
return false;
}
if(FAILED (m_lpkSound->SetCurrentPosition(0)))
{
return false;
}
}
}
return true;
}
bool fdSound: oadFile(int bufferIndex, LPSTR szFileName)
{
PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc;
FILE *pFile;
pFile = fopen(szFileName, "rb");
if (!pFile || bufferIndex < 0 || bufferIndex > 15)
{
return false;
}
WaveHeader Wavheader;
if (fread(&Wavheader, sizeof(Wavheader), 1, pFile) != 1)
{
fclose(pFile);
return false;
}
memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = Wavheader.wChnls;
pcmwf.wf.nSamplesPerSec = Wavheader.dwSRate;
pcmwf.wf.nBlockAlign = Wavheader.wBlkAlign;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = Wavheader.BitsPerSample;
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_STATIC;
dsbdesc.dwBufferBytes = Wavheader.dwDSize;
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
if (FAILED (m_lpkDSound->CreateSoundBuffer(&dsbdesc, &m_lpkSound[bufferIndex], NULL)))
{
return false;
}
if (sizeof(Wavheader) != 0xffffffff)
{
if(fseek(pFile, sizeof(Wavheader), SEEK_SET) != 0)
{
return false;
}
}
LPVOID pData1;
DWORD dwData1Size;
LPVOID pData2;
DWORD dwData2Size;
if (FAILED (m_lpkSound[bufferIndex]->Lock(0, Wavheader.dwDSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_ENTIREBUFFER)))
{
return false;
}
if (dwData1Size > 0)
{
fread(pData1, dwData1Size, 1, pFile);
}
if (dwData2Size > 0)
{
fread(pData2, dwData2Size, 1, pFile);
}
if (FAILED (m_lpkSound[bufferIndex]->Unlock(pData1, dwData1Size, pData2, dwData2Size)))
{
return false;
}
fclose(pFile);
return true;
} |
|