如何使用waveOutWrite()使音频播放流畅
how to make audio playback smooth using waveOutWrite()
我在尝试使用waveOutWrite()实现平滑音频播放时遇到了一个问题。我的数据包括许多从相机获得的adpcmdata块,在解码每个adpcm块后,我使用waveOutWrite()播放它。第一个区块打得很成功(至少我能听到),但当我打下一个区块时,我遇到了问题,这些区块之间存在差距。我试着在使用waveOutWrite()后调用sleep(),但不好。有人能告诉我在这种情况下如何变得平滑吗?我播放音频的方式有问题吗?
for (i = 0, i < MaxBlockData, i++)
BYTE * pcmBuff = new BYTE[length*8];
memset(pcmBuff, 0, length*8);
G726 g726;
int pcmDataSize = 0;
g726.SetRate(g726.Rate32kBits);
g726.SetLaw(g726.PCM16);
pcmDataSize = g726.Decode(pcmBuff, adpcmData[i], 0, length*8); /decode adcmData PCM 16
if(pcmDataSize > 0)
{
int sampleRate = 8000;
CHAR* waveIn = new CHAR[pcmDataSize];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;
result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);
if(result != MMSYSERR_NOERROR)
{
char fault[256];
waveInGetErrorTextA(result, fault, 256);
MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
return;
}
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = pcmDataSize;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
memcpy(WaveInHdr.lpData, pcmBuff, pcmDataSize);
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
{
MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
}
waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr));
Sleep((pcmDataSize/sampleRate ) * 1000); //Sleep for as long as there was recorded
waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR));
waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
waveInClose(hWaveIn);
waveOutClose(hWaveOut);
WaveInHdr.lpData = NULL;
delete []waveIn;
}
}
谢谢你阅读我的问题。
我不会这样工作的
当您播放第一个样本时,您不能在下一个样本的时间内睡觉,相反,您应该使用双缓冲或多缓冲以及回调机制
总体协议如下:
1) 从相机或其他位置获取第一个块
2) 从相机或其他位置获取第二块
3) 在没有任何等待的情况下写入第一块然后写入第二块
然后创建等待来自回调的信号的循环,并在接收到信号时写入下一个捕获的块。
要使用waveOut*系列平稳播放音频,请打开设备,分配缓冲区并不断向设备发送缓冲区,以保留待播放的积压数据。在代码中使用Sleep
的情况下,应该准备新数据并将其写入设备,同时检查播放的缓冲区(设置WHDR_DONE
标志表示驱动程序不再使用缓冲区,应用程序将接收到缓冲区)。
相关文章:
- C++新手,想知道如何使用VS code 2019播放音频文件
- 如何以编程方式将音频从任何录制设备路由到任何播放设备
- 大声音频无法播放
- Qt C++ 创建方形音频音调波.播放并保存它
- C++从字节数组实时播放音频
- 无法在带有 gst-launch-1.0 的 Qemu 的 armv7 上播放 wav 音频
- 如何使用Microsoft::D irectX::AudioVideoPlayback 来播放音频
- 如何将 cdparanoia 读取的 CD 音频数据移交给 ALSA 播放器?
- 如何在Raspberry Pi上使用C /libao/alsa通过USB声卡播放音频
- QT 创建器:程序启动时音量滑块仍播放音频
- 如何播放AMR音频,QMediaPlayer不支持
- 使用音频设备播放WebRTC C++应用程序的音频流
- 是否可以使用带有random_shuffle的矢量随机播放音频文件
- 在 openGL 中播放音频而不冻结绘制循环
- 将超能力高级音频播放器同步到绝对位置
- Qt - 如何设置音频播放从缓冲区的开头开始
- Qt和音频播放
- 如何使用waveOutWrite()使音频播放流畅
- 如何获得Windows音频播放的当前采样率
- Qt声子音频播放器中的循环问题