Top/EBUG勉強会/20180825_sndio

sndio - OpenBSDの音声フレームワーク

EBUG 第66回会合
2018年 8月25日、長岡市 ながおか市民センター
川俣吉広、kaw@on.rim.or.jp

概要

sndio(7)はOpenBSDで音声を統一的に扱うための仕組みで、Alexandre Ratchovらによって2008年リリースのOpenBSD 4.5に導入された。 現在は、FreeBSD/NetBSD/Linuxにも移植されている。

ALSA, JACK, OSS, PulseAudioなどの音声フレームワークと同様、sndioは音声を扱うハードウェアとアプリケーションとの橋渡しをする。 具体的には、sndioは以下のような機能を持っている。

構成

以下に、OpenBSDでsndioフレームワークが動作している例を示す。

sndio.png
ハードウェア
様々な音声機器は、PC内の音声コーデックに接続される。コーデックはアナログ機器とのA/D, D/A変換や複数入出力のミキシングやファンアウト、そして各信号のレベル制御などをおこなう。
デバイスドライバ
カーネル内には、コーデックに対応したデバイスドライバがあり、コーデックの機種毎の機能に対応した制御を行う。 例えばIntelのICH8 I/Oコントローラ・ハブはIntel(R) 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(8)
sndioフレームワークの中核で、OpenBSDブート時に起動され、デフォルトの音声デバイス/dev/audio0へのアクセスを提供する。前節の「概要」で述べた機能の殆どは、このsndiodによってサポートされる。
ユーザコマンド - aucat(1)
コマンドレベルでsndioにアクセスするためのツール。 aucatもsndiod同様、sndioの機能の殆どを提供する。 sndiodがデーモンとしてバックグラウンドで機能を提供するのに対し、aucatはユーザが直接オンライン、あるいはオフラインでsndioの機能を利用することを意図して作成されている。 例えば、aucatには処理を行う音声データをファイルから入力したり、ファイルへ出力したりする機能がある。 aucatコマンド自体はOpenBSD 2.0から存在し、sndioフレームワークが登場する以前のOpenBSD 4.3までは単に複数の音声ファイルを連結して再生する(concatenate and play audio files)コマンドだった。 OpenBSD 4.5でsndioフレームワークが登場した時点ではsndiodはなくaucatがデーモンの役目を追っていたが、OpenBSD 5.1以降はsndiodとaucatとに役割が分割された。
音声アプリケーション
音声を扱うアプリケーションでsndioを使用するには、以下のパターンが考えられる。
  • 音声アプリケーション自体が、最初からsndioに対応している。
    ...特に手を加えずにビルドして使う。

  • 音声アプリケーション自体は対応していないが、アプリケーションがリンクするライブラリが対応している。
    ...例えば音声編集ソフトのAudacityなど。Audacity自体はsndioに対応していないが、クロスプラットフォームの音声ライブラリであるPortAudioをリンクしてビルドするとPortAudioはsndioをサポートしているため、Audacityもsndio対応となる。
    $ cd /usr/ports
    $ find * -type d -name patches | xargs grep -rils 'portaudio' | cut -d/ -f1,2 \
    | sort | uniq | wc -l
    12

  • 音声アプリケーションにsndio対応のパッチを当てる。
    ...ports/packagesでは、このケースが最も多いようだ。
    $ cd /usr/ports
    $ find * -type d -name patches | xargs fgrep -rls 'sndio.h' | cut -d/ -f1,2 \
    | sort | uniq | wc -l
    41

  • sndioに対応していない音声アプリケーションとsndioツールを組合せて使う。
    ...音声アプリケーションが再生あるいは収録のみで、リアルタイム性を要求されないのであれば、パイプやファイルを経由してaucatなどとデータのやりとりをする。

API

使用例

報源


Top/EBUG勉強会/20180825_sndio

Front page   New Page list Search Recent changes   Help   RSS of recent changes