音频终结点生成器算法

在 Windows Vista 和更高版本的 Windows 中,AudioEndpointBuilder 是一种系统服务,用于枚举、初始化和激活系统中的音频终结点。 本主题概述了 AudioEndpointBuilder 服务使用的算法。

AudioEndpointBuilder 服务使用算法来发现和枚举终结点。 该算法旨在简化系统对多路复用 (MUXed) 捕获设备的访问权限,并帮助处理涉及多个主机引脚和多个桥接引脚或两者的拓扑。

在 Windows XP 中,音频模型使用术语音频设备来引用即插即用 (PnP) 树中的概念设备。 在 Windows Vista 和更高版本的 Windows 中,音频设备的概念经过重新设计,以更好地表示用户实际与之交互的设备。

借助 Windows Vista、MMDevice APIWASAPI 中的两个新 API,可以访问和操作这些新的音频设备。 MMDevice API 会将新的音频设备引用为终结点。

AudioEndpointBuilder 服务会监视设备接口到达和删除的 KSCATEGORY_AUDIO 类。 当音频设备驱动程序注册 KSCATEGORY_AUDIO 设备接口类的新实例时,AudioEndpointBuilder 服务会检测设备接口通知,并使用算法检查系统中音频设备的拓扑并采取适当的措施。

以下列表总结了 AudioEndpointBuilder 使用的算法的工作原理:

  1. 查找任何未连接的桥接引脚。

  2. 为任何未连接的桥接引脚创建终结点。 例如,当 AudioEndpointBuilder 找到具有 KSNODETYPE_SPEAKER 引脚类别 GUID 的未连接桥接引脚时,它将为此桥接引脚创建扬声器终结点。 有关 KSNODETYPE_SPEAKER 和其他引脚类别 GUID 的详细信息,请参阅 WinDDK\<build number>\inc\api 中的 Ksmedia.h。

  3. 设置终结点的默认属性。 例如,AudioEndpointBuilder 将设置名称、图标和外形规格。

  4. 确定是否有从终结点到主机引脚的路径,该主机引脚支持脉冲编码调制 (PCM)、音频编解码器-3 (AC3) 或 Windows 媒体视频 (WMV)。 主机引脚是 KSPIN 结构,其通信成员设置为 KSPIN_COMMUNICATION_SINK 或 KSPIN_COMMUNICATION_BOTH。 有关 KSPIN 结构的详细信息,请参阅 KSPIN

  5. 使用音频设备接口的注册表项中的属性信息填充终结点 PropertyStore。

  6. 设置终结点的状态。 终结点的状态可以是以下三个值之一:

    • 有效。 这表示路径存在,如步骤 4 中所述。

    • 已拔出。 如果音频设备支持插孔检测,则此状态指示终结点存在路径,并且已从音频适配器上的物理连接器中拔出插孔。

    • 不存在。 此状态指示在步骤 4 中未找到路径,并且此终结点不支持插孔检测。

  7. 如果这是关联 INF 文件中指定的内容,请将此终结点设置为默认终结点。

枚举终结点后,音频系统的客户端可以使用新的 Windows Vista API(如前面所示)直接或使用更熟悉的 API(如 Wave、 DirectShowDirectSound)间接直接操作它们。提供了新的 API 方法,以便音频客户端可以从终结点的 MMDevice ID 开始,并访问同一终结点的 Wave 或 DirectSound ID。

使用终结点时,可以利用以下内容:

  • 无论重启计算机的频率是什么,都可以使用相同的全局唯一 ID (GUID)。 拥有此持久 GUID 比保存终结点的 waveOut ID 或友好名称更可靠。

  • 无论重启计算机的频率是什么,都可以使用同一 PropertyStore。 音频设备相关的元数据保存在终结点 PropertyStore 中。

  • AudioEndpointBuilder 服务会自动管理和枚举多路复用 (MUX) 和解多路复用 (DEMUX) 的引脚。

如果开发自己的音频设备驱动程序和 INF 文件来处理音频设备,并且开发音频应用程序,或者同时开发两者,最好注意以下问题和最佳做法。 在考虑到这些建议的情况下开发驱动程序和应用程序时,会生成能够更有效地使用 AudioEndpointBuilder 的驱动程序、INF 文件和音频客户端。

  • 命名约定。 用于终结点的命名约定基于桥接引脚的友好名称。 但是,对于扬声器终结点,该名称已硬编码为“扬声器”,因此不能由驱动程序或第三方应用程序更改。

  • 欠佳拓扑。 由于 AudioEndpointBuilder 用于枚举终结点的算法,某些拓扑会被视为欠佳。 例如,创建这些欠佳拓扑之一时,会创建具有隐藏终结点的主机引脚,并且无法由 AudioEndpointBuilder 或拆分器(拆分终结点)看到,AudioEndpointBuilder 无法将此类引脚链接到其关联的主机引脚。

    • 隐藏的终结点

      在下图中,KS 筛选器显示为具有两个连接到单一桥接引脚(扬声器)的主机引脚。

      Diagram showing problematic topology with AC-3 host pin and hidden endpoint on left side, individual PCM and AC-3 sharing single filter.

      当 AudioEndpointBuilder 发现此桥接引脚时,它会跟踪一个路径,仅跟踪回到其中一个主机引脚,设置桥接引脚的默认值,创建并激活扬声器终结点,并继续发现其他桥接引脚。 因此,其他主机引脚在 AudioEndpointBuilder 中仍处于隐藏状态。

      Diagram illustrating recommended topology with traceable paths between host pins and endpoints.

      在上图中,已重新设计有问题的拓扑,以便 AudioEndpointBuilder 可以发现两个主机引脚(PCM 和 AC-3/PCM),因为它现在可以看到两个桥接引脚(扬声器和 SPDIF)。

    • 拆分器

      当一个主机引脚连接到多个桥接引脚时,会创建另一种类型的欠佳拓扑。 下图显示了 PCM 主机引脚连接到扬声器桥接引脚和 SPDIF 桥接引脚的拓扑。

      Diagram depicting problematic topology with two endpoints connected to one host pin and single PCM.

      在这种情况下,AudioEndpointBuilder 会发现一个桥接引脚,并跟踪路径,直到回到 PCM 主机引脚,设置默认值,然后创建并激活扬声器终结点。 在 AudioEndpointBuilder 发现下一个桥接引脚时,它会跟踪路径,直到回到同一 PCM 主机引脚,设置默认值,然后创建并激活 SPDIF 终结点。 但是,尽管两个终结点都已初始化并激活,但流式传输到其中一个终结点使得无法同时流式传输到另一个终结点:换言之,它们是互斥的终结点。

      下图显示了此拓扑的重新设计,其中存在单独的连接。 这种设计使 AudioEndpointBuilder 能够针对两个桥接引脚中的每一个引脚跟踪路径,直到回到 PCM 主机引脚。

      Diagram illustrating recommended topology with traceable paths between host pins and endpoints, featuring two PCMs on the left side.

  • 终结点格式。 当音频引擎在共享模式下运行时,终结点的格式在安装时采用由 INF 文件指示的特定设置。 例如,音频设备的音频驱动程序使用其关联的 INF 文件,将默认终结点设置为 44.1-kHz、16 位立体声 PCM 格式。 安装后,必须使用控制面板或第三方应用程序来更改终结点格式。

  • 默认设备。 使用 INF 文件中的信息在安装时选择设置为默认设备的终结点。 安装完成后,必须使用控制面板或第三方应用程序选择另一个终结点作为默认终结点。

注意 如果 INF 文件未在安装过程中选择要设置为默认值的终结点,客户端应用程序可以使用 MMDevice API 来选择终结点。 API 根据外形规格排名以及终结点是呈现终结点还是捕获终结点来进行选择。 下表显示了选择顺序。

呈现排名 捕获排名
扬声器 Microphone
线路输出 线路输入
SPDIF SPDIF

如果使用 MMDevice API 选择默认终结点,并且可用终结点排名相同,则 MMDevice API 将按字母顺序排列终结点 ID,以确定要选择为默认值的终结点。 例如,如果音频适配器同时具有线路输出连接器和线路输入连接器,并且关联的 INF 文件在安装时未选择其中一个作为默认值,则 MMDevice API 会标识按字母顺序排列的终结点 ID,并将该连接器设置为默认值。 重启系统后,此选择将保持不变,因为终结点 ID 可持久。 但是,如果系统中出现排名较高的终结点(例如,具有麦克风连接器的第二个适配器),则选择不会持久。