私は現在、リアルタイム信号処理を実験しているので、PortAudio (from C) を試してみました。
私のコンピュータには、オンボード サウンド (Intel HD Audio) と USB オーディオ インターフェイスの 2 つのオーディオ インターフェイスがあります。どちらも通常、Linux の ALSA で正常に動作します。また、Linux の JACK で USB オーディオ インターフェイスを試してみましたが、これも完璧に動作します。
私がやること:
私のコードは、PortAudio を初期化し、ストリームを開いて開始するだけです (1 つのチャネル、paInt32サンプル形式、/defaultLowInputLatencyにdefaultLowOutputLatency変更しようとしましたが、何も改善されませんでした)。paFloat32defaultHighInputLatencydefaultHighOutputLatency
コールバックが呼び出されるたびに、sizeof(int32_t) * frameCountバイトを経由memcpyして入力から出力バッファにコピーし、 を返しますpaContinue。コールバックでは他に何もしません。メモリの割り当ても、システム コールも、ブロックできるものもありません。読み取ったものを出力するだけです。コードは非常に単純ですが、それでも実行できません。
入力から出力バッファに型の要素をmemcpyコピーするループに置き換えても、何も変わりませんでした。frameCountint32_t
私が試したこと:
次のシナリオは、PortAudio で試行されました。
- USB オーディオ インターフェイス経由の入出力、PortAudio のコールバック メカニズム、ALSA バックエンド。
- USB オーディオ インターフェイス経由の入出力、1024 サンプル バッファ サイズ、ALSA バックエンドの PortAudio での I/O のブロック。
- USB オーディオ インターフェイス経由の入力、オンボード サウンド経由の出力、PortAudio のコールバック メカニズム、ALSA バックエンド。
- USB オーディオ インターフェイス経由の入力、オンボード サウンド経由の出力、1024 サンプル バッファー サイズの PortAudio での I/O のブロック、ALSA バックエンド。
- USB オーディオ インターフェイス、PortAudio のコールバック メカニズム、JACK バックエンドを介した入出力。
- USB オーディオ インターフェイス経由の入出力、1024 サンプル バッファ サイズ、JACK バックエンドの PortAudio での I/O のブロック。
私が遭遇した問題:
結果は以下の通り。(数字は上記のシナリオを表します。)
- デバイスからの出力がありません。
- デバイスからの出力が不安定 (中断)。常に多くのバッファ アンダーランが発生します。
- デバイスからの出力がありません。
- デバイスからの出力が実現不可能です。うまくいくこともあれば、うまくいかないこともあります。(何も変更せずに、実行可能ファイルを複数回実行するだけです。) 動作する場合、遅延は最初は低くなりますが、時間の経過とともに増加し、非常に顕著になります。
- デバイスからの出力がありません。
- デバイスからの出力がありません。
各試行の間に、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_Initialize、Pa_OpenStream、Pa_StartStream、Pa_StopStream、Pa_CloseStream、Pa_Terminateこの順序で) は、すべて を返しpaNoErrorます。
PortAudio に付属するpaex_read_write_wire.c(ブロッキング I/O) サンプルは、通常、デバイスにアクセスできますが、多くのアンダーランも発生します (私のテスト ケース 2 のように)。
どちらの場合でも、興味深いものは何も表示されませんdmesg。(ALSAにはカーネルレベルのコンポーネントがあるため、確認しました。)
私の質問:
ここで何が問題なのか、どうすれば修正できるのか、誰でも知っていますか? または、少なくとも、どうすればもう少し絞り込むことができますか?