試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

JACK Audio Connection Kitをネットワーク経由で使用

NetJack(http://netjack.sourceforge.net/)を使用することにより、JACK Audio Connection Kitを使用して、ネットワーク経由でJACK対応アプリケーションのオーディオデータを転送することができる。

準備

ローカル(手元・音声が直接出る)側とリモート側の両方でJACK Audio Connection KitとNetJackをインストールしている必要がある。
(2008/12/1)NetJackはJACK Audio Connection Kitのバージョン0.109.2から本体の一部となった。

Gentoo Linuxでは楽に入るが、初回インストール時は注意

Gentoo Linuxでは「USE=netjack」でビルドすれば自動的にNetJackを組み込んでビルドしてくれるのだが、一度JACK Audio Connection Kitをインストールしておかないと

make[1]: Leaving directory `/var/tmp/portage/media-sound/jack-audio-connection-kit-0.109.2/work/jack-audio-connection-kit-0.109.2'
scons: Reading SConscript files ...
{'jack_source_dir': '/var/tmp/portage/media-sound/jack-audio-connection-kit-0.109.2/work/jack-audio-connection-kit-0.109.2'}
Package jack was not found in the pkg-config search path.
Perhaps you should add the directory containing `jack.pc'
to the PKG_CONFIG_PATH environment variable
No package 'jack' found
OSError: 'pkg-config --cflags --libs jack samplerate' exited 1:
  File "/var/tmp/portage/media-sound/jack-audio-connection-kit-0.109.2/work/netjack-0.12/SConstruct", line 29:
    env.ParseConfig('pkg-config --cflags --libs jack samplerate')
  File "//usr/lib64/scons-0.97/SCons/Environment.py", line 1134:
    return function(self, self.backtick(command))
  File "//usr/lib64/scons-0.97/SCons/Environment.py", line 473:
    raise OSError("'%s' exited %d" % (command, status))
>>> Source compiled.
(中略)
make[1]: Leaving directory `/var/tmp/portage/media-sound/jack-audio-connection-kit-0.109.2/work/jack-audio-connection-kit-0.109.2'
!!! dobin: alsa_in does not exist
!!! dobin: alsa_out does not exist
!!! dobin: jacknet_client does not exist
install: cannot stat `jack_net.so': そのようなファイルやディレクトリはありません
>>> Completed installing jack-audio-connection-kit-0.109.2 into /var/tmp/portage/media-sound/jack-audio-connection-kit-0.109.2/image/
(以下略)

のようになって入らない(NetJack抜きでインストールされる)ため、再び上書きインストールする必要がある。もしJACK自体が既にインストールされていれば、正常にインストールされる。理由は、NetJackがJACKのライブラリを使用することにより、その開発パッケージが要求されるため。

ビルドに必要なもの

ビルドにはJACK Audio Connection Kitのソースツリーに加えてJACK/ALSA/libsamplerateが必要。いずれも開発パッケージで、Debian/Ubuntuではlibjack-dev/libasound2-dev/libsamplerate0-devの3つのパッケージとなる。
NetJackはJACKのモジュールとして動作するため、JACK Audio Connection Kit自身を再ビルドする必要はない。
また、ビルドツールのsconsも必要なので、これも入れておく。

ビルドの作業例

sconsjack_source_dir=でJACKのソースツリーの最上位ディレクトリを指定する。

$ tar zxf [jack-audio-connection-kit-[バージョン].tar.gzの場所]
$ tar jxf [netjack-0.12.tar.bz2の場所]
$ cd netjack-0.12/
$ scons jack_source_dir=../jack-audio-connection-kit-[バージョン]
$ sudo install -s jacknet_client alsa_{in,out} /usr/bin/
$ sudo install -s jack_net.so /usr/lib/jack/

使い方

  1. ローカルで通常通りjackdを開始(QjackCtlでも可)
  2. リモートで「jackd -d net*1を実行
  3. ローカルで「jacknet_client -p [リモートのIPアドレス]」を実行

ポートについて

ローカル/リモートのそれぞれで、ポートを待ち受ける必要があり、iptablesを使用している場合、それらを許可するように指定する必要がある。プロトコルはいずれもUDPのみ

リモート側

ポート番号は、既定では3000番。jackd -d net-l(--listen-port)オプションで番号は変更可能。

remote# iptables -A INPUT -s [ローカルのIPアドレス] -p udp -m udp --dport [リモートで待ち受けるポート番号] -j ACCEPT
ローカル側

ポート番号は、jacknet_clientの実行時に-rオプションで指定する。

local# iptables -A INPUT -s [リモートのIPアドレス] -p udp -m udp --dport [ローカルで待ち受けるポート番号] -j ACCEPT
jacknet_clientの出力
local$ jacknet_client -r [ローカルで待ち受けるポート番号] -p [リモートのIPアドレス]
engine sample rate: 48000
Packet Miss: (expected: 8236, got: -1) framecnt=0
Packet Miss: (expected: 8236, got: -1) framecnt=1
(中略)
Packet Miss: (expected: 8236, got: -1) framecnt=49
Packet Miss: (expected: 8236, got: -1) framecnt=50
FRAMCNT_DIFF = -50  -----  A Packet was lost, or did came too late (try -l 50)
FRAMCNT_DIFF = -49  -----  A Packet was lost, or did came too late (try -l 49)
FRAMCNT_DIFF = -48  -----  A Packet was lost, or did came too late (try -l 48)
FRAMCNT_DIFF = -47  -----  A Packet was lost, or did came too late (try -l 47)
Packet Miss: (expected: 8236, got: -1) framecnt=51
Packet Miss: (expected: 8236, got: -1) framecnt=52
FRAMCNT_DIFF = -48  -----  A Packet was lost, or did came too late (try -l 48)
FRAMCNT_DIFF = -47  -----  A Packet was lost, or did came too late (try -l 47)
FRAMCNT_DIFF = -46  -----  A Packet was lost, or did came too late (try -l 46)
Packet Miss: (expected: 8236, got: -1) framecnt=53
FRAMCNT_DIFF = -46  -----  A Packet was lost, or did came too late (try -l 46)
Packet Miss: (expected: 8236, got: -1) framecnt=54
FRAMCNT_DIFF = -4  -----  A Packet was lost, or did came too late (try -l 4)
Packet Miss: (expected: 8236, got: -1) framecnt=55
FRAMCNT_DIFF = -4  -----  A Packet was lost, or did came too late (try -l 4)
FRAMCNT_DIFF = -3  -----  A Packet was lost, or did came too late (try -l 3)
Packet Miss: (expected: 8236, got: -1) framecnt=56
FRAMCNT_DIFF = -3  -----  A Packet was lost, or did came too late (try -l 3)
FRAMCNT_DIFF = -2  -----  A Packet was lost, or did came too late (try -l 2)
Packet Miss: (expected: 8236, got: -1) framecnt=57
FRAMCNT_DIFF = -2  -----  A Packet was lost, or did came too late (try -l 2)
Packet Miss: (expected: 8236, got: -1) framecnt=58
FRAMCNT_DIFF = -2  -----  A Packet was lost, or did came too late (try -l 2)
sync = 1
(以下メッセージ)

「sync = 1」が表示されれば成功で、失敗すると「Packet Miss」のメッセージが出続ける。

接続後の使い方:「net_source」とのポート接続

この後、リモートマシン上でJACKクライアントから(リモートの)

  • system:playback_1
  • system:playback_2

へ音声を出力すると、このオーディオデータをローカル上の

  • net_source:capture_1
  • net_source:capture_2

という出力ポートとして使用できる。これらのポートをローカルのplaybackポートに接続することで音を出力することができ、他のJACKクライアントの入力ポートに接続することでオーディオデータを渡して処理することもできる。これらの操作では、オーディオデータがネットワーク経由で流れていると意識することはない。

また、逆に、ローカルのオーディオアプリケーションの出力ポート(もしくは外部入力の「system:capture_[番号]」)から

  • net_source:playback_1
  • net_source:playback_2

に接続することで、リモートに音声を送ることもできる。これはリモートのsystem:capture_[番号]のポートから取り出せる。

リモートのjackdがCtrl+Cで止まらない場合について

リモートの端末上で「jackd -d net」実行してからこれにローカルから接続する前に止めようとしたときなど、Ctrl+Ckillall(オプションなし)で終了しないことがある。この場合、-KILLオプション付きで強制的に終了する。

$ killall -KILL jackd

関連記事:

使用したバージョン:

  • JACK Audio Connection Kit 0.109.2
  • NetJack 0.12

*1:必要に応じて-r-pオプションを追加