直接上代码
网上都是播放本地文件的,对于播放实时语音流的文章比较少。
先记录一下,之后有空了整理成一个小demo再好好写一下
if (m_hHandle == INVALID_PLAYER_HANDLE)//先进行初始化,只做一次。
{
wfx.wFormatTag = WAVE_FORMAT_PCM;//设置波形声音的格式
wfx.nChannels = 1;//设置音频文件的通道数量
wfx.wBitsPerSample = 16;
wfx.nSamplesPerSec = 8000;//设置每个声道播放和记录时的样本频率
wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;//以字节为单位设置块对齐
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;//设置请求的平均数据传输率,单位byte/s。这个值对于创建缓冲大小是很有用的
wfx.cbSize = 0;//额外信息的大小
waveOutOpen(&hwo, WAVE_MAPPER, &wfx, NULL, 0L, CALLBACK_NULL);//打开一个给定的波形音频输出装置来进行声音播放,方式为回调函数方式。如果是对话框程序,可以将第五个参数改为(DWORD)this,操作跟本Demo程序相似
m_hHandle = 1;
}
r++;
//播放区1和播放区2轮流着来
if (r % 2 == 1)
{
wh1.dwLoops = 0L;//播放区一
wh1.lpData = new char[pcmLenth];
wh1.dwBufferLength = pcmLenth;
//fread(wh1.lpData, 1, DATASIZE, pcmfile);
memcpy(wh1.lpData, pcm, pcmLenth);
wh1.dwFlags = 0L;
if (r != 3)
{
waveOutPrepareHeader(hwo, &wh1, sizeof(WAVEHDR));//准备一个波形数据块用于播放
waveOutWrite(hwo, &wh1, sizeof(WAVEHDR));//在音频媒体中播放第二个参数指定的数据,也相当于开启一个播放区的意思
//waveOutUnprepareHeader(hwo, &wh2, sizeof(WAVEHDR));
while (waveOutUnprepareHeader(hwo, &wh2, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING)
{
continue;
}
delete wh2.lpData;
wh2.lpData = NULL;
delete pcm;
pcm = NULL;
}
else
{
waveOutPrepareHeader(hwo, &wh1, sizeof(WAVEHDR));//准备一个波形数据块用于播放
waveOutWrite(hwo, &wh1, sizeof(WAVEHDR));//在音频媒体中播放第二个参数指定的数据,也相当于开启一个播放区的意思
}
}
else
{
wh2.dwLoops = 0L;//播放区二
wh2.lpData = new char[pcmLenth];
wh2.dwBufferLength = pcmLenth;
//fread(wh1.lpData, 1, DATASIZE, pcmfile);
memcpy(wh2.lpData, pcm, pcmLenth);
wh2.dwFlags = 0L;
waveOutPrepareHeader(hwo, &wh2, sizeof(WAVEHDR));//准备一个波形数据块用于播放
waveOutWrite(hwo, &wh2, sizeof(WAVEHDR));//在音频媒体中播放第二个参数指定的数据,也相当于开启一个播放区的意思
//waveOutUnprepareHeader(hwo, &wh1, sizeof(WAVEHDR));
while (waveOutUnprepareHeader(hwo, &wh1, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING)
{
continue;
}
delete wh1.lpData;
wh1.lpData = NULL;
delete pcm;
pcm = NULL;
}