PythonからALSAのミキサーを扱う
pyalsaaudio(http://pyalsaaudio.sourceforge.net/)を用いると、PythonのコードからALSAのミキサーやPCMデバイスを操作することができる。
ここではミキサー項目の取得と音量取得/変更を試してみることにする。
ディストリのパッケージ
Gentooでは「pyalsaaudio」、Mandriva/Debian/Ubuntuでは「python-alsaaudio」というパッケージが用意されている。2009年2月現在のDebian/Ubuntuのパッケージはバージョンが古い(0.2系まで)。
ミキサー項目の取得
関数alsaaudio.mixers()を使用することで、利用可能なミキサー項目がリストとして得られる。
以下のコードを実行すると、(0番のサウンドカードにおける)利用可能なミキサー項目を全て表示する。
[任意]ファイル名: mixerlist.py
#! /usr/bin/python # -*- encoding: utf-8 -*- import sys try: import alsaaudio except: print >> sys.stderr, "Error: pyalsaaudio not installed" sys.exit(1) for m in alsaaudio.mixers(): print m
ミキサーオブジェクトの作成
ミキサー値の取得や変更をするためには、alsaaudio.Mixerオブジェクトを作成しておく必要がある。ミキサーに対する操作は、このオブジェクトのメンバ関数を呼び出して行うことになる。
下の例では(0番のサウンドカードにおける)ミキサー項目(コントロール)「Master」に対するミキサーのオブジェクトを作成する。もしこのミキサー項目がなければ例外alsaaudio.ALSAAudioErrorが発生する。
name = "Master" try: mixer = alsaaudio.Mixer(name) except alsaaudio.ALSAAudioError: print >> sys.stderr, "Error: No such control: %s" % name sys.exit(1)
音量の取得
alsaaudio.Mixerオブジェクトのメンバ関数getvolume()により、該当するミキサー項目の各チャンネルごとの値をリストとして取得できる。
音量の変更
音量を変更するにはalsaaudio.Mixerオブジェクトのメンバ関数setvolume()を使用し、チャンネル(0番からの数字で指定)ごとに音量を指定できる。
もし、全てのチャンネルで同じ値を用いて変更したい場合はチャンネルを指定する部分にalsaaudio.MIXER_CHANNEL_ALLを指定する。
音量変更の例
以下のスクリプトでは、指定した名前のミキサー項目に対して、指定した値に音量を変更する。その際には、変更前後の音量をチャンネルごとに表示する。
[任意]ファイル名: mixerset.py
#! /usr/bin/python # -*- encoding: utf-8 -*- import sys try: import alsaaudio except: print >> sys.stderr, "Error: pyalsaaudio not installed" sys.exit(1) if len(sys.argv) < 3: print "USAGE: %s [name] [volume/ch1] ( [volume/ch2] )" sys.exit(1) name = sys.argv[1] # ミキサー項目名 vol = sys.argv[2:4] # 音量のパーセンテージ(0-100)の入ったリスト # ミキサーオブジェクトの作成 try: print 'mixer = alsaaudio.Mixer("%s")' % name mixer = alsaaudio.Mixer(name) except alsaaudio.ALSAAudioError: print >> sys.stderr, "Error: No such control: %s" % name sys.exit(1) # (変更前の)音量をチャンネルごとにリストとして取得 # Masterは1ch oldvol = mixer.getvolume() # 音量を変更 # setvolume()で0から100以外の値を取ると例外alsaaudio.ALSAAudioErrorが発生 # alsaaudio.ALSAAudioError: Volume must be between 0 and 100 if len(vol) == 1: channel = alsaaudio.MIXER_CHANNEL_ALL print "mixer.setvolume(%d, alsaaudio.MIXER_CHANNEL_ALL)" % (int(vol[0])) mixer.setvolume(int(vol[0]), channel) else: # 各チャンネルの音量を変更 for i, v in enumerate(vol): mixer.setvolume(int(v), i) print "mixer.setvolume(%d, %d)" % (int(v), i) # 変更前後の値を表示 print "%s: %s -> %s" % (name, oldvol, vol)
下は実行例。
(マスターボリュームを60%にする) $ [mixerset.pyの場所] Master 60 mixer = alsaaudio.Mixer("Master") mixer.setvolume(60, alsaaudio.MIXER_CHANNEL_ALL) Master: [ [変更前のMaster値] ] -> ['60'] (PCMの左を60%,右を20%にする) $ [mixerset.pyの場所] PCM 60 20 mixer = alsaaudio.Mixer("PCM") mixer.setvolume(60, 0) mixer.setvolume(20, 1) PCM: [ [変更前のPCM値(左)], [変更前のPCM値(右)] ] -> ['60', '20'] (範囲外の値を指定してみる) $ [mixerset.pyの場所] PCM 101 mixer = alsaaudio.Mixer("PCM") mixer.setvolume(101, alsaaudio.MIXER_CHANNEL_ALL) Traceback (most recent call last): File "[mixerset.pyの場所]", line 36, in <module> mixer.setvolume(int(vol[0]), channel) alsaaudio.ALSAAudioError: Volume must be between 0 and 100
関連記事:
関連URL:
- http://pyalsaaudio.sourceforge.net/ - pyalsaaudioの公式サイト
使用したバージョン:
- Python 2.5.2
- pyalsaaudio 0.3
*1:カードと番号の対応は/proc/asound/cardsなどで確認できる