PKEY_AudioEngine_OEMFormat

在 Windows Vista 及更高版本中,PKEY_AudioEngine_OEMFormat 属性键标识音频终结点设备的默认流格式。 呈现和捕获设备都具有默认格式。 全局音频引擎使用设备的默认格式连接到设备进行共享模式操作。 安装设备的 INF 文件会将设备的默认格式加载到注册表中。 用户可以通过 Windows 多媒体控制面板 (Mmsys.cpl) 更改默认格式。 Windows XP 和早期版本的 Windows 不支持 PKEY_AudioEngine_OEMFormat 属性键。

INF 文件指定该设备的 add-registry 部分中音频终结点设备的默认格式。 以下 INF 示例显示了一个 add-registry 部分,该部分会将终结点设备的默认格式加载到注册表中。

;;
;; Identify endpoint device as a set of speakers.
;; Set default format to 48-kHz, 16-bit stereo.
;; Add endpoint extension property page.
;;
[OEMSettingsOverride.AddReg]
HKR,"EP\\0", %PKEY_AudioEndpoint_Association%,,%KSNODETYPE_SPEAKER%
HKR,"EP\\0", %PKEY_AudioEngine_OEMFormat%, %REG_BINARY%, 41,00,00,00,28,00,00,00,
 FE,FF,02,00,80,BB,00,00,00,EE,02,00,04,00,10,00,16,00,10,00,03,00,00,00,01,00,
 00,00,00,00,10,00,80,00,00,AA,00,38,9B,71
HKR,"EP\\0", %PKEY_AudioEndpoint_ControlPanelProvider%,,%AUDIOENDPOINT_EXT_UI_CLSID

前面的示例取自 Windows 驱动程序工具包中 Sysfx 音频示例中的 Sysfx.inf 文件。 此 INF 文件的 Strings 部分包含以下定义。

PKEY_AudioEndpoint_ControlPanelProvider = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},1"
PKEY_AudioEndpoint_Association          = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioEngine_OEMFormat              = "{E4870E26-3CC5-4CD2-BA46-CA0A9A70ED04},3"

在前面的示例中,add-registry 部分的名称 OEMSettingsOverride.AddReg 由 Sysfx.inf 的接口安装部分中的 AddReg 指令定义。 前面的示例将终结点编号 0(由字符串“EP\\0”标识)的多个属性添加到设备接口的注册表项。 (如果设备接口表示具有多个终结点的波次筛选器,则附加终结点编号为 1、2 等。)有关接口安装部分的详细信息,请参阅 INF AddInterface 指令

INF 文件创建三个属性键并将关联值加载到注册表后,应用程序可以获取终结点设备的 IPropertyStore 接口,以访问这些属性。 Windows SDK 中的标头文件 Mmdeviceapi.h 包含三个属性键的 C/C++ 定义。 有关获取 IPropertyStore 接口的详细信息,请参阅 Windows SDK 文档中的 IMMDevice::OpenPropertyStore 方法描述。

在前面的 INF 示例中,PKEY_AudioEndpoint_Association 属性键标识终结点设备的 KS 引脚类别 GUID。 PKEY_AudioEndpoint_ControlPanelProvider 属性键标识 COM 接口对象的类 GUID,该对象在终结点设备的Mmsys.cpl 中为属性页提供属性值。 有关这些属性键的详细信息,请参阅 Windows SDK 文档。 有关 KS 引脚类别 GUID 的详细信息,请参阅引脚类别属性

在前面的 INF 示例中,与 PKEY_AudioEngine_OEMFormat 属性键关联的属性值是一个 48 字节 REG_BINARY 值,其中包含描述格式的 WAVEFORMATEXWAVEFORMATEXTENSIBLE 结构的序列化表示形式。 若要计算要与 PKEY_AudioEngine_OEMFormat 属性键关联的 REG_BINARY 数据值,请在 PropVariant 结构中嵌入 WAVEFORMATEXWAVEFORMATEXTENSIBLE 结构,并调用 StgSerializePropVariant 函数来序列化 PropVariant 结构。 有关 PropVariant 结构和 StgSerializePropVariant 函数的详细信息,请参阅 Windows SDK 文档。

以下代码示例是一个控制台应用程序,用于打印在前面的 INF 示例中显示的 REG_BINARY 数据。

//
// Embed a WAVEFORMATEXTENSIBLE structure in a PropVariant
// container, and print the PropVariant structure as a
// serialized stream of bytes in REG_BINARY format.
//

#include <stdio.h>
#include <wtypes.h>
#include <propidl.h>
#include <propvarutil.h>
#include <mmreg.h>
#include <ks.h>
#include <ksmedia.h>

void PrintSerializedFormat(WAVEFORMATEX *pWfx)
{
    HRESULT hr;
    PROPVARIANT var;
    SERIALIZEDPROPERTYVALUE* pVal;
    ULONG cb;

    // Create a VT_BLOB from the WAVEFORMATEX structure.
    var.vt = VT_BLOB;
    var.blob.cbSize = sizeof(*pWfx) + pWfx->cbSize;
    var.blob.pBlobData = (BYTE*)pWfx;

    // Serialize the PROPVARIANT structure. The serialized byte stream
    // will eventually be written to the registry as REG_BINARY data.
    hr = StgSerializePropVariant(&var, &pVal, &cb);
    if (SUCCEEDED(hr))
    {
        // Write the binary data to stdout. Format the output so you can
        // copy and paste it directly into the INF file as REG_BINARY data.
        for (UINT i = 0; i < cb; i++)
        {
            BYTE b = ((BYTE*)pVal)[i];
            wprintf(L"%2.2X,", b);
        }

        wprintf(L"\n");
        CoTaskMemFree(pVal);
    }
}

//
// Use a WAVEFORMATEXTENSIBLE structure to specify the format
// for a 48-kHz, 16-bit, (2-channel) stereo audio stream.
//
void main()
{
    WAVEFORMATEXTENSIBLE wfx;

    wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
    wfx.Format.nChannels = 2;
    wfx.Format.nSamplesPerSec = 48000;
    wfx.Format.nAvgBytesPerSec = 4*48000;
    wfx.Format.nBlockAlign = 4;
    wfx.Format.wBitsPerSample = 16;
    wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
    wfx.Samples.wValidBitsPerSample = 16;
    wfx.dwChannelMask = 3;
    wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

    PrintSerializedFormat(&wfx.Format);
}

前面代码示例中的主函数将创建一个 WAVEFORMATEXTENSIBLE 结构来描述默认格式。 可以修改主函数以创建 WAVEFORMATEXWAVEFORMATEXTENSIBLE 结构,以描述终结点设备的默认格式。

前面代码示例中的 PrintSerializedFormat 函数可序列化格式描述,并将序列化格式描述打印为 REG_BINARY 数据。 可以复制函数生成的打印输出并将其粘贴到 INF 文件中。