7

非インターリーブモードでシングルチャンネルオーディオを再生しています。スピーカーにオーディオデータを書き込んでいるときにアンダーランが発生しています:ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred

これが私が書く方法です:

    printf("%d",snd_pcm_avail (spkhandle));  
    ret = snd_pcm_writen(spkhandle, pSpeakerBuf , framesIn18Millisec);
    if(ret < 0)
    {
        snd_pcm_recover(spkhandle, ret, 0);
    }

ALSAの実行を防ぐためのさまざまな方法/パラメーター構成は何ですか?

(私はLinux 3.0、ARMを使用しています)

編集:これはsnd_pcm_avail()APIを使用したバッファー測定です

      snd_pcm_avail = 2304      << snd_pcm_writen call 1 success
      snd_pcm_avail = 2160      << snd_pcm_writen call 2 success
      snd_pcm_avail = 2016      << snd_pcm_writen call 3 success
      snd_pcm_writen error -32 Broken pipe  << snd_pcm_writen call 4 failure
      ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred  << And displays this message

Markoが要求した出力は次のとおりです。

snd_output_t* out;
....
// Do alsa parameters init .... 
....
snd_output_stdio_attach(&out, stderr, 0);
snd_pcm_dump_sw_setup(spkhandle, out);

  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 144
  period_event : 0
  start_threshold  : 288
  stop_threshold   : 2304
  silence_threshold: 0
  silence_size : 0
  boundary     : 1207959552
4

2 に答える 2

6

このコードはタイトなループで実行され、でブロックすることを目的としていsnd_pcm_writen()ます。サンプルレートは指定されていません。数字はすべてうまく分割されているので、48kHzと仮定します。

私がここで行っていると思うことは次のとおりです。

  • snd_pcm_write()提供されたすべてのフレームを書き込むことを保証するものではありません(戻り値はエラー状態についてのみチェックされます)。それのロギングから判断すると、実際にはそれぞれのフレームをsnd_pcm_avail()消費していavail_minます。144これは3msのオーディオです。
  • この時点でオーディオが実行されていないと仮定すると、2回の書き込みの後、バッファ内のフレーム数はサンプルstart_thresholdで-に等しくなります。288音声出力開始
  • ブロックするための呼び出し、そして私はそれがオーディオ出力ハードウェアと同期しなければならず、またブロックするかもしれないことprintf()を覚えているようです。snd_pcm_avail()再生より6ミリ秒進んでいるため、3回目の呼び出し時にバッファが枯渇している可能性があります。snd_pcm_writen()

printf()要約すると、この時点で電話をかけるべきではありません。おそらくsnd_pcm_writen()、のすべてのフレームを消費していないという事実を補う必要があります。pSpeakerBuf

于 2013-01-30T15:30:28.793 に答える
1

これはバッファアンダーランです。〜/ .asoundrcファイルで明示的に言及することで、バッファサイズを増やしてみることができますか?

于 2013-01-30T10:33:08.330 に答える