本連載ではこれまで十数回にわたり、Ubuntuでサウンドを扱う話題を紹介してきました。Ubuntuのサウンド環境はALSA、PulseAudioそしてJACKなどといった複数のソフトウェアで構成されているため、そろそろ混乱してくるころです。というわけで今回は、UbuntuもといLinuxの現在のサウンドシステムに関して、MIDIも考慮しながら整理してみたいと思います。
ALSAの役割
ALSA とはAdvanced Linux Sound Architectureの略称で、Linuxにおける高機能なサウンドシステムを提供するためのソフトウェア群です。「 Advanced」ということは「Advancedでない」ものがあるわけで、それが本連載の第144回 でお伝えしたOpen Sound System です。Open Sound Systemには同時に音声を出力出来るソフトウェアの最大数が4つ、多チャンネルのサラウンド音声を扱うことができずステレオ音声だけ、といった弱点があり、ALSAはその弱点を克服するために生まれました。
ALSAは2つの大きな部品から構成されています。ひとつは「ALSAカーネルモジュール」で、その名の通りカーネルモジュールの形で提供される「サウンドデバイスのためのドライバー」です。もうひとつが「ALSAライブラリー」で、ソフトウェアがサウンドデバイスを扱うための手続きをAPI(Application Program Interface)の形で提供します[1] 。ALSAカーネルモジュールはLinuxカーネルのイメージに組み込まれており、ALSAライブラリーはパッケージ「libasound2」で提供されています。
現在、ALSAのサポートするサウンドデバイスはかなりの数に及び 、日々新しいコードが付加されています。
[1] 「ALSA」として配布されているソフトウェア群には、これら2つのモジュールに加えて、ボリュームコントローラなどのさまざまなユーティリティ・ソフトウェア、サウンドデバイス個別のファームウェアファイル、機能拡張のためのプラグイン、Open Sound System互換レイヤーやALSAライブラリーのPythonバインディングなども含まれます。
サウンドサーバーの役割
Ubuntuにログインすると自動起動するPulseAudio や、Qjackctlを使って手動で起動するJACK(Jack Audio Connection Kit) は、「 サウンドサーバー」と呼ばれています。
サウンドサーバーはあまり聞きなれない言葉ですが、以下のような役割を提供する常駐ソフトウェアです。機能面では、Windows環境で「ソフトウェアサウンドデバイス」「 フィルタドライバー」などと呼ばれるものによく似ています。
サウンドをミックス
さまざまな種類のデバイスへ接続
それぞれ細かく見ていきましょう。
サウンドをミックス
ソフトウェアは再生の際、ALSAライブラリーを利用してALSAカーネルモジュール経由でサウンドデバイスに接続し、オーディオデータを流し込みます。この際、このサウンドデバイスは使用中となってしまうため、他のソフトウェアを再生してオーディオデータをこのデバイスに流そうとしても、エラーが発生してしまいます。
図1 デバイスがビジー状態=使用中であるとしてエラーを報告
ここに、サウンドをミックスして出力する必要が生じます。サウンドサーバーは複数のソフトウェアから同時にオーディオデータが流れこんだ場合、音声を「ミックス」してひとつのオーディオデータとしてサウンドデバイスに送ることができます。
図2 PulseAudio Volume Controlはソフトウェアの音声入出力をデバイスの入出力に振り分ける。この際、同一のデバイスへの出力はミックスされる
実はこのミックスはALSAでもdmix プラグインで行うことができます。本連載の第159回 では、PulseAudioを標準でインストールしないXubuntuが、どのようにサウンドのミックスを可能としているかを紹介しました。
サウンドデバイスのマイク入力から取得した音データに関しても同等のことが起こるため、複数の録音ソフトウェアに音データを「増やして」から届けるといった機能も、サウンドサーバーは備えています。こちらも、ALSAにおいてはdsnoopプラグイン で実現することが可能です。
サウンドサーバーでミックスされたオーディオデータは、さらに出力対象デバイスに合わせてリサンプリングやフォーマット変更が行われ、デバイスに渡されます。
さまざまな種類のデバイスへ接続
本連載の第159回 、第160回 、第161回 、第172回 で、さまざまな接続形態のサウンドデバイスを利用する方法を紹介しました。その際利用するドライバーはALSAのみならず、Open Sound SystemやFFADO/Firewire、BlueZと多岐に渡りました。
さらに本連載の第106回 ではネットワーク越しに他のコンピューターのPulseAudioを利用する方法を紹介しました。この場合はネットワークをデバイスとして利用していると表現できるでしょう。
このようなデバイスの中から入力先/出力元を選択してソフトウェアとの接続を振り分けるというのも、サウンドサーバーの役割となります。
なお、PulseAudioは同時に複数のサウンドデバイスと接続して使っていくことが可能ですが、JACKはひとつのサウンドデバイスに集中的に接続します。これは設計思想の違いが影響していて、PulseAudioはプラグインによって自由に拡張してさまざまな機能を持たせることができるよう作られているのに対し、JACKは高品質なサウンドシステムを構築するためひとつのサウンドデバイスに対する高い使い勝手を志向して作られていることによります。
ひと通り整理したところで、ここまでを図にまとめてみました。
図3 Linuxのサウンドシステムの概念図
サウンドサーバー間の連携
PulseAudioとJACKはそのままではオーディオデータを互いにやりとりすることができません。そこで利用されるのがPulseAudioのプラグイン拡張 です。具体的にはパッケージ「pulseaudio-module-jack」に含まれるモジュール「module-jack-sink」と「module-jack-source」です。PulseAudio側でこのモジュールを有効にすると、起動しているJACKをあたかもひとつのサウンドデバイスのように扱うことができるようになります。
ロードするには端末(gnome-terminal)で以下のコマンドを実行します。この場合はPulseAudioとJACKをつなぐ入出力ポートが2つずつ開かれますが、マルチチャネルで接続したい場合は3(=Left+Right+Center出力)や5(5ch出力)や7(7ch出力)を指定することになるでしょう。
$ pacmd load-module module-jack-source channels=2;
$ pacmd load-module module-jack-sink channels=2;
ポートが開かれたら、JACK側はQjackctlやPatchageで、PulseAudio側はPulseAudio Volume Controlでポートを接続します。
図4 PatchageとPulseAudio Volume Control。連携時には両方をつなぐSink/Sourceとplayback/captureが利用可能となる
ALSAライブラリーとPulseAudioの音声入出力については、本連載の第144回 で少し触れている通り、Ubuntu環境の標準ではPulseAudioが「ALSAデバイスのふりをするもの」として追加され、標準の入出力先として設定されています。この設定はファイル「/usr/share/alsa/pulse.conf」に記述されています。「 /usr/share/alsa/alsa.conf」を編集することでpulse.confをロードするエントリを削除すれば、ALSAライブラリーを利用するソフトウェアから直接、ALSAカーネルモジュールに出力するようになります。しかしUbuntuで利用する多くのソフトウェアはPulseAudioに対して直接音声入出力を行うようになっているため、影響を受けるのはALSAデバイスを直接指定しているソフトウェアだけです[2] 。一般的なデスクトップ環境では、ウェブブラウザ上で動画再生やゲームを実装するAdobe Flash Playerに限定されるでしょう。
JACKのネットワーク機能
PulseAudioと同じように、JACKもLAN内の別なコンピューターと連携することができます。これは、Ubuntu 10.10以降で利用可能なJACKのパッケージ「jackd2」が備える機能となります。
設定に先立ち、サウンドデバイスに接続して実際に音声を出力するコンピューターをマスター、マスターにネットワーク接続してオーディオデータを転送するコンピューターをスレーブと呼ぶことにします。JACKのネットワーク機能は以下の手順で起動します。
マスター側でQjackctlを使い、通常通りサウンドデバイスを利用するようにJACKを起動
スレーブ側でQjackctlのDriverを「netone」に設定してJACKを起動。この際、端末でifconfigなどを実行してスレーブのIPアドレスを調べておく
マスター側で端末を開き、コマンド「$ jack_netsource -H (IPアドレス);」を実行
筆者のUbuntu Studioではうまくいかなかったのですが、Avahi を適切に設定しているUbuntu同士であれば、IPアドレスの代わりにホスト名も使うことができるでしょう。
JACKのネットワーク機能が立ち上がると、スレーブのplayback/captureポートがマスターのcapture/playbackポートとして認識されますので、Patchageなどでマスター/クライアントポートを接続することでオーディオデータを転送することができるようになります。
図5 Patchageでスレーブ側のポートを表示
図6 Patchageでマスター側のポートを表示
なお、コマンド「$ man jack_netsource;」を実行することでマニュアルを参照することができます。音切れが気になる場合は、コマンドラインから起動オプションのネットワークパケットのサイズを調整することで対応します。
2つのMIDIサブシステムの連携
ここまでは「音を出す」という機能に着目して紹介してきましたが、MIDI規格に基づいて信号をやりとりすることで、第149回 、第150回 、第169回 、第170回 、第176回 で紹介したようなソフトウェアを互いに連携させることができます。これらのソフトウェアは、「 MIDIポートを通じて他のデバイスやソフトウェアを操作する」( MIDI出力)機能と、「 MIDIポートを通じて他のデバイスやソフトウェアからの操作命令を受け取る」( MIDI入力)機能に対応しているため、適切に設定を行うことで「DAWソフトウェアからソフトウェアシンセサイザーを鳴らす」「 MIDI対応のキーボードからDAWに旋律を入力する」といった使い方ができるようになります。
この際、MIDI信号の扱いに力を発揮するのがALSAシーケンサー機能です。MIDIを扱うハードウェアもソフトウェアもALSAシーケンサー機能にポートを開いてMIDI入出力を行うことができます。
LinuxにはALSA以外に、JACKサウンドサーバーの一機能であるJACKシーケンサー機能があります。Firewire接続のMIDIデバイスやFeSTige といった一部のソフトウェアは、JACKシーケンサー機能を用いてMIDI入出力を行います。
残念なことに、ALSAシーケンサー機能とJACKシーケンサー機能はそのままでは連携することができません。そこで、この2つのMIDIサブシステムの橋渡しをするソフトウェアであるa2jmidid を使います。
起動は端末から行います。その際、あらかじめJACKサウンドサーバーを起動しておくのを忘れないでください。端末を開き、コマンド「$ a2jmidid -e;」を実行します。
図7 a2jmididを起動してからpatchageでMIDIポートを見ると、ALSAシーケンサー上で認識されたポートが、そのままJACKシーケンサーから認識されている状態を確認できる。なお、紺はJACKオーディオ機能、緑はALSAシーケンサー機能、赤はJACKシーケンサー機能で認識されているポートを示し、同じ色のポートのみ接続が可能
MIDIサブシステムのネットワーク機能
JACKシーケンサー機能も、先述したJACKのネットワーク機能により、ネットワークを経由して他のコンピューターにMIDI入出力ポートを提供することができます。また、ALSAシーケンサー機能もパッケージ「alsa-tools」に含まれる「aseqnet」を利用することでネットワーク機能を持たせることができます。
ALSAシーケンサー機能のネットワーキングを行うには、マスターでコマンド「$ aseqnet;」を実行します。この際、マスターのIPアドレスを調べておいてください。スレーブで「$ aseqnet (IPアドレス);」を実行してマスターに接続します(ここでも、IPアドレスの代わりにホスト名を指定して接続が可能かと思います) 。
図8 Patchageでポートを見ると、NetworkというMIDI入出力ポートがマスター/スレーブ共に開いているのがわかる
このように、一見複雑に見える現在のLinuxのサウンドシステムも、ALSA/PulseAudioの関係を軸に見るとそれなりにすっきりとまとまっています。さらに今回は、音楽制作/編集環境目的で利用されるJACKとMIDI機能も加えて整理してみました。実際はこれらのソフトウェアに加えて、GStreamer やSDL ( Simple DirectMedia Layer) 、PortAudio といったマルチメディアフレームワークが多用されているわけですが、ALSAライブラリーを利用している点では同じです。サウンドに関するトラブルに遭遇した際は、それぞれのソフトウェアやマルチメディアフレームワークが何に対して音声入出力を行っているかを調べると、解決が早まることでしょう。