sndio(7)は音声を統一的に扱うための仕組みで、Alexandre Ratchovらによって2008年リリースのOpenBSD 4.5に始めて導入された。 現在はFreeBSD/NetBSD/Linuxにも移植されている。
ALSA, JACK, OSS, PulseAudioなどの音声フレームワークと同様、sndioは音声を扱うハードウェアとアプリケーションとの橋渡しをする。 具体的には、sndioは以下のような機能を持っている。
以下に、OpenBSDでsndioフレームワークが動作している様子を示す。
$ audioctl name=azalia0 mode=play,record pause=0 active=1 nblks=8 blksz=960 rate=48000 encoding=s16le play.channels=2 play.bytes=3796930560 play.errors=883200 record.channels=2 record.bytes=3796930560 record.errors=552960
$ mixerctl -v | sort inputs.dac-0:1=234,234 inputs.beep=119 inputs.beep_mute=off [ off on ] inputs.dac-2:3=234,234 inputs.hp_source=sel6,mix6 { sel6 mix6 } inputs.mic2=0,0 inputs.mic3=0,0 inputs.mic3_source=sel7,mix6 { sel7 mix6 } inputs.mic=0,0 inputs.mix4_source=sel3,mix6 { sel3 mix6 } inputs.mix6_mic2=0,0 inputs.mix6_mic=0,0 inputs.mix6_source=mic,mic2 { mic mic2 } inputs.sel3_source=dac-0:1 [ dac-0:1 dac-2:3 ] inputs.sel4_source=dac-0:1 [ dac-0:1 dac-2:3 ] inputs.sel6_source=dac-0:1 [ dac-0:1 dac-2:3 ] inputs.sel7_source=dac-0:1 [ dac-0:1 dac-2:3 ] inputs.spkr_source=dac-2:3,mix6 { dac-2:3 mix6 } outputs.hp_boost=off [ off on ] outputs.hp_mute=off [ off on ] outputs.hp_sense=plugged [ unplugged plugged ] outputs.master.mute=off [ off on ] outputs.master.slaves=dac-0:1,dac-2:3,hp,spkr { dac-0:1 dac-2:3 beep hp spkr mic3 mix6 mic3 } outputs.master=255,255 outputs.mic2_dir=input-vr80 [ none input input-vr0 input-vr50 input-vr80 input-vr100 ] outputs.mic3_dir=input-vr80 [ none output input input-vr0 input-vr50 input-vr80 input-vr100 ] outputs.mic3_mute=off [ off on ] outputs.mic3_sense=unplugged [ unplugged plugged ] outputs.mic_dir=input-vr80 [ none input input-vr0 input-vr50 input-vr80 input-vr100 ] outputs.mic_sense=plugged [ unplugged plugged ] outputs.mix6=0,0 outputs.mix6_mute=off [ off on ] outputs.spkr_boost=off [ off on ] outputs.spkr_eapd=on [ off on ] outputs.spkr_mute=on [ off on ] outputs.spkr_muters=hp,mic3 { hp mic3 } record.adc-0:1=200,200 record.adc-0:1_mute=off [ off on ] record.adc-0:1_source=mic [ mic mic2 ] record.adc-2:3=200,200 record.adc-2:3_mute=off [ off on ] record.adc-2:3_source=mic2 [ mic mic2 ] record.volume.mute=off [ off on ] record.volume.slaves=adc-2:3,adc-0:1 { adc-2:3 adc-0:1 mic mic2 } record.volume=200,200
$ cd /usr/ports $ find * -type d -name patches | xargs grep -rils 'portaudio' | cut -d/ -f1,2 \ | sort | uniq | wc -l 12
$ cd /usr/ports $ find * -type d -name patches | xargs fgrep -rls 'sndio.h' | cut -d/ -f1,2 \ | sort | uniq | wc -l 41
sndio APIを使用するには、libsndioより提供される各種関数を使う。
sio_*が音声ストリーム関連、mio_*がMIDIストリーム関連の関数となる。
処理の流れ:
sio_open() /* 音声デバイスや音声サーバに接続 */ ↓ sio_getpar() / sio_setpar() /* 音声フォーマットの取得と設定 */ ↓ sio_start() /* 処理の開始 */ ↓ sio_read() / sio_write() /* 入出力 */ ↓ sio_stop() /* 処理の終了 */ ↓ sio_close() /* 接続を閉じる */
MIDI接続の場合も、これに準ずる。
sio_open()では、一番目の引数で、以下の記法によって接続先を指定する:
type[@hostname][,unit]/devnum[.option]
この記法はsndiodやaucatなどで音源のデバイスやサーバに接続する場合の接続先指定としても使用される。
例:
rsnd/0 ... /dev/audio0
snd/0.rear ... デフォルトで起動しているsndiodのリアスピーカ出力
# rcctl set sndiod flags '-s default -m play,mon -s mon' # rcctl restart sndiodこの設定を行っておくとffmpeg実行時、-i snd/0.mon を指定することで、スクリーンキャプチャ時にアプリケーションの再生音を収録する。
$ ffmpeg -f x11grab -s 800x600 -i :0.0+100,100 -f sndio -i snd/0.mon screencapt.mpg
$ aucat -o - | lame -r -s 48 - recinput.mp3