PulseaudioとSoxによる低遅延リアルタイムサウンドフィルタリング

PulseaudioとSoxによる低遅延リアルタイムサウンドフィルタリング

オーディオ実験にはLinuxを使用するので、PulseAudioとALSAを使用します。一貫した低レイテンシを達成できません。

コンピュータを使用してスペクトルの同じ部分にノイズを生成することによって、不要な周囲ノイズ(サイレンやバックアップアラームなど)を隠すというアイデアがあります。

非常に簡単な方法は、入力サンプルに「ピンクノイズ」(1 / f)または「ブラウンノイズ」(1 / f ^ 2)などのいくつかの累乗ノイズを掛け、その結果をスピーカーで再生することです。私はこれが周波数領域の畳み込みに相当すると思うので、周波数スパイクをより広く、より迷惑にする効果がなければなりません。

私はPulseAudioの熱心なファンではありませんが、Linuxの標準アプリケーションレベルのオーディオフレームワークであり、可変速リサンプリングが可能な最も簡単なツールのようです。リサンプリングは、複数のデバイス(この場合はマイクとスピーカー)を使用するときのクロック歪みを修正するために使用されます。遅延時間を短縮するためのいくつかの提案があります。PulseAudioの場合はこちらそしてUnixパイプの場合はこちら

必要なフィルタリング効果を達成するSoxコマンドがありますが、PulseAudioの入力と出力が予測可能なレイテンシを持つようにする方法がわかりません。以下の簡略化された(Zsh)パイプラインコマンドはサンプルをマイクからスピーカーに直接送信しますが、時々それを実行すると主観的な遅延時間がほとんど無視されることがあり、時には遅延時間が500ミリ秒に近づくことがあります(例:指をスピーカーの前でパチパチする)場合)。マイク)、一部の実行ではすぐに聞こえ、他の実行では毎秒2回鳴ります。)これらの違いはパイプラインを再起動したときに発生し、PulseAudioサーバーを再起動する必要はありません。

PFMT=(--rate 48000 --format s16le --channels 1)
pacat -r --latency-msec=1 $PFMT | pacat --latency-msec=1 $PFMT

stdbuf -o64 -i64Unixパイプバッファが原因で発生した場合に備えて、各項目の前に置いてみましたが、pacat動作が変わらないようです。

常にパイプラインをシャットダウンして再開し、パイプラインが低い遅延時間で始まるまで繰り返し続けることができますが、毎回動作するソリューションがあればよいでしょう。 PulseAudio ログでは、高レイテンシ実行と低レイテンシ実行の違いを把握できません。

短い待ち時間で実行(最初の行は仮想「モニタ」ソース):

$ (pactl list sources; pactl list sinks) | grep Latency
Latency: 0 usec, configured 1999818 usec
Latency: 4193 usec, configured 66000 usec
Latency: 2861 usec, configured 15012 usec

高い待ち時間で実行:

$ (pactl list sources; pactl list sinks) | grep Latency
Latency: 0 usec, configured 1999818 usec
Latency: 505 usec, configured 66000 usec
Latency: 3305 usec, configured 15012 usec

以下は、インターネット提案からコピーしたPulseAudio設定の関連行です。そのうちどれも効果的かどうかはわかりません。

# .config/pulse/daemon.conf
;; https://forums.linuxmint.com/viewtopic.php?t=44862
default-fragments = 2
default-fragment-size-msec = 5

high-priority = yes
rlimit-nice = 31
nice-level = -11
realtime-scheduling = yes
rlimit-rtprio = 9
realtime-priority = 9

私は数年前のPulseAudioバージョンを実行していますので、修正された既知のバグを見つけたら教えてください。

以下は、私が実行したいフルノイズ乗算コマンド(Zshの再)です。このコマンドは、上記の単純なパイプラインと同様に、予測不能なレイテンシの問題を経験します。これは、現在経験している待ち時間の問題とは実際には関係ありませんが、これがPulseAudioを使用してソースからシンクにmodule-loopbackサンプルをルーティングするのではない理由です。

SFMT=(-e signed -r 48000 -b 16 -c 1 -t raw)
PFMT=(--rate 48000 --format s16le --channels 1)
STDB=(stdbuf -o64 -i64)
sox -n $SFMT - synth brownnoise vol 0.01 | sox --buffer 64 -T $SFMT - $SFMT <($STDB pacat -r --latency-msec=1 $PFMT) $SFMT >($STDB pacat --latency-msec=1 $PFMT) vol 100

ありがとうございます。


2023年12月5日に更新:

私のオーディオ設定とALSAに関するいくつかの質問にコメントします。入力はUSBマイク「JMTek、LLC. USB PnPオーディオデバイス」で、出力はAMDオーディオコントローラを介してマイノートパソコンに内蔵された3.5mmオーディオジャックです。

ALSA(aplay、arecord)を使用すると、より一貫して低レイテンシを達成するようですが、-Bを使用してもバッファサイズが50マイクロ秒に短縮されます。さらに、パルスとは異なり、ALSAの明らかな待ち時間は時々数分で徐々に増加します(例えば、10msから100msへ)。 Pulse と同様に、ALSA には、ある呼び出しから次の呼び出しまでのランダムな待ち時間の変化の問題があります。時には<10ms、時には>400msを得ます。しかし、前述したように、ALSAの待ち時間はより一般的なようです。 ALSAの実験に使用したシェルコード。チャンネルの速度や数を変更するために、「プラグ」PCMを使用せずにデバイスから直接データを読み取るか、デバイスにデータを書き込んでいることに注意してください。

#!/bin/zsh
SFMT=(-e signed -r 48000 -b 16 -c 1 -t raw)
AFMT=(-r 48000 -f S16_LE -c 1)
AOPT=(-B 50 $AFMT)
STDB=(stdbuf -o64 -i64)
sox -n $SFMT - synth brownnoise vol 0.01 | sox --buffer 64 -T $SFMT - $SFMT <($STDB arecord $AOPT -Dhw:2) $SFMT -c 2 >($STDB aplay $AOPT -c 2 -Dhw:1) vol 300

上記ALSA実験の出力例:

Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
underrun!!! (at least 18304.245 ms long)
underrun!!! (at least 870598.858 ms long)
underrun!!! (at least 241414.917 ms long)
underrun!!! (at least 1.451 ms long)
underrun!!! (at least 12.687 ms long)
overrun!!! (at least 4.934 ms long)
underrun!!! (at least 10.253 ms long)
underrun!!! (at least 11.326 ms long)
overrun!!! (at least 0.549 ms long)
...

ベストアンサー1

おすすめ記事