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

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

ALSA PCMプラグインとその設定について(概要と設定ファイル)

ALSAにはPCMプラグインという仕組みがある。PCMプラグインは、PCM音声に関する色々な処理を行う。プラグインというと機能拡張のようだが、ALSA対応アプリケーションから音を出すときには、「alsa-lib」パッケージに含まれるPCMプラグインが1つ*1以上使用されている。追加の「alsa-plugins」パッケージを入れると、追加のプラグイン(例:ALSA JACKプラグイン 関連記事)が利用できる。
ここでは、ALSA PCMプラグインの種類とその定義、設定ファイルに関してを扱う。

プラグインの種類とデバイス

ALSA PCMプラグインには、行う処理によっていくつかの種類(type)がある。
http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html
に、種類ごとの説明と定義の形が出ている。
PCMプラグインバイスとは、どの種類(type)のプラグインを使用して、どのようなパラメータを指定するのかを定義したもので、/usr/share/alsa/以下のファイル群で基本的なプラグインに関して記述されている他、カスタム設定ファイルとして

  • /etc/asoundrc:システムワイド(全てのユーザ向け)
  • ${HOME}/.asoundrc:一般ユーザ(自分専用)

に記述することもできる。デバイス定義の形としては、下のようになる。

pcm.[任意のPCMプラグインデバイス名]
{
  type [プラグインの種類名]
  # (以下、種類ごとの各種設定を記述する)
}

また、/usr/share/alsa/alsa.confには、カスタマイズしやすいように(かどうかは分からないが)、幾つかの変数が用意されている。
[引用]ファイル名: /usr/share/alsa/alsa.conf より

#
# defaults
#

# show all name hints also for definitions without hint {} section
defaults.namehint.showall off
# show just basic name hints
defaults.namehint.basic on
# show extended name hints
defaults.namehint.extended off
#
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.rate 48000
defaults.pcm.dmix.format "unchanged"
(以下略)

これらの値を上書きすることで、PCMプラグインバイスの定義を書き直さずに変更できる部分もある。
設定ファイルの文法は

などを参照。

設定ファイルの引数と変数参照

上のように、変数の値で色々といじれる部分があるのは、プラグインバイスの定義内に引数を受け取ったり変数を使用できたりする仕組みがあるため。
それらは独自の方法で記述されているのだが、以下のことが分かっている。(完全に把握しているわけではない上、説明も不完全)

  • 「@args」で仮引数をスペース区切りで並べて角括弧でくくる
  • 「@args.[仮引数名]」の後ろに波括弧で引数の型や既定値の記述をする
    • 「type」は引数の型名(integer:整数 string:文字列)
    • defaultの波括弧中で既定値(引数省略時の値)を指定
  • 仮引数は「$[仮引数名]」のように、先頭にドル記号を付けることで値を取り出す
  • 「@func」は特別な方法で値を格納
    • 「@func getenv」は環境変数から読み取る
    • 「@func refer」は変数参照
    • 「@func concat」は文字列連結
  • 実引数は、プラグインバイス名を指定する際に「[プラグインバイス名]:[実引数1],[実引数2], ...」という形で指定する(例:「hw:0,0,0」)

文字で説明しても分かりにくいため、例を参考にするのがよい。
[引用]ファイル名: /usr/share/alsa/alsa.conf より

defaults.pcm.card 0
defaults.pcm.device 0
(中略)
pcm.hw {
	@args [ CARD DEV SUBDEV ]
	@args.CARD {
		type string
		default {
			@func getenv
			vars [
				ALSA_PCM_CARD
				ALSA_CARD
			]
			default {
				@func refer
				name defaults.pcm.card
			}
		}
	}
	@args.DEV {
		type integer
		default {
			@func igetenv
			vars [
				ALSA_PCM_DEVICE
			]
			default {
				@func refer
				name defaults.pcm.device
			}
		}
	}
	@args.SUBDEV {
(中略)
		}
	}		
	type hw
	card $CARD
	device $DEV
	subdevice $SUBDEV
	hint {
(以下略)

プラグインルーティング

プラグインは、その定義内で「slave.pcm」に指定した別のプラグインバイスとつながり、あるプラグインバイスから別のプラグインバイスへデータを順に渡して処理していく。渡す順番は再生(プレイバック)と録音(キャプチャ)とで逆になる。
「slave.pcm」の後ろには別の定義済みプラグインバイス名を指定するか

pcm.foo
{
  type [種類]
  slave.pcm pcm.bar  # pcm.barは定義済みとする
}

もしくは直接書くか

pcm.foo
{
  type [種類]
  slave.pcm
  {
    # 「type」を含むslaveの記述
  }
}

のどちらか。
(2008/3/16)設定ファイルに定義された「デバイス」についての呼び方に関しての修正を行った。

関連記事:

使用したバージョン:

*1:「hw」プラグインを直接使用している場合は1つになる