I am writing an application that reproduces sound received from hardware (for example, a ring buffer filled with a sine wave with a certain frequency). Everything works fine, and I can correctly reproduce the sound created, except for periodically pressing (maybe at the end of the buffer?) And noise.
I initialize and run the 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: %s\n", Audio_fragments, snd_strerror(err)); } else qDebug() << a1.sprintf("setting # fragments to %d: %s\n", 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: %s\n", 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); }
Changing the size or fragments of the audio buffer also changes the period of pressing. Can someone help me with this problem? I also checked the first and last values. Yours is always the difference.
OS: Ubuntu 11
in details.
the amount of data received is dynamic, and the changes depend on different parameters. But I always play a role, for example. 128 values ββor 256 or 512 ....
// I get Audiodata from the hardware (in Timerloop)
audiobuffersize = 256; short *AudioData = new short[256]; int generalAudioSample = 0; void CollectDataFromHw() { ... int n = 0; n = GetData(buf1,buf2);
I also changed the audio footwear. If I set it to a larger size, I have an extra Echo for clicks.
any idea? // ----------------------- problem
snd_pcm_prepare(pcmPlaybackHandle);
each call to this function causes a click on the sound!