pyAudioを使ってみました。


選択したオーディオデバイスにデータを書き込んで音を出したいな。。と思って少し探していたら、
pyAudioというものがあったので、試してみました。とりあえず、今回はWindows版で。
使い方はかなり簡単です。

サイト: http://people.csail.mit.edu/hubert/pyaudio/


上記のサイトから、自分のPythonのバージョンにあったインストーラをダウンロードしてきて、
インストールします。


インタプリタを起動して

import pyaudio

として、エラーにならなければ、準備完了です。

再生方法は、上記の本家サイトのサンプルの方法そのままです。
ただ、サンプルにはデバイスを切り替える方法などがかかれていませんね。


私は以下のような方法で実現しました。


(1) pyAudioインスタンスを生成
何はなくとも、まずpyAudioを生成します。

import pyaudio

aud = pyAudio.PyAudio()

(1) デバイス数の取得

cnt = aud.get_device_count()で取得できます。

(2) デバイス情報の取得

infoList = [aud.get_device_info_by_index(i) for i in range(cnt)]

infoListの要素は辞書になっていて、PortAudioのPaDeviceInfo構造体とほぼ同じ情報を持っています。
「ほぼ」と書いたのは、PaDeviceInfo構造体にはない(たしかなかったと思います)、'index'というキー
が追加されています。このindexはデバイスを特定する際のIDになっています。
'name'というキーで辞書の値を取り出せば、デバイス名文字列が得られるので、それを使ってコンボボックスなどを作成することができます。


(3) デバイスを指定してPyAudioのストリームを開く

stream = enc.open(....)

でストリームを開く際のオプション引数として、

output_device_index=インデックス # (2)で取得した辞書の'index'で得られる値

を渡すようにすればそのデバイスに対するストリームを開くことができます。


上記の手順で、無事pyAudioでWaveファイルを再生させることができました。


ただ、少しだけ気になることがありました。
(1) 複数のデバイスに対して再生を同時に行った場合、音飛びが発生する場合がある。
  まだ詳しくは調査していないのですが、PyAudioが非ブロッキングモードに対応していない
  ことが原因かもしれません。ブロッキングがデPyAudioインスタンス単位なのか、
  デバイス単位なのかストリーム単位なのか。。そのあたりを調べる必要がありそうです。


ブロッキングモードに対応しているオーディオモジュールとしてはfastaudioというものも
あるのですが、ライセンスが微妙。。。
「商用利用したい場合などは、連絡ください。検討します」といった内容のライセンスでした。