首战用DirectSound改造waveout,贴出成功播放声音的代码
2014-05-07 22:59
453 查看
以下为设置
HRESULT CPlay_AudioPlay::StartDirectSound()
{
//下面初始化DirectSound工作。
HRESULT hr;
if(FAILED(hr = DirectSoundCreate8(NULL,&m_pDsd,NULL)))
{
return PLAY_USUAL_ERROR;
}
//设置设备的协作度
if(FAILED(hr = m_pDsd->SetCooperativeLevel(m_hwnd,DSSCL_PRIORITY)))
{
return PLAY_USUAL_ERROR;
}
WAVEFORMATEX waveformat;
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.nChannels = 1;
waveformat.nSamplesPerSec = 8000;
waveformat.wBitsPerSample = 16;
waveformat.nBlockAlign = waveformat.nChannels * waveformat.wBitsPerSample /8;
waveformat.nAvgBytesPerSec = waveformat.nBlockAlign * waveformat.nSamplesPerSec;
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_GLOBALFOCUS ¦ DSBCAPS_CTRLFX ¦ DSBCAPS_CTRLPOSITIONNOTIFY ¦DSBCAPS_GETCURRENTPOSITION2;
dsbd.dwBufferBytes = waveformat.nAvgBytesPerSec * 4; //Set 3 Second Buffer
dsbd.lpwfxFormat = &waveformat;
LPDIRECTSOUNDBUFFER lpbuffer;
//创建辅助缓冲区对象
if(FAILED(hr = m_pDsd->CreateSoundBuffer(&dsbd,&lpbuffer,NULL)))
{
return PLAY_USUAL_ERROR;
}
if( FAILED( hr = lpbuffer->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &m_pDSBuffer8)))
{
return PLAY_USUAL_ERROR;
}
lpbuffer->Release();
//设置通知长度
LPDIRECTSOUNDNOTIFY8 g_pDSNotify = NULL;
DSBPOSITIONNOTIFY g_aPosNotify[AUDIO_BUF_NUM];//设置通知标志的数组
for(int i =0; i < AUDIO_BUF_NUM;i++)
{
g_aPosNotify[i].dwOffset = i* waveformat.nAvgBytesPerSec ;
g_aPosNotify[i].hEventNotify = m_event[i];
}
if(FAILED(hr = m_pDSBuffer8->QueryInterface(IID_IDirectSoundNotify,(LPVOID *) &g_pDSNotify )))
return PLAY_USUAL_ERROR;
g_pDSNotify->SetNotificationPositions(AUDIO_BUF_NUM,g_aPosNotify);
g_pDSNotify->Release();
return 0;
}
以下为传送数据
ASample = *((AVSample*)pAudioPlay->m_pAudioData);
pAudioPlay->m_pSynchronism->GetClearanceTime(ASample,lClearanceTime);
lTime = GetTickCount() - lTime;
if(lClearanceTime > 0)
{
// tools.WaitTime(lClearanceTime); //音视频同步播放
}
lTempLen = pAudioPlay->m_lReadLen - sizeof(AVSample);
pAudioPlay->m_pDSBuffer8->Lock(0,0,&(lpLockBufExcursion),&lDataLengthRemain,
&lpLockBufStart,&lDataLengthWrite,DSBLOCK_ENTIREBUFFER);
memcpy(lpLockBufExcursion,pAudioPlay->m_pAudioData + sizeof(AVSample),lTempLen);
TRACE("x=%x,Remain = %d, WriteLength = %d/n",lpLockBufExcursion,lDataLengthRemain,lTempLen);
pAudioPlay->m_pDSBuffer8->Unlock(lpLockBufExcursion,lDataLengthRemain,lpLockBufStart,lDataLengthWrite);
// pAudioPlay->m_pDSBuffer8->SetCurrentPosition(0);
pAudioPlay->m_pDSBuffer8->Play(0,0,DSBPLAY_LOOPING);
// WaitForMultipleObjects (AUDIO_BUF_NUM, pAudioPlay->m_event, FALSE, INFINITE);
数据为单声道立体声,采样率8000,16bit,每个音频包相隔10毫秒。
每次读出数据长度160字节,放入缓冲区。缓冲区64000字节。每次返回的lpLockBufExcursion,lDataLengthRemain都相同
传入的数据使用waveout时是可以播放的,应该不是数据的问题。
我保存了一秒的数据塞进去还是不行。
请问我哪里做错了。
问题解决了,我写数据的时候,总是写在开头,本想着调用Play把数据播放完了,就播放下一帧,写在缓冲区开头应该没问题。
现在我自己记录已经写入的数据总长度,在LOCK时把数据放在已经写入数据的最后。直到填满缓冲区,之后再把总长度置零。
贴出相关代码:
LONG TotalLength = 0;
。。。。。
char * buf = (char*)lpLockBufExcursion;
memcpy(buf + TotalLength,pAudioPlay->m_pAudioData + sizeof(AVSample),lTempLen);
TotalLength += lTempLen;
if(TotalLength >= 64000)
{
TotalLength = 0;
}
后记,总算是把声音放出来了,也总算稍微了解一点DirectSound了。
但像
// pAudioPlay->m_pDSBuffer8->SetCurrentPosition(0);
//WaitForMultipleObjects (AUDIO_BUF_NUM, pAudioPlay->m_event, FALSE, INFINITE);
我都把注释起来了,因为还不会用。暂时先这样吧,之后再有什么经验,我还是会在我的博客上共享的。
国内的奉献精神和学习气氛严重有问题,我在网上查了好几天的资料,发了好几个帖子,竟然没人能够给我什么有用的提示和帮助,中国的程序员很牛X吗?中国的编程水平跟外国都快差一个时代了。中国程序员写出什么给人印象深刻的东西了。
为什么中国人都要表现的那么自私,这才算中国的文化吗?
DirectX是别人的,总是去学习别人的东西怎么用,什么时候才能做出自己的东西,核心的东西。
我把我所有的编程经验都贴出来,因为我想让初学者少走弯路,能更快去研究更高端的东西。我想加速中国的软件发展,即使只有一丝的效果,我也要去做。
HRESULT CPlay_AudioPlay::StartDirectSound()
{
//下面初始化DirectSound工作。
HRESULT hr;
if(FAILED(hr = DirectSoundCreate8(NULL,&m_pDsd,NULL)))
{
return PLAY_USUAL_ERROR;
}
//设置设备的协作度
if(FAILED(hr = m_pDsd->SetCooperativeLevel(m_hwnd,DSSCL_PRIORITY)))
{
return PLAY_USUAL_ERROR;
}
WAVEFORMATEX waveformat;
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.nChannels = 1;
waveformat.nSamplesPerSec = 8000;
waveformat.wBitsPerSample = 16;
waveformat.nBlockAlign = waveformat.nChannels * waveformat.wBitsPerSample /8;
waveformat.nAvgBytesPerSec = waveformat.nBlockAlign * waveformat.nSamplesPerSec;
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_GLOBALFOCUS ¦ DSBCAPS_CTRLFX ¦ DSBCAPS_CTRLPOSITIONNOTIFY ¦DSBCAPS_GETCURRENTPOSITION2;
dsbd.dwBufferBytes = waveformat.nAvgBytesPerSec * 4; //Set 3 Second Buffer
dsbd.lpwfxFormat = &waveformat;
LPDIRECTSOUNDBUFFER lpbuffer;
//创建辅助缓冲区对象
if(FAILED(hr = m_pDsd->CreateSoundBuffer(&dsbd,&lpbuffer,NULL)))
{
return PLAY_USUAL_ERROR;
}
if( FAILED( hr = lpbuffer->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &m_pDSBuffer8)))
{
return PLAY_USUAL_ERROR;
}
lpbuffer->Release();
//设置通知长度
LPDIRECTSOUNDNOTIFY8 g_pDSNotify = NULL;
DSBPOSITIONNOTIFY g_aPosNotify[AUDIO_BUF_NUM];//设置通知标志的数组
for(int i =0; i < AUDIO_BUF_NUM;i++)
{
g_aPosNotify[i].dwOffset = i* waveformat.nAvgBytesPerSec ;
g_aPosNotify[i].hEventNotify = m_event[i];
}
if(FAILED(hr = m_pDSBuffer8->QueryInterface(IID_IDirectSoundNotify,(LPVOID *) &g_pDSNotify )))
return PLAY_USUAL_ERROR;
g_pDSNotify->SetNotificationPositions(AUDIO_BUF_NUM,g_aPosNotify);
g_pDSNotify->Release();
return 0;
}
以下为传送数据
ASample = *((AVSample*)pAudioPlay->m_pAudioData);
pAudioPlay->m_pSynchronism->GetClearanceTime(ASample,lClearanceTime);
lTime = GetTickCount() - lTime;
if(lClearanceTime > 0)
{
// tools.WaitTime(lClearanceTime); //音视频同步播放
}
lTempLen = pAudioPlay->m_lReadLen - sizeof(AVSample);
pAudioPlay->m_pDSBuffer8->Lock(0,0,&(lpLockBufExcursion),&lDataLengthRemain,
&lpLockBufStart,&lDataLengthWrite,DSBLOCK_ENTIREBUFFER);
memcpy(lpLockBufExcursion,pAudioPlay->m_pAudioData + sizeof(AVSample),lTempLen);
TRACE("x=%x,Remain = %d, WriteLength = %d/n",lpLockBufExcursion,lDataLengthRemain,lTempLen);
pAudioPlay->m_pDSBuffer8->Unlock(lpLockBufExcursion,lDataLengthRemain,lpLockBufStart,lDataLengthWrite);
// pAudioPlay->m_pDSBuffer8->SetCurrentPosition(0);
pAudioPlay->m_pDSBuffer8->Play(0,0,DSBPLAY_LOOPING);
// WaitForMultipleObjects (AUDIO_BUF_NUM, pAudioPlay->m_event, FALSE, INFINITE);
数据为单声道立体声,采样率8000,16bit,每个音频包相隔10毫秒。
每次读出数据长度160字节,放入缓冲区。缓冲区64000字节。每次返回的lpLockBufExcursion,lDataLengthRemain都相同
传入的数据使用waveout时是可以播放的,应该不是数据的问题。
我保存了一秒的数据塞进去还是不行。
请问我哪里做错了。
问题解决了,我写数据的时候,总是写在开头,本想着调用Play把数据播放完了,就播放下一帧,写在缓冲区开头应该没问题。
现在我自己记录已经写入的数据总长度,在LOCK时把数据放在已经写入数据的最后。直到填满缓冲区,之后再把总长度置零。
贴出相关代码:
LONG TotalLength = 0;
。。。。。
char * buf = (char*)lpLockBufExcursion;
memcpy(buf + TotalLength,pAudioPlay->m_pAudioData + sizeof(AVSample),lTempLen);
TotalLength += lTempLen;
if(TotalLength >= 64000)
{
TotalLength = 0;
}
后记,总算是把声音放出来了,也总算稍微了解一点DirectSound了。
但像
// pAudioPlay->m_pDSBuffer8->SetCurrentPosition(0);
//WaitForMultipleObjects (AUDIO_BUF_NUM, pAudioPlay->m_event, FALSE, INFINITE);
我都把注释起来了,因为还不会用。暂时先这样吧,之后再有什么经验,我还是会在我的博客上共享的。
国内的奉献精神和学习气氛严重有问题,我在网上查了好几天的资料,发了好几个帖子,竟然没人能够给我什么有用的提示和帮助,中国的程序员很牛X吗?中国的编程水平跟外国都快差一个时代了。中国程序员写出什么给人印象深刻的东西了。
为什么中国人都要表现的那么自私,这才算中国的文化吗?
DirectX是别人的,总是去学习别人的东西怎么用,什么时候才能做出自己的东西,核心的东西。
我把我所有的编程经验都贴出来,因为我想让初学者少走弯路,能更快去研究更高端的东西。我想加速中国的软件发展,即使只有一丝的效果,我也要去做。
相关文章推荐
- 首战用DirectSound改造waveout,贴出成功播放声音的代码。
- WaveOut播放声音死锁问题原因
- waveOutOpen、waveOutWrite系统函数用法编程实现声音播放
- waveout 播放声音
- Android开发音乐播放和调节大小声音代码
- DirectX.DirectSound声音播放资料
- linux 播放声音文件程序代码
- 关于DirectSound播放声音缓存的一些认识
- 建立第一个directX程序--winform--在C#下利用DirectSound实现声音播放
- DirectSound 播放声音杂音问题.
- Android声音播放实例代码
- DirectX编程:[初级]C#中利用DirectSound播放WAV格式声音[最少只要4句话]
- DirectSound 与Waveout的区别
- 用DirectSound在窗口中播放声音,可当窗口失去焦点后却不播放的解决办法
- waveout**实现音频播放
- 推送时,播放震动声音不停止的代码
- 在 Delphi 下使用 DirectSound (7): 播放资源文件中的 Wave 数据
- 半夜听到黄家驹的声音, 忽醒,一身冷汗,哦,原来是计算机忘了关,还在播放Beyond演唱会.于是做了个较简单的自动关机程序(代码下载)
- Wave 文件(9): 使用 waveOut... 函数播放 wav 文件
- 使用wmp控件连续播放多个声音文件的代码(计算机报时程序C#)