- The added line is THIS COLOR.
- The deleted line is THIS COLOR.
#topicpath
* sndio - OpenBSDの音声フレームワーク [#t571d65f]
RIGHT:EBUG 第66回会合 ~
2018年 8月25日、長岡市 ながおか市民センター ~
川俣吉広、kaw@on.rim.or.jp
**概要 [#xbc2884e]
sndioはOpenBSDで開発された音声を扱うための仕組みで、2008年にAlexandre RatchovらによってOpenBSD 4.5に導された。
現在は、FreeBSD/NetBSD/Linuxにも移植されている。
sndioは他のオーディオフレームワーク(ALSA, JACK, OSS, PulseAudioなど)と同様、音声を扱うハードウェアとアプリケーションとの橋渡しをする。
体的には、以下のような機能を持っている。
-音声デバイスを直接アクセスした場合、デバイスにアクセスできるは単一のアプリケーションだけ。
sndioを介在させることで複数のアプリケーションが同時に音声を再生・収録できることを可能にする。
-音声のフォーマット変換を行う。
音声データの形式、サンプルレート、量子化ビット深度、チャンネル数などのパラメータが音声デバイスとアプリケーションとで異っていても、sndioで変換を行うことで支障なく使用できる。
-音源の制御を可能にする。
sndioは音声データそのもの以外に、起動・停止、音量制御、タイムコードなどををMIDIプロトコルを使用して伝送することができる。これにより、音源の制御を行うことができる。
-信号のルーティングを行う。
sndioサウンドサーバでは複数の音源をミックスしたり、あるいは複数の音声アプリケーションへ送出するなどのルーティング行う。
これらの伝送はネットワークを経由して、他ホストで稼動している音声デバイスやアプリケーションを使用することもできる。
**構成 [#z972347e]
以下に、OpenBSDでsndioフレームワークが動作している例を示す。
#ref(sndio.png);
:ハードウェア|様な音声機器は、PC内の音声コーデックに接続される。コーデックはアナログ機器とのA/D, D/A変換や複数入出力のミキシングやファンアウト、そして各信号のレベル制御などをおこなう。
:デバイスドライバ|カーネルには、コーデックに対応したデバイスドライバがあり、コーデックの機種毎の機能に対応した制御を行う。
例えばIntelのICHxxチップはHD Audio規格に準拠しており、これに対応するドライバは、azalia(4)である。
各コーデックに対応したドライバの上にはaudio(4)があり、これがユーザプロセスに対して一貫したAPIを提供する。
このレイヤーを参・操作するツールとしてaudioctl(1)やmixerctl(1)が提供されている。
$ 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
:オーディオサーバ - sndiod|
:ユーザコマンド - aucat|
:音声アプリケーション|
**API [#ba4463c8]
**使用例 [#x7ebf0e4]
**報源 [#fcd638e8]
----
#topicpath