播放产生的音频数据在声音中有噪音和周期性的咔嗒声
playing created Audio-Data has noise and periodical clicking in sound
我写了一个应用程序,它播放从硬件获得的声音(就像一个充满一定频率的窦波的环形缓冲区)。一切都很好,我可以正确地播放创建的声音,除了周期性的点击(可能在缓冲区的末尾?)和噪音。
我初始化并运行Buffer:
void Audiooutput::InitializeAudioParameters()
{
Audio_DataWritten = 0;
Audio_fragments = 4;
Audio_channels = 2;
Audio_BufferSize = 256;
Audio_Samplerate = 8000;
Audio_ResamplingFactor = 1;
Audio_Framesize = 2;
// (SND_PCM_FORMAT_S16_LE / 8);
Audio_frames = Audio_BufferSize / Audio_Framesize * Audio_fragments;
snd_pcm_uframes_t size;
err = snd_pcm_hw_params_any(pcmPlaybackHandle, hw_params);
err = snd_pcm_hw_params_set_rate_resample(pcmPlaybackHandle, hw_params, 1);
// qDebug()<<a1.sprintf(" % d t snd_pcm_hw_params_set_rate: %s",Audio_Samplerate,snd_strerror(err));
err =
snd_pcm_hw_params_set_format(pcmPlaybackHandle, hw_params,
SND_PCM_FORMAT_S16_LE);
err =
snd_pcm_hw_params_set_channels(pcmPlaybackHandle, hw_params,
Audio_channels);
err = snd_pcm_hw_params_set_rate_near(pcmPlaybackHandle, hw_params, &Audio_Samplerate, 0);
// qDebug()<<a1.sprintf(" % d t snd_pcm_hw_params_set_rate: %s",Audio_Samplerate,snd_strerror(err));
if ((err =
snd_pcm_hw_params_set_periods_near(pcmPlaybackHandle, hw_params,
&Audio_fragments, 0)) < 0) {
qDebug() << a1.sprintf("Error setting # fragments to %d: %sn",
Audio_fragments, snd_strerror(err));
} else
qDebug() << a1.sprintf("setting # fragments to %d: %sn",
Audio_fragments, snd_strerror(err));
err = snd_pcm_hw_params_get_buffer_size(hw_params, &size);
if ((err =
snd_pcm_hw_params_set_buffer_size_near(pcmPlaybackHandle,
hw_params,
&Audio_frames)) < 0) {
qDebug() << a1.
sprintf("Error setting buffer_size %d frames: %s",
Audio_frames, snd_strerror(err));
} else
qDebug() << a1.sprintf("setting Buffersize to %d --> %d: %sn",
Audio_BufferSize, Audio_frames,
snd_strerror(err));
Audio_BufferSize = Audio_frames;
if ((err = snd_pcm_hw_params(pcmPlaybackHandle, hw_params)) < 0) {
qDebug() << a1.sprintf("Error setting HW params: %s",
snd_strerror(err));
}
Q_ASSERT(err >= 0);
}
void Audiooutput::ProduceAudioOutput(int n, int mmodes, int totalMModeGates,
short *sinusValue, short *cosinusValue)
{
for (int audioSample = 0; audioSample < n;
audioSample += Audio_ResamplingFactor) {
currentposition =
(int)(m_Audio.generalPos % (Audio_BufferSize / 2));
if (currentposition == 0) {
QueueAudioBuffer();
m_Audio.currentPos = 0;
}
m_Audio.generalPos++;
AudioData[currentposition * 2] =
(short)(sinusValue[audioSample]);
AudioData[currentposition * 2 + 1] =
(short)(cosinusValue[audioSample]);
}
}
void Audiooutput::QueueAudioBuffer()
{
snd_pcm_prepare(pcmPlaybackHandle);
Audio_DataWritten +=
snd_pcm_writei(pcmPlaybackHandle, AudioData, Audio_BufferSize);
}
改变audiobuffer大小或片段也会改变点击周期。有人能帮我解决这个问题吗?我也检查了第一个和最后一个值。他们总是不同的。
操作系统:Ubuntu 11
更多细节。
接收数据的计数是动态的,它的变化取决于不同的参数。但我总是扮演一定的角色,例如128值或256或512....
//我从硬件(在Timerloop中)获得Audiodata
audiobuffersize = 256;
short *AudioData = new short[256];
int generalAudioSample = 0;
void CollectDataFromHw()
{
...
int n = 0;
n = GetData(buf1,buf2);//buf1 = new short[MAX_SHRT]
if(n > 0)
FillAudioBuffer(n,buf1,buf2)
...
}
-------------------------------------------
void FillAudioBuffer(int n, short*buf1, short*buf2)
{
for(int audioSample = 0;audioSample < n; audioSample++){
iCurrentAudioSample = (int)(generalAudioSample % (audiobuffersize/2));
if(iCurrentAudioSample == 0) {
snd_pcm_writei(pcmPlaybackHandle,AudioData,audiobuffersize );
memset(AudioData,0x00,audiobuffersize*sizeof(short));
}
generalAudioSample++;
AudioData[iCurrentAudioSample * 2] = (short)(buf1[audioSample];
AudioData[iCurrentAudioSample * 2 +1] = (short)(buf2[audioSample];
}
}
我也改变了audiobuffersize。如果我把它设置成更大的尺寸,我有一些回声额外的点击。
有什么想法吗?//-----------------------问题是
snd_pcm_prepare(pcmPlaybackHandle);
每次调用这个函数都会产生咔嗒声
无法测试源代码,但我认为你听到的高频咔哒声是声波中的不连续。您必须确保循环周期(或缓冲区大小)是波周期的倍数。
检查缓冲区的第一个值和最后一个值是否几乎相同(例如+/- 1)。它们的距离决定了不需要的咔哒声的振幅。
已解决在Buffer被填满之前,它已经被播放了好几次。
代码中愚蠢的错误。缺少parantez -> audio_buffersize/2 <--因此结果通常是if(iCurrentAudioSample == 0) true !!!!!
iCurrentAudioSample = (int)(generalAudioSample % (audio_buffersize/2));
if(iCurrentAudioSample == 0)
{
writetoaudioStream(audiobuffer);
}
相关文章:
- 如何在 C++ 中获取随机函数的周期性
- CGAL 3D 周期性德劳内三角测量与信息的问题
- 我的 RSU 如何在静脉中以周期性的时间间隔调用函数
- 写入 Linux 上的共享内存时出现周期性延迟峰值
- 周期性共生
- C 的周期性线程创建
- FFmpeg - 重新采样的音频,噪音很大
- 通过C 地图周期性迭代,程序崩溃
- 来自UDP插座的定期延迟峰值由周期性sendto()/recvFrom()延迟引起的Linux RT抢先系统的C
- 在 C++ 中以周期性的时间间隔调用函数的视觉需求
- C++在微秒范围内周期性调用函数
- 滤除噪音和速度值的变化
- 用于处理周期性事件的开源库
- 降低pcm音量后产生奇怪的噪音
- 噪音消除程序
- 在c++ /C中后台运行周期性循环
- 使用SDL2播放正弦波-噪音/划痕问题
- 如何在Qt中周期性地调用函数
- 在QAudioOutput中改变音量后的噪音
- 播放产生的音频数据在声音中有噪音和周期性的咔嗒声