わたしも少しまえにWindows 7のパソコンを新調して使ってます。わたしの場合はPhotoshopなんかも使うのでメモリを12GBいれてるので64bit OSを使ってます。オーディオ環境も整えつつありますが、音はXPに比べてかなり良いです。パソコン自体の性能も違うんで単純比較できませんけど、XPのときにあったASIOでも取れない妙な曇り感はかなり薄れました。WASAPIを使うとさらに透明感は増します。Mac OSXとも十分比肩できるプラットフォームになってると思います。
WindowsはVistaで大きく進化しましたけど、オーディオ周りもそのときに見直しされてます。このWASAPIもそのひとつで、Core Audioと呼ばれるOSのオーディオ周りの新アーキテクチャの一部です。
とはいえWASAPI自体はよく比較されるASIOとはちょっと違います。わたしも混同していたところもあるので、少し整理したいと思います。
*この記事のソースは主にMSDNのCore Audio API解説です。
1. WASAPIとは
よくASIOと比較されるのですが、WASAPIはドライバーではありません。前に書いたようにWindows7はマイクロカーネル的な考えで設計されているので、本当にハードにくっつくドライバー以外はOS付属の機能といえどユーザーモードで動作します。
*ちなみにVista/7のオーディオエンジン(XPのカーネルミキサー)はユーザーモードで動きますが、アプリケーションとは別に保護されているようですので、厳密にユーザーアプリと同じではありません。
それではWASAPIとはなにをするものか、と言うことですが、これは名前を見てみると良いかもしれません。
WASAPIはWindows Audio Session APIの略です。つまりWindows Vista/7で加わった「オーディオセッション」というCore Audioの概念を統括するソフトウエア群です。
オーディオセッションと言うのは複数の「オーディオストリーム」を束ねて抽象化する概念です。オーディオストリームとはつまりミュージックプレーヤーからドライバーへの音楽データ(オーディオサンプル)の流れと言って良いでしょう。
オーディオセッションの役割ということで、例をあげてみます。
一口にミュージックプレーヤーと言っても実体は複数のプロセス(プログラムの単位)から成り立っています。例えば楽曲ファイルが著作権保護されていた場合、音楽再生するプロセスとは別に保護解除するプロセスが必要になります。しかしそれぞれ別個のプロセスから出たオーディオストリームが別だと音量がばらばらになってしまうかもしれません。それらのオーディオストリームを同じ作業の単位ということでまとめれば、ボリュームなど変更を等しく適用できます。それがオーディオセッションです。
つまりこの場合ボリュームの適用は個々のオーディオストリームではなく、オーディオセッションに対して適用されることになります。
それではよく言われるWASAPIを使うとレイテンシーが小さくて音が良い、と言うのはどういうことかと言うことですが、ここで排他モードと共有モードと言う言葉が出てきます。ここでは前のMSDNのブログに関する記事もご覧ください。
またこちらにPCオーディオファン2の図の元が有ります。
http://msdn.microsoft.com/en-us/library/dd316780(VS.85).aspx
2. 排他モードと共有モード
簡単にまとめると、排他モードのときはオーディオストリームの行き先はドライバー(エンドポイント)に直結されます。さらにドライバーへのデータの受け渡しはCPUを介さないDMA(Direct Memory Access)によるマッピングで行われるため、レイテンシーも最小に出来ます。ビットパーフェクトの保障ができるのもこの経路と「理想的な」ドライバーを組み合わせたときです。
よりよい音を求めるときのモードといえます。
共有モードのときはストリームの行き先はいったんオーディオエンジンになります。オーディオエンジンで他のアプリの音とミックス(つまり共有)されたあとにドライバにいきます。ここはXPではカーネルミキサーと呼ばれていたところです。
オーディオエンジンとドライバーはやはりDMAによるマッピングで直結されています。オーディオエンジンはWindows7ではVistaからさらに低レイテンシーに改良されているようです。
より自由な使い方を求めるときのモードといえます。
排他モードと共有モードの違いでレイテンシーの他はフォーマットもあります。
排他モードではPCMでなくても出力できます。DSDなどは排他モードで出せそうです。
共有モードではPCMでなければなりません。これはWASAPIではなく、経路に挟まるオーディオエンジンがPCMでなければ処理できないという制限です。
それではこの排他とか共有というモードはどこでどうやって決めるのでしょうか?
それについてもう少し深く見て行きます。(以後はプログラミング解説的な内容になります)
まず排他モードと言うのはどの単位のモードの設定なのかというと、オーディオストリーム単位です。オーディオストリームを初期化するモードが排他モードか共有モードになります。ファイルをオープンするときに読み書きのモード指定するような感じだと思います。
さきほどはWASAPIの概念的な定義を書きましたが、WASAPIの実体はWindows7でのオーディオストリームを作成管理する一連のプログラミング・インターフェイスです。下記ページに記載されているものです。
http://msdn.microsoft.com/en-us/library/dd371455(VS.85).aspx
これらのインターフェイスでCore Audioで加わったオーディオ周りの動作を規定するわけです。
例えば具体的にこちらのページに排他モードでオーディオストリームを作成するプログラムの例が乗っています。
http://msdn.microsoft.com/en-us/library/dd370844(VS.85).aspx
なかほどの"pAudioClient->Initialize()"でpAudioClientオブジェクトに対してInitialiseメソッドを適用しますが、ここでオーディオストリームを排他モードで初期化しているのが分かります。
第一引数"AUDCLNT_SHAREMODE_EXCLUSIVE"が列挙型で排他モードを意味しています。共有モードで初期化する時は"AUDCLNT_SHAREMODE_SHARED"になります。また最後の引数はNullですが、ここはセッションGUIDというこのストリームが属すべきオーディオセッションのIDです。これがNullと言うことはどれにも属さないということです。
Initializeメソッドに関しては下記に詳しい解説が有ります。
http://msdn.microsoft.com/en-us/library/dd370875(VS.85).aspx
ここでさきの排他モードと共有モードの列挙型が記載されてます。
AudioClientというクラスはアプリケーション(ミュージックプレーヤー)とオーディオデバイスをとりもつ役割をします。
http://msdn.microsoft.com/en-us/library/dd370865(VS.85).aspx
先のコードの少し上をみるとpAudioClientの対象の出力デバイスはデフォルトデバイスということがわかります。pDevice->ActivateのところでpAudioClientとのリンクがなされています。このデバイスで排他モードが使えるのかというのは、この例ではその下のGetStreamFormat関数の中で確認してます。
つまり排他モードとか共有モードというのはデバイス側のプロパティなどで決定するのではなく、あくまでアプリケーション側が明示的に宣言することで決められるということです。
3. デバイス設定
一方でデバイス側では、サウンド設定からデバイスプロパティで下記の様な共有モードと排他モードの設定ができます。これはWavelength Protonの例です。
二つある排他モードの設定の上の方がこのデバイスで排他モードを許すという設定です。ただし排他モードを決めるのは上で書いたようにあくまでWASAPIを利用したアプリケーションなので、ここで設定したからといって排他モードになるわけではありません。
共有モードの設定はオーディオエンジンの設定と考えた方が良いでしょう。
共有モードではさまざまなアプリケーションからのオーディオストリームを混ぜるので、オーディオストリームのサンプリングレートが異なるときには統一せねばなりません。
XPのカーネルミキサーでは48KHz固定だったこの統一サンプルレートを、Windows7ではここでデバイスから取得した値にいろいろと可変できるということです。
またProtonではアプリケーションに基本24bitでの出力を要求していることがわかると思います。ちなみにこれがiPadがProtonでは動かない原因と考えられます。(iPadは16bitしか出せないため)
もうひとつポイントとしてここでは88KHz/24bitの設定が抜けています。これはWindows7の問題です。(PCオーディオファン2のP205参照)
ただし排他モードではどのみちこの設定は意味がないので、88KHzがここで抜けているからといってWindows7では88KHzが使えないというわけではありません。
たとえばFoobar2000のリサンプラーできれいにx2で整数倍アップサンプリングをして、44.1を88.2で出したい(DACに渡したい)というときは、排他モードで出せばよいわけです。排他モードにすれば共有モードで設定してあるサンプルレートは無視されます。
共有モードにした場合は上のダイアログでセットされた値にリサンプルされます。また共有モードの場合は仮にここでセットした値と同じサンプリングレートでプレーヤーから出したとしてもビットパーフェクトは期待できないと思います。
4. WASAPIの実際のプレーヤーでの使用例
下の図はFoobar2000でWASAPIコンポーネントを入れた場合の出力先の選択を示しています。
DS(DirectSound)経由かWASAPIかをそれぞれのデバイスで選べます。現在Proton(USB DAC)とBridge(USB DDC)が接続されています。
DirectSound経由の場合はサウンドエンジン経由、つまり共有モードに設定されます。この場合はリサンプラーをFoobar側で使ってもどのみちオーディオエンジンでさらにリサンプルされるのでアプリ側でのリサンプルは不要(二度手間)に思えます。
またWASAPIコンポーネントも中では排他モードでしか初期化していないようです。たとえばデバイスプロパティで排他モードのチェックをはずして排他モードを使えなくするとエラーで再生できなくなります。
このときに排他モードで開けてエラーならば、共有モードで初期化するという手も本来あるはずですがそれはしていないようです。まあそれはDSを使用してくれ、ということでしょうけれども、WASAPIでの共有モードの音も聴いてみたいとは思いますね。
ちょっと長くなりましたが、Windows 7のオーディオプラットフォームとしての能力は高いと思うし、Windowsはアプリケーションの選択も多いのでうまく使いこなしていきたいと思います。
Music TO GO!
2010年07月10日
この記事へのトラックバック
PCオーディオへの取組み(40) WASAPI
Excerpt: 40.uLilithでWASAPIを試行
Weblog: 落花流水【 愛燦々と! 】
Tracked: 2010-12-15 10:34