この連載のLXCの構築・
LXCでコンテナを使うときは,
Linuxにおける主なサウンドシステム・ サウンドサーバ
まず,
- Open Sound System
(OSS) - UNIXベースのプラットフォームで使うことができるサウンドシステムで,
ハードウェアを直接制御するOSSドライバを含んでいます。 - Advanced Linux Sound Architecture
(ALSA) - OSSを置き換えるために開発されたLinuxにおける高機能なサウンドシステムで,
現在はALSAが主流となっています。ALSAドライバとOSSエミュレーション機能を含んでいます。 - Enlightened Sound Daemon
(ESD, EsounD) - GNOMEで使われていたサウンドサーバで,
実行中の各種アプリケーションが出力するサウンドを取りまとめて, ローカルデバイスやネットワーク先のデバイスに送り出します。 - PulseAudio
- ESDの置き換えとして,
クロスプラットフォームでネットワークに対応したサウンドサーバで, 現在はPulseAudioが主流となっています。ESDエミュレーション機能を含んでいます。
これらのサウンドシステム・/dev/
,/dev/
など/dev/
aplay
コマンドなどのALSA APIを使用したアプリケーションやesdplay
コマンドなどのESD APIを使用したアプリケーションは,paplay
コマンドなどのPulseAudio APIを使用したアプリケーションとともに,padsp
コマンド
OSSを経由してサウンドを出力する
まず,/dev/
にリダイレクトすることにより,
taro@host:~$ cat pipipipi.au > /dev/audio
Sunオーディオファイルは,/usr/
/usr/
一般的なWAVファイルのような,/dev/
を使います。このとき,/dev/
をオープンしてから音声ファイル形式を設定し,
ここで,dsptest.
)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <unistd.h>
static unsigned char buf[2048];
int main(void)
{
int fdi, fdo, arg, len;
fdi = open("geragerapo-no-uta.wav", O_RDONLY);
if ((fdo = open("/dev/dsp", O_WRONLY)) == -1) {
perror("/dev/dsp");
close(fdi);
return 1;
}
arg = AFMT_S16_LE, ioctl(fdo, SNDCTL_DSP_SETFMT, &arg);
arg = 2, ioctl(fdo, SNDCTL_DSP_CHANNELS, &arg);
arg = 44100, ioctl(fdo, SNDCTL_DSP_SPEED, &arg);
lseek(fdi, 44, SEEK_SET);
while ((len = read(fdi, buf, 2048)) > 0)
write(fdo, buf, len);
close(fdi), close(fdo);
return 0;
}
以下のようにコンパイルして実行することにより,
taro@host:~$ make dsptest cc dsptest.c -o dsptest taro@host:~$ ./dsptest
コンテナ内でサウンドを出力する (OSS)
それでは,taro
ユーザがroot権限でdefault
バリアントのPlamoコンテナct01
を作成し,hanako
ユーザが音を出すことを試みます。
hanako@ct01:~$ cat pipipipi.au > /dev/audio -bash: /dev/audio: 許可がありません hanako@ct01:~$ ./dsptest /dev/dsp: No such file or directory
コンテナ内に/dev/
や/dev/
が存在しないため,taro
ユーザが以下のコマンドを実行して,
taro@host:~$ sudo lxc-attach -n ct01 -e -- \ > mknod -m 660 /dev/mixer c 14 0 taro@host:~$ sudo lxc-attach -n ct01 -e -- \ > mknod -m 660 /dev/sequencer c 14 1 taro@host:~$ sudo lxc-attach -n ct01 -e -- \ > mknod -m 660 /dev/dsp c 14 3 taro@host:~$ sudo lxc-attach -n ct01 -e -- \ > mknod -m 660 /dev/audio c 14 4 taro@host:~$ sudo lxc-attach -n ct01 -e -- \ > mknod -m 660 /dev/sequencer2 c 14 8 taro@host:~$ sudo lxc-attach -n ct01 -- \ > chmod +t /dev/{mixer,sequencer{,2},dsp,audio} taro@host:~$ sudo lxc-attach -n ct01 -- \ > chgrp audio /dev/{mixer,sequencer{,2},dsp,audio}
また,/var/
)
# Audio configuration
lxc.cgroup.devices.allow = c 14:* rwm
これらの設定により,
hanako@ct01:~$ cat pipipipi.au > /dev/audio hanako@ct01:~$ ./dsptest
これで音が出るようになりました。
コンテナ内でサウンドを出力する (ALSA)
次に,aplay
コマンドを使って音を出してみましょう。実行したところ,
hanako@ct01:~$ aplay pipipipi.au ALSA lib confmisc.c:768:(parse_card) cannot find card '0' ALSA lib conf.c:4246:(_snd_config_evaluate) function snd_func_card_driver returned error: \ そのようなファイルやディレクトリはありません ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings ALSA lib conf.c:4246:(_snd_config_evaluate) function snd_func_concat returned error: \ そのようなファイルやディレクトリはありません ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name ALSA lib conf.c:4246:(_snd_config_evaluate) function snd_func_refer returned error: \ そのようなファイルやディレクトリはありません ALSA lib conf.c:4725:(snd_config_expand) Evaluate error: \ そのようなファイルやディレクトリはありません ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM default aplay: main:696: audio open error: \ そのようなファイルやディレクトリはありません
はい,/dev/
が存在しないためですね。ホストにいるtaro
ユーザが以下のコマンドを実行して,/dev/
ディレクトリを作成します。
taro@host:~$ sudo lxc-attach -n ct01 -- mkdir -m 755 /dev/snd
また,/dev/
をバインドマウントする処理を含めた以下の設定を,/var/
)
# Audio configuration
lxc.mount.entry = /dev/snd dev/snd none bind 0 0
lxc.cgroup.devices.allow = c 14:* rwm
lxc.cgroup.devices.allow = c 116:* rwm
これらの設定により,
hanako@ct01:~$ aplay pipipipi.au 再生中 Sparc オーディオ 'pipipipi.au' : Mu-Law, レート 8000 Hz, モノラル hanako@ct01:~$ aplay geragerapo-no-uta.wav 再生中 WAVE 'geragerapo-no-uta.wav' : Signed 16 bit Little Endian, レート 44100 Hz, ステレオ
これで音が出るようになりました。