公開多重通道節點
在 Windows XP 之前的 Microsoft Windows 版本中,WDM 音訊驅動程式沒有簡化的方式來公開下列類型的多重通道節點:
特別是,明確查詢節點支援之通道數目的機制不存在。 雖然此問題有因應措施,但有缺點。 例如,用戶端可以使用 KSPROPERTY_AUDIO_VOLUMELEVEL 屬性反復查詢磁片區節點, (KSNODETYPE_VOLUME) 每個通道的磁片區層級--0、1 等等,直到要求傳回錯誤,指出沒有任何通道存在。 不過,這項技術需要多個查詢,而且處理較新的多重通道音訊裝置效率過低。 在 Windows XP 和更新版本的作業系統中,這項限制是藉由在KSPROPERTY_MEMBERSHEADER結構的Flags成員中定義兩個額外的旗標位,而屬性處理常式會輸出以回應基本支援查詢:
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL
在節點上的基本支援屬性要求期間,處理常式會將此旗標位設定為指出KSPROPERTY_MEMBERSHEADER MembersCount 成員包含節點支援的通道數目。 針對 Windows Vista 和更新版本的 Windows 作業系統,每個通道屬性都必須設定此旗標。
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM
處理常式會在這個旗標位與KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL旗標位之間執行位 OR,以指出單一屬性值會一致地套用到節點中的所有通道。 例如,如果硬體只為所有通道提供單一磁片區層級控制項,磁片區節點的基本支援處理常式會設定KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM旗標來指出這項限制。 如果未設定此旗標,則可以獨立控制每個通道的磁片區層級,而與其他通道的磁片區層級無關。
注意 Windows Vista 作業系統不會使用KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM旗標。
在 Windows XP 和更新版本的迷你埠驅動程式中,多重通道磁片區節點的屬性處理常式應該設定KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL位,以回應KSPROPERTY_AUDIO_VOLUMELEVEL基本支援查詢。 處理常式會針對 node 公開的每個通道傳回 KSPROPERTY_STEPPING_LONG 結構陣列,並將 MembersSize 設定為 sizeof (KSPROPERTY_STEPPING_LONG) 。 每個陣列元素都會描述通道的最小和最大磁片區層級,以及範圍中連續值之間的差異。 您可以為每個個別通道指定不同的範圍,以便正確公開具有非統一範圍的通道。 例如,子通道的範圍可能與其他通道的範圍不同。
下列程式碼範例示範如何處理具有非統 一屬性值之音訊屬性的基本支援查詢 。 下列第一行程式碼中的變數 pDescription 指向資料緩衝區開頭的 KSPROPERTY_DESCRIPTION 結構,處理常式會將基本支援資訊寫入其中:
//
// Fill in the members header.
//
PKSPROPERTY_MEMBERSHEADER pMembers = PKSPROPERTY_MEMBERSHEADER(pDescription + 1);
pMembers->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
pMembers->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
pMembers->MembersCount = ulNumChannels;
pMembers->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;
//
// Fill in the stepped range with the driver default.
//
PKSPROPERTY_STEPPING_LONG pRange = PKSPROPERTY_STEPPING_LONG(pMembers + 1);
pRange->Reserved = 0;
for (ULONG i=0; i<ulNumChannels; i++)
{
pRange[i].Bounds.SignedMinimum = ulChannelMin[i];
pRange[i].Bounds.SignedMaximum = ulChannelMax[i];
pRange[i].SteppingDelta = ChannelStepping[i];
}
pPropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
sizeof(KSPROPERTY_MEMBERSHEADER) +
ulNumChannels * sizeof(KSPROPERTY_STEPPING_LONG);
下圖顯示此範例的資料緩衝區配置。 pDescription、pMembers 和 pRange 指標會顯示在緩衝區內指向其各自的位移。
在此範例中,處理常式會將 MembersCount 設定為 ulNumChannels,也就是通道數目。 範圍陣列的位元組大小為
MembersSize * MembersCount
請注意,如果在此範例中設定KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM旗標,處理常式會將陣列中的所有KSPROPERTY_STEPPING_LONG結構設定為相同的範圍。
音調節點 KSPROPERTY_AUDIO_BASS、 KSPROPERTY_AUDIO_TREBLE或 KSPROPERTY_AUDIO_MID 屬性的基本支援處理常式會以類似的方式運作。
如果多重通道節點具有具有 BOOL 類型的每個通道屬性值的屬性,則基本支援處理常式必須填入逐步執行範圍陣列的值。 在此情況下,處理常式會將成員設定為下列程式碼範例中顯示的值。 這種類型的屬性的兩個範例是靜音節點 的KSPROPERTY_AUDIO_MUTE 屬性,以及音調節點 的KSPROPERTY_AUDIO_BASS_BOOST 屬性。
下列程式碼範例示範如何處理多重通道節點的基本支援要求,如果是具有 BOOL 類型之每個通道屬性值的屬性:
//
// Fill in the members header.
//
PKSPROPERTY_MEMBERSHEADER pMembers = PKSPROPERTY_MEMBERSHEADER(pDescription + 1);
pMembers->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
pMembers->MembersSize = sizeof (KSPROPERTY_STEPPING_LONG);
pMembers->MembersCount = ulNumChannels;
pMembers->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;
pPropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
sizeof(KSPROPERTY_MEMBERSHEADER) +
ulNumChannels * sizeof(KSPROPERTY_STEPPING_LONG);
//
// Fill in the stepped range with values in FOR loop.
//
PKSPROPERTY_STEPPING_LONG pRange = PKSPROPERTY_STEPPING_LONG(pMembers + 1);
pRange->Reserved = 0;
for (ULONG i=0; i<ulNumChannels; i++)
{
pRange[i].Bounds.SignedMinimum = 0;
pRange[i].Bounds.SignedMaximum = 1;
pRange[i].SteppingDelta = 1;
}
請注意,在上述程式碼範例中,FOR 迴圈會使用零 (0) ,以及一個 (1) 來設定每個通道範圍的最小值和最大值。 這是因為我們正在設定具有 BOOL 類型的每一通道屬性值的多通道節點。
如果通道屬性是一致的,可以在KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM旗標與KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL旗標之間執行位 OR 作業,以及指派給 pMembers-Flags > 成員的結果。 這個值是用來指出硬體會在節點中的所有通道上統一套用相同的屬性值。
使用 KSPROPERTY_MEMBER_FLAG_UNIFORM 和 KSPROPERTY_MEMBER_FLAG_MULTICHANNEL 旗標,就不需要將通道分組成對,並針對每一組通道公開個別的身歷聲音量節點,如同在 Windows 驅動程式套件 (WDK) 的 Ac97 範例驅動程式中所完成。 因為 Windows XP 之前的 Windows 版本不支援這些旗標,所以驅動程式的基本支援處理常式必須使用 IPortClsVersion 介面來查詢 Portcls.sys 版本,才能判斷是否使用這些旗標。
拓撲剖析器在核心模式 WDMAud 系統驅動程式中 (,Wdmaud.sys) 從其 WDM 音訊驅動程式取得音訊裝置的拓撲。 剖析器會透過舊版 Windows 多媒體混音器 API,將該裝置公開為傳統 混音器 裝置。 在 Windows XP 和更新版本中,WDMAud 會使用 KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL 旗標來決定在 MIXEDLINE 結構的 cChannels 成員中報告的通道數目。 此外,如果節點的基本支援處理常式指定KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM旗標,WDMAud 會在對應的 MIXERCONTROL 結構中設定MIXERCONTROL_CONTROLF_UNIFORM旗標。 透過此旗標,應用程式可以透過主要控制項,判斷它們是否可以個別調整每個通道或所有通道。 如需混合器CONTROL、MIXERLINE 和混音器API 的詳細資訊,請參閱Microsoft Windows SDK檔。
在 Windows XP 和更新版本中,SndVol32 磁片區控制程式 (請參閱 SysTray 和 SndVol32) 顯示多重通道裝置的控制項,如下圖所示。
如果 SndVol32 偵測到有兩個以上的通道的線條,它會將一般移動流覽控制項取代為標示為 [說話者音量] 的按鈕,該按鈕會出現在上圖的主音量滑杆上方。 按一下 [說話者音量 ] 按鈕會顯示一個對話方塊,其中顯示特定線條之所有通道的控制項,如下圖所示。
由於 混音器 API 會依編號公開通道,因此它會從目前在 Windows 多媒體控制台 (Mmsys.cpl) [ 進階音訊屬性 ] 對話方塊中選取的喇叭組態推斷通道名稱。
例如,如果裝置在一行上公開四個通道,且使用者已選取 「四次語音喇叭」,則通道名稱會是「左」 (通道 0) 、「右」 (通道 1) 、「上向左」 (通道 2) ,以及「右向右」 (通道 3) ,如下圖所示。 將喇叭設定變更為「環繞音效喇叭」會導致通道對應「Left」 (通道 0) 、「Right」 (通道 1) 、「Front Center」 (通道 2) 和 「Back Center」 (通道 3) 。
在驅動程式層級,KSPROPERTY_AUDIO_CHANNEL_CONFIG 屬性會分別使用遮罩值KSAUDIO_SPEAKER_QUAD或KSAUDIO_SPEAKER_SURROUND來代表四次語音或環繞喇叭組態。 標頭檔 Ksmedia.h 會定義下列值,如下所示:
#define KSAUDIO_SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define KSAUDIO_SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER)
其中一個遮罩包含四個位,可指定四個通道的喇叭位置。 不論是哪一種情況,KSPROPERTY_AUDIO_VOLUMELEVEL 屬性都分別識別這四個通道與通道 0、1、2 和 3 相同。
如果節點的基本支援處理常式設定KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM旗標位, 則 [說話者 音量] 對話方塊中顯示的滑杆會隨著對任何單一滑杆所做的變更而移動。