首页 > 新闻系统 > 媒体动画 > 文章正文

利用Directsound 3D实现游戏中3D音效

2005-12-13 17:39:03 来源:天极yesky 作者: 点击:



//初始化Dsound
HRESULT hr;
if(FAILED(hr = DirectSoundCreate8(NULL,&g_pDsd,NULL)))
 return FALSE;
if(FAILED(hr = g_pDsd->SetCooperativeLevel(m_hWnd,DSSCL_PRIORITY)))
 return FALSE;
//初始化Directsound 的主缓冲区,并设置格式
LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;
DSBUFFERDESC dsbdesc ;
ZeroMemory(&dsbdesc,sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;//一定不要忘记创建主缓冲区的时候要设置DSBCAPS_CTRL3D标志。只有指定了这个标志,后面你才能从这个辅助缓冲区中请求到3D的buffer指针。
if(FAILED(hr = g_pDsd->CreateSoundBuffer(&dsbdesc,&pDSBPrimary ,NULL)))
 return FALSE;
 //获取3D 模拟世界中的听者指针。
if( FAILED( hr = pDSBPrimary->QueryInterface( IID_IDirectSound3DListener, (VOID**)&g_pDSListener ) ) )
 return FALSE;

WAVEFORMATEX wfx;
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
wfx.wFormatTag = (WORD) WAVE_FORMAT_PCM;
wfx.nChannels = WAVECHANNEL ;
wfx.nSamplesPerSec = WAVESAMPLEPERSEC ;
wfx.wBitsPerSample = WAVEBITSPERSAMPLE ;
wfx.nBlockAlign = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels);
wfx.nAvgBytesPerSec = (DWORD) (wfx.nSamplesPerSec * wfx.nBlockAlign);
if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) ) //设置缓冲区的音频格式。
 return FALSE;

  第3步,创建辅助缓冲区,通过辅助缓冲区获取3dbuffer指针

DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_CTRL3D| DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2;
//看看创建辅助缓冲区的buffer时设置的标志,3D的标志自然是需要的,还有一个标志需要注意,DSBCAPS_CTRLPOSITIONNOTIFY,如果你采用的流(stream)buffer的话,就需要边播放,边向buffer中填充数据,就需要设置这个标志,这样,在directsound播放到指定位置时,就会触发事件。
//dsbd.dwBufferBytes =MAX_AUDIO_BUF * BUFFERNOTIFYSIZE ;//如果采用流buffer,可以设置适当的buffer大小。
dsbd.dwBufferBytes =g_pWaveFile->GetSize(); // 如果采用静态buffer,那么buffer的大小就是文件的大小了。
dsbd.guid3DAlgorithm = guid3DAlgorithm;
dsbd.lpwfxFormat = g_pWaveFile->m_pwfx;
if(FAILED(hr = g_pDsd->CreateSoundBuffer(&dsbd,&g_pDSBuffer,NULL)))
 return ;
 //通过辅助缓冲区,来获取3D buffer的指针。
if(FAILED(hr = g_pDSBuffer->QueryInterface(IID_IDirectSound3DBuffer, (VOID**)&g_pDS3DBuffer )))
 return ;

g_dsBufferParams.dwSize = sizeof(DS3DBUFFER);
g_pDS3DBuffer->GetAllParameters( &g_dsBufferParams );

//设置3Dbuffer的属性。
g_dsBufferParams.dwMode = DS3DMODE_HEADRELATIVE;
g_pDS3DBuffer->SetAllParameters( &g_dsBufferParams, DS3D_IMMEDIATE );

  第4步 设置多普勒因子以及最小最大距离。

FLOAT fDopplerFactor;
FLOAT fRolloffFactor;
FLOAT fMinDistance;
FLOAT fMaxDistance;

CSliderCtrl *pDopplerSlider = (CSliderCtrl*)GetDlgItem(IDC_DOPPLER_SLIDER);
fDopplerFactor = pDopplerSlider->GetPos();

CSliderCtrl *pRolloffSlider= (CSliderCtrl*)GetDlgItem(IDC_ROLLOFF_SLIDER);
fRolloffFactor = pRolloffSlider->GetPos();

CSliderCtrl *pMinDistSlider = (CSliderCtrl*)GetDlgItem(IDC_MINDISTANCE_SLIDER );
fMinDistance = pMinDistSlider->GetPos();
CSliderCtrl *pMaxDistSlider = (CSliderCtrl*)GetDlgItem(IDC_MAXDISTANCE_SLIDER );
fMaxDistance = pMaxDistSlider->GetPos();

g_dsListenerParams.flDopplerFactor = fDopplerFactor;
g_dsListenerParams.flRolloffFactor = fRolloffFactor;

if( g_pDSListener )
{
 g_pDSListener->SetAllParameters( &g_dsListenerParams, DS3D_DEFERRED );
 g_pDSListener->CommitDeferredSettings();
}

g_dsBufferParams.flMinDistance = fMinDistance;
g_dsBufferParams.flMaxDistance = fMaxDistance;

if( g_pDS3DBuffer )
 g_pDS3DBuffer->SetAllParameters( &g_dsBufferParams, DS3D_DEFERRED );

  第5步 然后就是通过调用辅助缓冲区的play方法,来进行播放音频文件了。
9 7 3 1 2 3 4 4 8 :

精彩推荐
本类热门文章

论坛美图

本周软件下载排行

广告联系 | 版权说明 | 意见建议 | 加入收藏 | 军网站群 [ 军软件园 - 军软件商城 - 军软件园论坛 ]

电信与信息服务业务经营许可证:京ICP证050203