PCM 以外のサポートの背景
以前のバージョンの Microsoft Windows では、いくつかの問題により、waveOut API と DirectSound API を介して非 PCM の形式をサポートできませんでした。 これらの問題とその解決方法について、以下で説明します。
waveOut API
WaveOut アプリケーションと VxD ウェーブ ドライバーを分離するソフトウェア レイヤーは、かなり薄いレイヤーです。 カスタム ウェーブ形式をサポートするドライバーとアプリケーションは、オペレーティング システムがその形式を認識しているかどうかに関係なく、その形式でデータをストリーミングできます。
ただし、Windows 2000 および Windows 98 では、WDM オーディオ フレームワークにより、waveOut API (および DirectShow の waveOut レンダラー) によって処理されるすべてのオーディオ データが、カーネル オーディオ ミキサーである KMixer システム ドライバー (Kmixer.sys) を通過するように強制されます。 waveOutOpen 呼び出しは、ドライバーが形式をサポートしているかどうかに関係なく、KMixer が形式をサポートしている場合にのみ成功します。
KMixer は、すべての WDM オペレーティング システムで WAVE_FORMAT_PCM を処理します。 Windows 2000 以降および Windows 98 Standard Editionでは、WAVE_FORMAT_IEEE_FLOAT だけでなく、PCM 形式および IEEE 浮動小数点形式の WAVEFORMATEXTENSIBLE バリアントもサポートするように KMixer を拡張します。 KMixer は非 PCM 形式をサポートしていないため、KMixer を介して PCM 以外のデータを渡そうとすると失敗します。
Windows では、PCM 以外のオーディオ データが単純に KMixer をバイパスすることで、非 PCM 形式がサポートされています。 具体的には、waveOut の非 PCM データは、最初に KMixer を通過するのではなく、PortCls (または USBAudio) に直接流れます。 非 PCM データのミキシングはハードウェアで行う必要がありますが、AC-3 や WMA Pro などの形式で非 PCM データを使用するアプリケーションでは通常、ミキシングは必要なく、ドライバーは通常、その形式でのハードウェアでのミキシングをサポートしていません。
DirectSound API
従来の waveOut ドライバーと VxD ドライバーでは、DirectSound は、1 次バッファーと 2 次バッファーの両方で WAVEFORMATEX (ただし、WAVEFORMATEXTENSIBLE は除く) PCM 形式をサポートし、サンプルあたり 8 ビットまたは 16 ビット、1 つまたは 2 つのチャンネル、100 Hz から 100 kHz のサンプリング レートを備えています。 VxD ドライバーは、協調レベルが DSSCL_WRITEPRIMARY に設定されている場合に、プライマリ バッファーに許可される形式をさらに制限できます (DirectX SDK の IDirectSoundBuffer::SetFormat メソッドの説明を参照)。 これらの制限は、Windows Me または Windows XP では変更されていません。
WDM ドライバーは、WAVEFORMATEX 形式と WAVEFORMATEXTENSIBLE 形式の両方で PCM 形式をサポートできます。 Windows 2000 以降、Windows Me、および Windows 98 Standard Edition の場合、ドライバーは、WAVE_FORMAT_IEEE_FLOAT 形式をプライマリとセカンダリの DSBCAPS_LOCSOFTWARE バッファ (KMixer によってミックスされる) に対して、WAVEFORMATEX と WAVEFORMATEXTENSIBLE の両方の形式でサポートすることもできます。
SetFormat を呼び出してプライマリ バッファーのデータ形式を指定すると、サウンド カードによって選択された最終的なミキシング形式にのみ間接的な影響が及びます。 プライマリ バッファー オブジェクトは、IDirectSound3DListener インターフェイスを取得し、デバイスのグローバル ボリュームとパンを設定するために使用されますが、サウンド カードからの単一の出力ストリームは表しません。 代わりに、KMixer は、複数の DSSCL_WRITEPRIMARY DirectSound クライアントを同時に実行できるように、プライマリ バッファー データをミックスします。
Windows 2000 および Windows 98 では、DirectSound は PCM データのみをサポートします。 (DirectSound のレンダラーを使用する DirectShow の場合も同じです。) 非 PCM 形式の CreateSoundBuffer の呼び出しは、ドライバーが形式をサポートしている場合でも、常に失敗します。 エラーは 2 つの理由で発生します。 まず、DirectSound は KS ピンを作成するたびに、IDirectSoundBuffer オブジェクトの作成に使用される WAVEFORMATEX 構造体の wFormatTag メンバーからサブタイプを派生させる代わりに、KSDATAFORMAT_SUBTYPE_PCM を自動的に指定します。 次に、DirectSound では、クライアントが DirectSound バッファーのパン、ボリューム、または周波数コントロールを要求するかどうかに関係なく、すべてのデータ パスにボリューム ノードと SRC (サンプル レート変換) ノード (KSNODETYPE_VOLUME と KSNODETYPE_SRC) が必要です。 この要件は、データが KMixer を通過するか、デバイスがハードウェア ミキシングを実行する場合に満たされます。 ただし、非 PCM 形式の場合、KMixer はデータ パスに存在せず、ドライバー自体は通常、ハードウェアでのミキシングを実行するように求められたときに失敗します。
Windows XP 以降と Windows Me では、DirectSound アプリケーションで非 PCM 形式が使用されるのを妨げる制限事項は削除されます。 DirectSound 8 (以降のバージョン) では、正しい形式のサブタイプが使用され、すべてのデータ パスにボリューム ノードと SRC ノードが自動的に要求されることはなくなりました。