wave播放音频流使用双缓冲无效果

xzyong 2012-02-21 09:36:21
问题:使用的双缓冲无效果,没有起到作用,听的声音还是一卡一卡的,请大虾们看看我写的哪出错了?

WAVEFORMATEX waveformat = {WAVE_FORMAT_PCM, (WORD)1, 8000, 16000, (WORD)2, (WORD)16, 0}; //设定波形音频的格式

//打开音频设备
DWORD rval = waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveformat, (DWORD_PTR)WaveCallback, (DWORD)this, CALLBACK_FUNCTION);

waveHdr1.dwBufferLength = SIZEPERFRAME * FRAMEPERPACKET * PACKETPERPLAY;
waveHdr1.lpData = pData[0];
waveHdr1.dwFlags = WHDR_DONE;
waveHdr1.dwLoops = 0;
waveHdr1.lpNext = NULL;

waveHdr2.dwBufferLength = SIZEPERFRAME * FRAMEPERPACKET * PACKETPERPLAY;
waveHdr2.lpData = pData[1];
waveHdr2.dwFlags = WHDR_DONE;
waveHdr2.dwLoops = 0;
waveHdr2.lpNext = NULL;

//写入wave设备
waveOutPrepareHeader(hWaveOut, &waveHdr1, sizeof(WAVEHDR));
waveOutPrepareHeader(hWaveOut, &waveHdr2, sizeof(WAVEHDR));

waveOutWrite(hWaveOut, &waveHdr1, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &waveHdr2, sizeof(WAVEHDR));

//回调函数
void CALLBACK CAudioManger::WaveCallback(HWAVEOUT hWave, UINT uMsg, DWORD dwUser,DWORD dw1, DWORD dw2)
{
CAudioManger *pWavePlay = (CAudioManger*)dwUser;

if(NULL != pWavePlay && uMsg == WOM_DONE)
{
LPWAVEHDR pWaveHeader = (LPWAVEHDR)dw1;
waveOutUnprepareHeader( hWave, pWaveHeader, sizeof(WAVEHDR) );

while (1)
{
if (pWavePlay->pPlay->pNext->nNum >= PACKETPERPLAY-1)
{
pWavePlay->pPlay = pWavePlay->pPlay->pNext;
break;
}
}
pWaveHeader->lpData = pWavePlay->pPlay->pBuffer;
pWavePlay->pPlay->nNum = 0;
pWaveHeader->dwBufferLength = SIZEPERFRAME * FRAMEPERPACKET * PACKETPERPLAY;
pWaveHeader->lpNext = NULL;
waveOutPrepareHeader(hWave, pWaveHeader, sizeof(WAVEHDR));
waveOutWrite(hWave, pWaveHeader, sizeof(WAVEHDR) );

}

return ;
}
...全文
231 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
猿创日记 2012-02-23
  • 打赏
  • 举报
回复
这样啊。那你的pBuffer里面获取到的数据大小你确定是SIZEPERFRAME * FRAMEPERPACKET * PACKETPERPLAY嘛?
xzyong 2012-02-23
  • 打赏
  • 举报
回复
不会的,我试过把buffer调大,结果断音的间隔就长,我猜测问题就出在于使用的双缓冲没有成功
猿创日记 2012-02-23
  • 打赏
  • 举报
回复
有没有尝试把BUFFER调大一点?有可能太小导致这边播完那边还没放好,可以考虑用3个BUFFER。
xzyong 2012-02-23
  • 打赏
  • 举报
回复
to:zq282502532
WAVEFORMATEX格式是一样的,我是捕获麦克风的不是读取文件,设置的格式如下
WAVEFORMATEX waveformat;
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.nChannels = (WORD)1;
waveformat.nSamplesPerSec = 8000;
waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec*2;
waveformat.wBitsPerSample = (WORD)16;
waveformat.nBlockAlign = (WORD)2;

while不会死循环的,这里只是多增加一个判断而已

to:liuqian4243
是在局域网,每次进入回调都能可以填充数据
Ny-6000 2012-02-23
  • 打赏
  • 举报
回复
网速不好,怎么缓冲也没用.
猿创日记 2012-02-23
  • 打赏
  • 举报
回复
额、这里竟然是.NET区。。
猿创日记 2012-02-23
  • 打赏
  • 举报
回复
需要播放的文件格式和你设置的WAVEFORMATEX是一样的吗?最好根据文件读取格式,然后设置WAVEFORMATEX。
回调函数中while循环没怎么看懂。会不会造成死循环啊?
xzyong 2012-02-23
  • 打赏
  • 举报
回复
感谢zq282502532
已经解决了,确实是因为播放文件大小引起的问题

能不能再请教这个问题:
http://topic.csdn.net/u/20120223/17/2d117fea-c116-42e2-b447-3da2bcb44e97.html
猿创日记 2012-02-23
  • 打赏
  • 举报
回复
你可以先播放文件,等把类写好了之后然后再移植到音频捕捉上。
xzyong 2012-02-23
  • 打赏
  • 举报
回复
我捕捉音频流的设置的数据
IAMStreamConfig *pConfig=NULL;
m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Audio,m_pBF,IID_IAMStreamConfig, (void**)&pConfig);
AUDIO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE * pamtPreviewStream;
pConfig->GetStreamCaps(iDeviceID, &pamtPreviewStream, (BYTE*)&scc);
WAVEFORMATEX *pWF = (WAVEFORMATEX *) pamtPreviewStream->pbFormat;
pWF->wFormatTag = WAVE_FORMAT_PCM;
pWF->nChannels = (WORD)1;
pWF->nSamplesPerSec = 8000;
pWF->nAvgBytesPerSec = pWF->nSamplesPerSec*2;
pWF->wBitsPerSample = (WORD)16;
pWF->nBlockAlign = (WORD)2;
hr = pConfig->SetFormat(pamtPreviewStream) ;
pConfig->Release();
猿创日记 2012-02-23
  • 打赏
  • 举报
回复
额、还是你自己调试吧。不太清楚了。
弄清双缓冲回调的本质就好。
xzyong 2012-02-23
  • 打赏
  • 举报
回复
是的啊,我每次发送的数据是SIZEPERFRAME * FRAMEPERPACKET这么大,然后把多个包连接起来成一个流进行播放的,包的个数是PACKETPERPLAY

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧