4

私は現在、リアルタイム信号処理を実験しているので、PortAudio (from C) を試してみました。

私のコンピュータには、オンボード サウンド (Intel HD Audio) と USB オーディオ インターフェイスの 2 つのオーディオ インターフェイスがあります。どちらも通常、Linux の ALSA で正常に動作します。また、Linux の JACK で USB オーディオ インターフェイスを試してみましたが、これも完璧に動作します。

私がやること:

私のコードは、PortAudio を初期化し、ストリームを開いて開始するだけです (1 つのチャネル、paInt32サンプル形式、/defaultLowInputLatencydefaultLowOutputLatency変更しようとしましたが、何も改善されませんでした)。paFloat32defaultHighInputLatencydefaultHighOutputLatency

コールバックが呼び出されるたびに、sizeof(int32_t) * frameCountバイトを経由memcpyして入力から出力バッファにコピーし、 を返しますpaContinue。コールバックでは他に何もしません。メモリの割り当ても、システム コールも、ブロックできるものもありません。読み取ったものを出力するだけです。コードは非常に単純ですが、それでも実行できません。

入力から出力バッファに型の要素をmemcpyコピーするループに置き換えても、何も変わりませんでした。frameCountint32_t

私が試したこと:

次のシナリオは、PortAudio で試行されました。

  1. USB オーディオ インターフェイス経由の入出力、PortAudio のコールバック メカニズム、ALSA バックエンド。
  2. USB オーディオ インターフェイス経由の入出力、1024 サンプル バッファ サイズ、ALSA バックエンドの PortAudio での I/O のブロック。
  3. USB オーディオ インターフェイス経由の入力、オンボード サウンド経由の出力、PortAudio のコールバック メカニズム、ALSA バックエンド。
  4. USB オーディオ インターフェイス経由の入力、オンボード サウンド経由の出力、1024 サンプル バッファー サイズの PortAudio での I/O のブロック、ALSA バックエンド。
  5. USB オーディオ インターフェイス、PortAudio のコールバック メカニズム、JACK バックエンドを介した入出力。
  6. USB オーディオ インターフェイス経由の入出力、1024 サンプル バッファ サイズ、JACK バックエンドの PortAudio での I/O のブロック。

私が遭遇した問題:

結果は以下の通り。(数字は上記のシナリオを表します。)

  1. デバイスからの出力がありません。
  2. デバイスからの出力が不安定 (中断)。常に多くのバッファ アンダーランが発生します。
  3. デバイスからの出力がありません。
  4. デバイスからの出力が実現不可能です。うまくいくこともあれば、うまくいかないこともあります。(何も変更せずに、実行可能ファイルを複数回実行するだけです。) 動作する場合、遅延は最初は低くなりますが、時間の経過とともに増加し、非常に顕著になります。
  5. デバイスからの出力がありません。
  6. デバイスからの出力がありません。

各試行の間に、ALSA がまだ応答しているかどうかがテストされ (完全に「ロックアップ」され、アプリケーションがサウンドを出力できなくなる場合がありました)、ALSA が「ロックアップ」した場合に備えてシステムを再起動し、テストを続けました。

詳細は、問題を追跡するときに役立つ場合があります。

出力がまったくないシナリオで、ALSA をバックエンドとして使用すると、次のエラー メッセージが表示されます。

Expression 'err' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3350
Expression 'ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3876
Expression 'PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 4248

JACK をバックエンドとして使用すると、次のエラー メッセージが表示されます。

Cannot lock down 42435354 byte memory area (Cannot allocate memory)

さらに、どの方法を使用しても、常にこれらの警告が表示されます。

ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map

ALSA を使用していると、アンダーランに関する苦情も 1 つか 2 つありました。

ALSA lib pcm.c:7905:(snd_pcm_recover) underrun occurred

私が呼び出した PortAudio 関数 ( Pa_InitializePa_OpenStreamPa_StartStreamPa_StopStreamPa_CloseStreamPa_Terminateこの順序で) は、すべて を返しpaNoErrorます。

PortAudio に付属するpaex_read_write_wire.c(ブロッキング I/O) サンプルは、通常、デバイスにアクセスできますが、多くのアンダーランも発生します (私のテスト ケース 2 のように)。

どちらの場合でも、興味深いものは何も表示されませんdmesg。(ALSAにはカーネルレベルのコンポーネントがあるため、確認しました。)

私の質問:

ここで何が問題なのか、どうすれば修正できるのか、誰でも知っていますか? または、少なくとも、どうすればもう少し絞り込むことができますか?

4

2 に答える 2

1

サンプルのブロックを 1 つだけ書き込むと、再生デバイスは、次のブロックを書き込もうとしているときにサンプルを使い果たします。

読み取り/書き込みループを開始する前に、再生デバイスのバッファをゼロ サンプルで埋める必要があります。

于 2016-02-10T09:25:29.517 に答える