Chienomi

PulseEffectsでLinuxの音声環境を整える

Live With Linux::tips

本記事はPulseAudio/PulseEffectsを用いてYouTube動画再生やWeb会議、配信などにおける音声を整えることを題材としたものである。

特にコンプレッサーの話をするが、音楽制作の話ではなく、Linuxにおける日常利用にフォーカスしたものとなる。

PulseEffectsはEasyEffectsとなり、対象音声プラットフォームをPulseAudioを完全にドロップしてPipeWireに絞ったものとなっている。 依然としてPulseAudioを使いたい人に向けてPulseEffects Legacyが存在している。 本記事ではPipeWireを使うEasyEffects、PulseAudioのみのPulseEffects Legacyの両方を解説する。

PipeWireは新しいマルチメディアフレームワークで、動画・音声の低レベルAPIを提供すると共に、映像処理・音声処理の中間レイヤーとして機能する。 特にWaylandでデスクトップキャプチャをする上でよく話題に出る。

PipeWireは従来より扱いやすい、優れたAPIであるため、音声ソフトウェアの開発者はPulseAudioよりもPipeWireを好む傾向にある。 これを持ってPipeWireはPulseAudioを置き換えるとする言説も多いが、これは適切とは考えがたい。 なぜならば、PulseAudioが優れているのは、別にPulseAudioのAPIを使うことを前提としたことではなく、むしろ従来のアプリケーション(特にALSAを使うアプリケーション)を柔軟にコントロールできるという点が魅力的であった。特にボリュームコントロールやオーディオルーティングの強力さは一度体験すればなくてはならないものである。 また、様々なsink/sourceをコマンドで自在に扱えるというのも魅力的だ。

PipeWireもその機能としてはPulseAudioと同等のことを実現可能であるはずで、そうした機能を実現するソフトウェア群が追加されればPipeWireがPulseAudioを置き換えるようなことはあるだろうが、現状PipeWireはプログラマのものであってユーザーのものではないため、PipeWireを使うことによるユーザー利益はかなり少ない。 PipeWireのPulseAudio互換機能を使うことで使い勝手の悪さはある程度解消されるが、PipeWireなしにPulseAudioを使うことよりも優れた結果が得られるかどうかはかなり疑問である。

PipeWire on Manjaro Linux

Manjaro Linuxにおいては、PipeWire本体は導入されているが、グローバルにPipeWireを使うようにはなっていない。 一方、EasyEffectsはcommunityパッケージである一方(PulseAudioそのものはextraなのに!)、PulseEffectsはAURになる。

この点を見て、PulseEffectsを使うよりも、EasyEffectsを使うためにPipeWireを使うほうが綺麗だと考える人もいるだろう。

Manjaro LinuxでEasyEffectsを使う場合、manjaro-pipewireパッケージをインストールする。 この際、pulseaudio-jackなどのパッケージをインストールしていると依存関係の解消に失敗するので、原因になったパッケージを先に消しておく必要がある。 manjaro-pipewiremanjaro-pulseと排他関係にある。

manjaro-pipewireを導入した場合、PulseAudioの接続を確立するには再起動が必要である。

そしてesayeffectsを入れれば、完成だ。

実際に使ってみたところ、マイクミュートの動作がおかしい、入力信号がPulseAudioから見えないことがある、といった問題があった。

PulseAudioに戻す場合、manjaro-pulseをインストールすれば良いのだが、pulseaudio-bluetoothが引っかかってしまうため、pacman -S manjaro-pulse pulseaudio-bluetoothとする必要がある。

また、pipewire-alsaが残ってしまうが、これを残しているとALSAアプリケーションがPulseAudioではなくPipeWireを使うケースがあるため、これを削除する。

PulseEffects in Manjaro Linux

AURのpulseeffects-legacyまたはpulseeffects-legacy-gitを導入する。

インストール後、提案パッケージはすべて入れないと、PulseEffects上で設定しても機能しないものが出る。

EasyEffectsの使い方

デバイスの選択

PipeWireの場合、PulseAudio Volume Controlを用いてうまく接続の切り替えができなくなるため、ルーティングもEasyEffectsで行うように考える必要がある。

PipeWireタブで入力デバイスと出力デバイスをそれぞれ選択する。 これは、入力デバイスから入った音が入力として処理され、出力として処理した音が出力デバイスから出ていくという意味である。

出力と入力はタブで分けられ、さらにプレイヤー/レコーダーとプラグインタブに分かれている。

プラグインタブで使いたいものを挿していき、順番を並び替え、設定を行う。 任意に追加できるように見えるが、同じものを複数使うことはできない。

入力デバイスとして設定したデバイスから入った音はEasyEffectsによって処理される。

一方、アプリケーション再生音はすべてEasyEffectsで拾って指定デバイスに出力する前提で考えられている。 エフェクトに通したくない場合はプレイヤータブでアプリケーションをオフにする。

PulseEffectsの使い方

動作画面

PulseEffectsはPulseAudio sinkになるため、PulseAudio Volume Control (pavucontrol)によって通す通さないをコントロールできる。

左上のスピーカー/マイクのマークで出力フィルタと入力フィルタを切り替える。 使用したいフィルタにチェックを入れ設定を行う。必要に応じて順序も入れ替えるが、通常はこの順序のまま使う。

フィルタリストの先頭にあるApplicationsをクリックするとApplicationにフィルタを適用するかどうかの選択ができるが、使わない場合はPulseEffectsを通さないようにPulseAudioでルーティングしたほうが確実。 毎回拾われてしまうので、オーディオプレイヤーアプリなど拾ってほしくないものはブロックリストに入れると楽。

入出力デバイスは設定のPulseAudioタブにある。このルーティングはPulseAudioの設定でやるのは面倒なので基本的にここで選択する。 EasyEffects同様、PulseEffectsが拾う入力、PulseEffectsを通して渡す出力の選択である。 「デフォルト」はPulseAudioの代替デバイスを指している。

マイクのコンプレッション

「コンプレッサー」がどんなものであるかは、音声を扱う作業をしたことがある人でないと知らないだろう。

まず、次に示すのは声を録音しただけの音声だ。

録音した状態

信号として許容できる最大の値を「0dB」とする。これを越えるものについては、デジタル音声ではノイズになる。 ここで、この音声全体の最大値がちょうど0.0dBに収まるように最大化する。

最大化した状態

大きくはなかったが、スパイクが立っているため、全体としては意外と大きくならないのが分かるだろう。

全体にすれば、スパイクは局所的なものだ。バランスは大事だが、スパイクを残したいわけではない。なので、スパイクを軽減したいと考えられる。

そこで登場するのがコンプレッサーである。コンプレッサーの基本的な動作は、閾値よりも大きい信号を、最大で圧縮比の大きさに収まるように圧縮する。 つまり、-16dBが閾値で、圧縮比が4:1であるならば、音声は-12dBに収まるように変更される。

圧縮(upward)

本図は-16dBで4:1の圧縮を施す図である。Audacityは「大きくする方向に変更する」挙動なので図に違和感があるが、通常は音声信号は小さくなる。 (Downward/Upwardと表現される。)

一般的にThresholdとRatioのほかに、AttackとReleaseという値がある。 これは、その信号が入力されてから本来の圧縮までにどれだけの時間をかけるかである。Releaseは、その大きさを下回ってからもとの信号の大きさまで戻すのにどれだけの時間をかけるかである。

Peak/RMSというものもあるが、こちらは性質的な違いである。 Peakは突発的な大きな音を抑えるもので、RMSは体感的な音の大きさに作用するものである。 目的がことなり、音楽的に迫力のある音を求める場合はRMSになるが、マイクの入力でスパイクを取るならPeakになる。

圧縮後の信号

実際に-16dB, 4:1, Peakでupward圧縮をした図である。 スパイクが圧縮され、全体的に0dBに近づいたのが分かる。

スパイクを潰すような圧縮の場合、目立った音質変化は感じられないが、大きい音が全体的に潰れるようなコンプレッションをかけると音質的に大きく変容する。 もちろん、全体的に大きな音、つまり音圧の高い音なる。 音楽的に「迫力のある(音圧の高い音)」を求めて音質の変化や強弱の消滅を鑑みることなく強いコンプレッションをかけたものが「海苔音源」とよく批判されるものである。

過剰な圧縮

さて、配信やビデオ会議などにおいてコンプレッションをかける意義は主に2つある。

ひとつは突発的な非常に大きな音を抑制することである。 ホラーゲーム配信などで悲鳴を上げたり、あるいはマイクにぶつかるなどして大きな信号を入れてしまうと、視聴者の鼓膜を破壊することになる。 コンプレッサーでこのような非常に大きいピークを抑えることで、最大の音をある程度に収めることができる。

もうひとつは音の平均化である。 どうしても普通に話すと話し始めと話し終わりの音は小さく、言葉として聞き取りづらいことがある。 そこで、全体的に音量を上げつつ、大きな音との差を埋めるようにすれば相手にとって聞き取りやすい一定の音量の話し声になる。 これは特にラップトップ内蔵マイクやウェブカメラ内蔵マイクなど、アンプの調整ができず感度があまりよくないマイクを使う場合に特に有効である。

この知識の上で前提の話をしよう。

まず、マイクの入力は決して0dBを越えてはならない。 つまり、マイクアンプの入力は、想定される最大の信号が0dBを下回る値とする。

PulseAudioなどのマイク音量は、100%よりも上げた場合は増幅することができるが、0dBを越える入力に対して下げても割れたままである。 常にマイクアンプから入力される信号の大きさを基準に考えなくてはならず、コンピュータシステム上のマイク音量は相手に対する調整に過ぎない。

ではそもそもマイクから想定されない、極端に過大な音声が入力されることに備えるにはどうすれば良いか。 マイクアンプのボリュームを絞ることが現実的でないのであれば、コンピュータへの入力の手前にハードウェアコンプレッサーを設置すべきだ。

アナログコンプレッサーの場合は0dBを越えても歪むだけであるため、アナログコンプレッサーを置くことは安定した録音に非常に有効だ。

一方、デジタルコンプレッサーはコンピュータ上と同じ制約を受けるが、そういう極端なダイナミクスに対応するための製品であるため、コンピュータ上で処理するよりは柔軟性が高い。 まずマイクアンプの音量を、極端に過大な音においてもコンプレッサーの許容範囲に収まるように設定する。一般的にハードウェアコンプレッサーにはインプットゲインの設定はない。それはマイクアンプ側で調整する。 このときマイクアンプの出力はかなり小さいと思われるため、一般的にはハードウェアコンプレッサーで増幅を行って出力する。 突発的な音に対応することが目的であれば、普段はコンプレッションがかからないような設定で問題ない。

一般的にハードウェアコンプレッサーは高価な機材であり、普通の人が使うようなものではない。 ハードウェアコンプレッサーを喋りで必要とするのは、プロの配信者であると考えていいだろう。しかも、台本がなく、事故の発生するような配信を行う人向けだ。

Universal AudioのVoltシリーズは、Volt176/276という低価格帯オーディオインターフェイスとしてはかなり高めのオーディオインターフェイスがあるのだが、このオーディオインターフェイスはアナログコンプレッサーを搭載している。 オーディオインターフェイスそのものが低価格デジタルコンプレッサーよりも安い価格であるため、ハードウェアコンプレッサーに魅力を感じる人にはとてもオススメだ。 ちなみに、この記事はコンプレッサーのついたVolt176にするか、コンプレッサーのないVolt1にするか悩んだ結果、PulseEffectsで試すことにした、というところから始まっている。

コンピュータに入ってくる入力が最大の入力を踏まえてもノイズに紛れない程度の信号を確保できたならば、あとはコンピュータ上で処理することができる。ここで登場するのが今回のEasyEffects/PulseEffectsだ。

インプットゲインは信号入力を増幅して処理する。 「それでは結局過大な入力で0dBを越えてしまうのではないか?」と思うだろう。しかし、ここに注目してほしい。

コンプレッサーのルーティング

s16leというのは、ステレオの16ビット(リトルエンディアン)ということだが、これは入力されるPCMデータのフォーマットを指している。 次にfloat32leとなっているが、これはコンプレッサーがどのようなPCMフォーマットで動作するかを指している。量子化ビット数が増えたならば、それはより大きい信号を扱えるようになっているということであるため、それだけで割れにくくなるのだが、浮動小数点数でのPCM処理は、処理時にそもそも割れない。

例えばマイクアンプのゲインを下げて、通常の喋りで-40dBあたりにあるとする。ここで話し声をある程度均一にしたいと考えて圧縮しようとするわけだが、この状態では相当閾値を下げない限り圧縮されない。

だが、ここで20dBくらいインプットゲインを上げれば-20dBあたりになり、現実的な設定で圧縮して均一化を図ることができる。

だが、内部処理で割れないだけで、出力時に0dBを越えていたらやっぱり割れる。見ての通り出力はs16leなのだ。 アウトプットゲインは処理を終えた音声を増幅/減衰するものである。圧縮して小さくなった分を上げるのであればプラスに振ることになるが、このときに0dBを越えないように注意する必要がある。通常、downwardで圧縮したならばマイナスにする必要はない。

もっともこのような目的にはメイクアップゲインのほうを利用する。 メイクアップゲインはコンプレッサーとして指定した分音量を上げる。アウトプットゲインはコンプレッサー処理後に単純に音量を上げる。 なお、メイクアップゲインで上げた結果0dBを越えた場合は割れる。

以上を踏まえた上でコンプレッサーの設定方法は

  • マイクのアンプは過大入力を想定して安全圏に留める。内蔵のマイク端子など調整できない場合は関係ない
  • 0dB基準としてどれくらい圧縮したいかを考えてThresholdを設定する
  • Ratioは喋りだと4:1〜5:1くらいが一般的
  • モードはPeak
  • AttackとReleaseは考え方によって変わるのでなんとも言えない
  • 音量をある程度揃えたい場合、インプットゲインを上げて声が大きいときに軽く圧縮されるようにする
  • 出力する信号が小さい場合はメイクアップゲインで余裕をもって上げる(ギリギリまで上げることはしない)

過大入力が頭を悩ませる要素なので、ハードウェアリミッターを使うことで大きすぎる音は完全に潰すという方法もある。

例えばRoland Rubix24/44はハードウェアコンプレッサーとハードウェアリミッターを両方搭載するオーディオインターフェイスであり、配信にはとても使いやすい。 また低価格USBラージダイアフラムコンデンサーマイクのBOYA PM-500はリミッターを内蔵しており、手軽に配信環境を整えることができる。

RNC1773(E)のような安価でありながら高性能なハードウェアコンプレッサー/リミッターを使うことは魅力的であるが、そのためにはマイクプリアンプ→コンプレッサー→インターフェイスの3台つなぎが必要となり、費用的にも設置的にも厳しい。

その他のフィルター

Gate

閾値より小さい音を消してしまうもの。

暗騒音やリップノイズなどを消すのに用いる。

周波数帯まで指定するものがMultiband Gate。 GateはどちらかというとMultiband Gateのほうが良いのだけど、これで狙う効果をPulseEffectsで指定するのは結構きついので、Gateで最低限消せば良いと思う。

Limiter

ある程度以上の音を完全に圧縮してしまう、極端なコンプレッサー。

CalfにはLookaheadがあり、絶対越えないようにできる。 突発的に大きな音を出してしまった場合に大音量になるのを防ぐのに使う。

突発的な音に備えると入力はかなり小さな信号になるはずだ。 そこで入ってくる大きなは突発的な大きな音であると考えることができ、これによって通常の入力との差を埋めておく。

この処理で完全にヘッドルームが空くので、次段のコンプレッサーでインプットゲインを大きく取り、全体的に大きめの音で揃えることができる。

WebRTC

ノイズやエコーを低減したり、コンプレッサーをかけたりと色々と入っているもの。 コンプレッサーには設定がない。

Deesser

歯擦音を低減するのに用いる。

Noise Reduction

環境ノイズを低減するのに用いる。

出力のほうを圧縮する

音質に問題が出るし、私は基本的に出力をエフェクトでいじるようなことはすべきでないと思うが、YouTubeをブラウザで再生すると他より音がだいぶ小さい問題に悩まされたりするので、そこに限定して使うのはアリだと思う。

しかし、まずなぜYouTubeの音が小さいのか、という点について言及する必要があるだろう。

FirefoxでYouTubeを再生した場合、再生と同時にアプリケーションボリュームが下げられている。 再生する動画によってどれくらい下げられるかは異なるため、恐らくノーマライズの一環なのだろう。

そのため、アプリケーションボリュームを100%に戻してやれば0dBに到達するようになる。

一方、ChromiumやGoogle Chromeを使った場合、アプリケーションボリュームは100%だが、音が小さいという状態になる。

この解消方法だが、ノーマライズによるゲインリダクションを外すというのが一番手っ取り早いから、mpvで再生するとゲインリダクションのない状態で再生できる。あるいは、FirefoxでYouTubeを見るようにしてもいい。

それでも動画自体の音量が低くて聞き取りづらいといったことをカバーするのであれば、方法は色々あるが、比較的汎用性が高いのはコンプを使う方法だ。 動画自体の音量のばらつきについてはPiecesで記事にした。 20/100/-12dB/4:1/-6dB Knee/0dB makeで、あとは動画によってインプットゲインをいじるくらいでだいたいうまくいく。 必要に応じて-18dBでマキシマイザをかけると音が前に出てかなり聞きやすい。

声が埋もれがちな場合の対策として、イコライザで66Hz/-6.14dB, 372Hz/0dB, 2.1kHz/-1.05dB, 11.8kHz/-9.59dBというセットも用意した。

やたらボリュームが小さい配信は珍しくないので、かなり便利。

当然だが、音楽を聞く場合など音質を重視する場合はエフェクトを通さないようにすべきだ。

PulseAudioのモジュールでコンプ

コンプだけ欲しい、といった話であればPulseEffectsなどを使わず、PulseAudioだけで完結するのもそんなに難しい話ではない。

ここではswh-pluginsのLADSPAコンプレッサーを使うとする。

まずはnull sinkを用意する。

pacmd load-module module-null-sink

次にnull sinkに出力するコンプレッサーを用意する。 ステレオでSC4を使う場合

pacmd load-module module-ladspa-sink sink_name=compressor sink_master=8 plugin=sc4_1882 label=sc4 control=1,2,300,-26,4,6,0

ここではnull sinkのindexが8だったので、sink_master=8を指定した。

モノラルでSC4mを使う場合は

pacmd load-module module-ladspa-sink sink_name=compressor sink_master=8 plugin=sc4m_1916 label=sc4m control=1,2,300,-26,4,6,0

controlの引数は

  1. RMS/Peak(0=RMS, 1=Peak)
  2. Attack
  3. Release
  4. Threshold
  5. Ratio
  6. Knee
  7. Makeup
  8. Amplitude
  9. Gain reduction

である。

続いてmodule-loopbackを利用し、マイクの入力をコンプレッサーに入れる。

インデックスは私のものなので、list-sinkslist-sourcesを使って確認すること。

pacmd load-module module-loopback source=2 sink=9

これでコンプレッサーsinkのmonitorを拾うようにすれば圧縮した音を乗せることができる。