簡體   English   中英

播放創建的音頻數據有噪音和周期性的聲音點擊

[英]playing created Audio-Data has noise and periodical clicking in sound

我寫了一個應用程序,它從硬件中播放聲音(就像一個充滿特定頻率的正弦波的環形緩沖區)。 一切正常,我可以正確播放創建的聲音,除了定期點擊(可能在緩沖區的末尾?)和噪音。

我初始化並運行緩沖區:

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);
}

更改音頻緩沖區大小或片段也會更改單擊期間。 任何人都可以幫我解決這個問題嗎? 我還檢查了第一個和最后一個值。 你總是與眾不同。

操作系統:Ubuntu 11

更多詳情。

接收數據的計數是動態的,並且變化取決於不同的參數。 但我總是玩某個部分,例如128個值或256或512 ....

//我從硬件中獲取Audiodata(在Timerloop中)

    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。 如果我將它設置為更大的尺寸,我會點擊一些額外的Echo。

任何的想法 ? // - - - - - - - - - - - - 問題是

snd_pcm_prepare(pcmPlaybackHandle);

每次調用此功能都會產生聲音點擊!

無法測試源代碼,但我認為您聽到的高頻點擊是聲波中的不連續性。 您必須確保循環周期(或緩沖區大小)是波周期的倍數。

檢查緩沖區的第一個和最后一個值是否幾乎相同(例如+/- 1)。 它們的距離決定了不需要的咔嗒聲的幅度

已解決的緩沖區在填充數據之前已經播放了好幾次。

代碼中的愚蠢錯誤。輸入一個parantez - > audio_buffersize / 2 < - - 因此結果很頻繁,如果(iCurrentAudioSample == 0)真的!!!!!

iCurrentAudioSample = (int)(generalAudioSample % (audio_buffersize/2));
if(iCurrentAudioSample == 0)
{
 writetoaudioStream(audiobuffer);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM