NAudio ライブラリでオーディオを再生する(5)


前回から少し時間が経ってしまいました。というのも、capture、loopback、render のテストをやって、やはり Core Audio API の Endpoint をもう少し理解しておかないと先に進めないということで、テストプログラムを書いては動かしていました。正月はそれで終わったといってもいいでしょう。

なお、今回のコードは Windows Vista では動かないかもしれません。Windows 7 なら大丈夫だと思います。

サウンドの設定を理解する

mmDevice3まず、サウンド設定でいじれるところを確認しておきましょう。再生側でも録音側でも、レベルの設定、ミュートがあり、「バランス」のボタンを押すと、LR 独立したレベル調整があります。これらをプログラムから監視・変更できるはずです。そのあたりに注目してみます。それ以外にもサウンドドライバ固有の各種設定もあるようですが、今回はそこまでは確認できませんでした。でも、レベル調整とミュート、それにレベルメーターの機能が使えればそれで十分です。

mmDevice4

NAudio.CoreAudioApiを調べる

NAudio.CoreAudioApi.AudioEndpointVolume に注目すると、次のようなプロパティが見つかります。

AudioEndpointVolume.VolumeRange.MinDecibels [get]
音量調整の最小値(dB)
AudioEndpointVolume.VolumeRange.MaxDecibels [get]
音量調整の最大値(dB)
EEndpointHardwareSupport
音量、ミュート、メーターをハードウェアでサポートしているか、ソフトウェアか
AudioEndpointVolume.Channels[].VolumeLevel
チャンネルごとの音量(dB)
AudioEndpointVolume.Channels[].VolumeLevelScalar
チャンネルごとの音量(0~1)
float MasterVolumeLevel [get, set]
マスター音量(dB)
float MasterVolumeLevelScalar [get, set]
マスター音量(0~1)
bool Mute [get, set]
ミュートのオン・オフ

よく見ると、デシベルとリニアが2種類用意されてます。それから、他のプログラムがこれらを変更したときの通知もあります。

AudioEndpointVolumeNotificationDelegate
OnVolumeNotification(AudioVolumeNotificationData data)

この AudioVolumeNotificationData data にも、マスター音量やチャンネルごとの音量が含まれていますが、これらはすべてリニア値(0~1)のようです。通知を受けたら、上記のデシベル値を参照したほうが処理しやすそうです。

それから、レベルメーターですが、NAudio.CoreAudioApi.AudioMeterInformation にマスター、LRともにメーターのピーク値があります。これらは、リニア値(0~1)です。このピークメーターがどのような間隔で処理されているのかわかりませんが、タイマーで一定間隔ごとに監視すれば十分でしょう。

エンドポイントのパラメータを表示する

以上のことがわったところで、エンドポイントの監視をおこなうプログラムを書きます。まず、エンドポイントに相当するユーザコントロールを作成します。エンドポイントの名称、音量ボリューム(マスター、L、R)、ミュート(ミュートはマスターしかない)レベルメーター(マスター、L、R)に加えて、情報を書きだす TextBox も用意しました。

mmDevice-usercontrol

メインのフォームで、MMDeviceEnumerator を使ってエンドポイントを入力、出力それぞれ列挙して、ユーザコントロール mmDevicePanel を初期化していき、フォーム上に並べています。

mmDevice1

実行して見ると、たしかにサウンドのレベルを動かしても反映しますし、このテストプログラムで音量を動かすとサウンドのレベルも変化します。レベルメーターも動いているようです。

いろいろ試してみると、エンドポイントはこんな感じの構造であることが分かりました。出力(Render)側では、レベルメーターは音量調整の前から取られていること、マスター音量とL、Rはハードウェアによっては連動していたり独立しています。入力側では逆に音量調整の後にレベルメーターが入っています。

endpoint-image

レベルメーターが実際に出力している値を表さないのは一見すると不便なようですが、ミュート状態と音量は把握しているわけですから、掛け算するだけです。ただ、逆に入力側が音量調整の前のデータではないのは残念ですね。このあたりもう少しという感じでしょうか。

いずれにしても、エンドポイントの使い方、構造がなんとなく見えてきました。まだ調べていないこともありますが、今回のテストプログラムを基礎にすればだんだんと解明できそうな気がしてきました。

なお、この過程で2回ほどテストプログラムを作りなおして、2日ほど費やしました。説明はさらりと済ませてしまいましたが、ソースコードには苦労の跡が残っていますので、興味のある方はぜひご覧ください。

load_download mmDeviceTest2.zip

参考

  • About the Windows Core Audio APIs (Windows)
    http://msdn.microsoft.com/ja-jp/library/windows/desktop/dd370784%28v=vs.85%29.aspx
  • Core Audio インタフェース(mikeo_410)
    http://mikeo410.lv9.org/lumadcms/~programmingcoreaudiointerface
  • Core Audio APIをC#から使う(こけし出張所)
    http://d.hatena.ne.jp/hirekoke/20120608/p1

You can skip to the end and leave a response. Pinging is currently not allowed.
Subscribe to RSS Feed Twitter は Ume108 だよ