拓扑筛选器

拓扑筛选器表示音频适配器上的线路部分卡,用于处理在卡上管理的各种波形和 MIDI 流之间的交互。 此线路会混合呈现流和捕获流的多路复用。

拓扑筛选器提供网桥引脚(请参阅音频筛选器图),这些图钉表示音频适配器与外部设备的物理连接。 这些连接通常携带模拟输出信号,这些信号驱动扬声器和来自麦克风的模拟输入信号。 拓扑筛选器的网桥引脚也可能表示模拟线路和线出插孔,甚至可能表示数字输入和输出连接器。

术语“拓扑筛选器”从某种意义上说是误用。 尽管其名称如此,但拓扑筛选器只是公开其内部拓扑或布局的几种音频筛选器之一。 尽管拓扑筛选器包含关键拓扑功能,但它不一定包含适配器的整个拓扑。 波形和 MIDI 筛选器具有自己的拓扑。 例如,最小 WaveCyclic 或 WavePci 筛选器(请参阅 波形筛选器)可能会公开一个拓扑,该拓扑由两个引脚和一个 DAC(数字到模拟转换器)或 ADC(模拟到数字转换器)组成,具体取决于基础设备是执行音频呈现还是捕获。

拓扑筛选器作为端口/微型端口对实现。 拓扑筛选器工厂创建拓扑筛选器,如下所示:

  • 它实例化拓扑微型端口驱动程序对象。

  • 它通过调用具有 GUID 值的 PcNewPort 来实例化拓扑端口驱动程序对象CLSID_PortTopology

  • 它调用端口驱动程序的 IPort::Init 方法,将微型端口驱动程序绑定到端口驱动程序。

Subdevice Creation 中的代码示例演示了此过程。

拓扑端口和微型端口驱动程序通过各自的 IPortTopology 和 IMiniportTopology 接口相互通信。 与波形和 MIDI 端口和微型端口驱动程序相比,这些接口相对简单,因为拓扑筛选器不需要显式管理通过引脚传递的流。 拓扑筛选器的引脚表示适配器硬件中的硬连接。 拓扑筛选器引脚基础的物理连接通常携带模拟音频信号,但可能会转而携带数字音频流,具体取决于硬件实现。

与 IMiniportWaveCyclicIMiniportWavePciIMiniportMidiIMiniportDMus 接口相比,IMiniportTopology 接口没有 NewStream 方法。

拓扑筛选器的大部分功能都由其属性处理程序提供。 拓扑筛选器主要是为了向 SysAudio 系统驱动程序和使用 Microsoft Windows 多媒体混音器 API 的应用程序提供拓扑信息。 拓扑筛选器中的属性处理程序提供对音频适配器通常提供的各种控件(例如音量、均衡和混响)的访问权限。 通过属性请求,混音器 API 可以枚举适配器硬件中的控制节点、发现节点之间的连接,以及查询和设置节点的控制参数。 SndVol32 应用程序(请参阅 SysTray 和 SndVol32)使用混音器 API 发现适配器的每流卷和静音控件。

生成筛选器图时,SysAudio 在其引脚上查询KSPROPERTY_PIN_PHYSICALCONNECTION属性的拓扑筛选器,以确定哪个波形、MIDI 或 Direct音乐筛选器引脚连接到哪个拓扑筛选器引脚。

与波形、MIDI 或 Direct音乐 筛选器不同,拓扑筛选器不会实例化引脚。 因此,没有引脚对象可用于处理拓扑筛选器的引脚属性的查询。 拓扑筛选器本身处理有关其引脚上物理连接的所有查询。 有关详细信息,请参阅 KSPROP标准版TID_Pin

与其他类型的音频筛选器类似,拓扑筛选器使用PCCONNECTION_DESCRIPTOR结构的数组来描述其内部拓扑。 微型端口驱动程序在从 IMiniport::GetDescription 方法输出的PCFILTER_DESCRIPTOR结构中公开此数组。 该数组将拓扑指定为拓扑筛选器节点和引脚之间的连接列表(请参阅节点和连接)。 WDMAud 系统驱动程序将这些连接和节点转换为混音器行,以及混音器 API 向应用程序公开的控制。 如音频筛选器中所述 ,KS 筛选器上的输入引脚映射到 SRC 混音器线,筛选器上的输出引脚映射到 DST 混音器线。

典型的音频适配器可以通过扬声器播放波形和 MIDI 文件,并且可以从麦克风和 MIDI 合成器捕获音频信号。 下面的代码示例包含公开这些功能的拓扑筛选器PCCONNECTION_DESCRIPTOR数组:

    // topology pins
    enum
    {
        KSPIN_TOPO_WAVEOUT_SRC = 0,
        KSPIN_TOPO_SYNTHOUT_SRC,
        KSPIN_TOPO_SYNTHIN_SRC,
        KSPIN_TOPO_MIC_SRC,
        KSPIN_TOPO_LINEOUT_DST,
        KSPIN_TOPO_WAVEIN_DST
    };
 
    // topology nodes
    enum
    {
        KSNODE_TOPO_WAVEOUT_VOLUME = 0,
        KSNODE_TOPO_WAVEOUT_MUTE,
        KSNODE_TOPO_SYNTHOUT_VOLUME,
        KSNODE_TOPO_SYNTHOUT_MUTE,
        KSNODE_TOPO_MIC_VOLUME,
        KSNODE_TOPO_SYNTHIN_VOLUME,
        KSNODE_TOPO_LINEOUT_MIX,
        KSNODE_TOPO_LINEOUT_VOLUME,
        KSNODE_TOPO_WAVEIN_MUX
    };
 
    static PCCONNECTION_DESCRIPTOR MiniportConnections[] =
    {
       // FromNode---------------------FromPin------------------ToNode-----------------------ToPin
 
        { PCFILTER_NODE,               KSPIN_TOPO_WAVEOUT_SRC,  KSNODE_TOPO_WAVEOUT_VOLUME,  1 },
        { KSNODE_TOPO_WAVEOUT_VOLUME,  0,                       KSNODE_TOPO_WAVEOUT_MUTE,    1 },
        { KSNODE_TOPO_WAVEOUT_MUTE,    0,                       KSNODE_TOPO_LINEOUT_MIX,     1 },
 
        { PCFILTER_NODE,               KSPIN_TOPO_SYNTHOUT_SRC, KSNODE_TOPO_SYNTHOUT_VOLUME, 1 },
        { KSNODE_TOPO_SYNTHOUT_VOLUME, 0,                       KSNODE_TOPO_SYNTHOUT_MUTE,   1 },
        { KSNODE_TOPO_SYNTHOUT_MUTE,   0,                       KSNODE_TOPO_LINEOUT_MIX,     2 },
 
        { PCFILTER_NODE,               KSPIN_TOPO_SYNTHIN_SRC,  KSNODE_TOPO_SYNTHIN_VOLUME,  1 },
        { KSNODE_TOPO_SYNTHIN_VOLUME,  0,                       KSNODE_TOPO_WAVEIN_MUX,      1 },
 
        { PCFILTER_NODE,               KSPIN_TOPO_MIC_SRC,      KSNODE_TOPO_MIC_VOLUME,      1 },
        { KSNODE_TOPO_MIC_VOLUME,      0,                       KSNODE_TOPO_WAVEIN_MUX,      2 },
 
        { KSNODE_TOPO_LINEOUT_MIX,     0,                       KSNODE_TOPO_LINEOUT_VOLUME,  1 },
        { KSNODE_TOPO_LINEOUT_VOLUME,  0,                 PCFILTER_NODE,  KSPIN_TOPO_LINEOUT_DST },
 
        { KSNODE_TOPO_WAVEIN_MUX,      0,                 PCFILTER_NODE,  KSPIN_TOPO_WAVEIN_DST }
    };

前面的代码示例中的常量 PCFILTER_NODE 为 null 节点 ID,并在头文件 Portcls.h 中定义。 有关如何使用此常量来区分筛选器上的外部引脚与节点上逻辑引脚的说明,请参阅 PCCONNECTION_DESCRIPTOR

前面的代码示例中的每个引脚名称都以“SRC”或“DST”结尾,具体取决于混音器 API 是否将引脚映射到源或目标混音器线。 为了避免混淆,请记住源和目标混音器线分别映射到接收器(输入)和源(输出)KS 筛选器引脚。 有关详细信息,请参阅 音频筛选器

前面的代码示例中的PCCONNECTION_DESCRIPTOR数组描述了下图中的拓扑筛选器。

Diagram illustrating the topology filter connections described by the PCCONNECTION_DESCRIPTOR array.

图中的拓扑筛选器左侧有四个输入(接收器)引脚,右侧有两个输出(源)引脚。 连接前两个输入引脚和顶部输出引脚的数据路径混合了从正在播放的波和 MIDI 流呈现的两个模拟信号。 连接底部两个输入引脚的数据路径和底部输出引脚多路复用捕获的模拟信号。

四个输入引脚按如下所示运行:

  • KSPIN_TOPO_WAVEOUT_SRC引脚在物理上连接到波形筛选器的输出引脚,该引脚呈现来自源(如.wav文件)的波形流,以在引脚上生成模拟信号。

  • KSPIN_TOPO_SYNTHOUT_SRC引脚在物理上连接到合成器筛选器的输出引脚,例如,来自源(如.mid文件)的 MIDI 流,以在引脚上生成模拟信号。

  • KSPIN_TOPO_SYNTHIN_SRC引脚在物理上连接到生成模拟信号的合成器。 (请注意,更实用的硬件设计可能采用 MPU-401 MIDI 接口中的 MIDI 输入流,并将其直接转换为波形格式,从而完全绕过拓扑筛选器。

  • KSPIN_TOPO_MIC_SRC引脚在物理上连接到从麦克风获取模拟信号的输入插孔。

两个输出引脚按如下所示运行:

  • KSPIN_TOPO_LINEOUT_DST引脚在物理上连接到通常驱动一组扬声器的模拟换行插孔。

  • KSPIN_TOPO_WAVEIN_DST引脚在物理上连接到波形筛选器的输入引脚,它将模拟信号转换为波形流,并将其写入目标(如.wav文件)。

卷和静音节点(请参阅KSNODETYPE_VOLUMEKSNODETYPE_MUTE)用于控制各种流的卷级别。 SUM 节点(见 KSNODETYPE_SUM)混合来自波形和 MIDI 输入的音频流。 MUX 节点(请参阅 KSNODETYPE_MUX)在两个输入流之间进行选择。

该图使用虚线箭头来指示两个节点或引脚和节点之间的连接。 箭头指向数据流的方向。 该图显示总共 13 个连接,每个连接对应于上述代码示例中PCCONNECTION_DESCRIPTOR数组中 13 个元素之一。

除了拓扑筛选器,适配器驱动程序还会创建其他筛选器-波形、FM 合成器、波形表等,以连接到拓扑筛选器上的引脚。

例如,物理连接到拓扑筛选器KSPIN_TOPO_WAVEOUT_SRC引脚的波形筛选器包含 DAC(由 KSNODETYPE_DAC 节点表示),该 DAC 会将 PCM 数据转换为输出到拓扑筛选器引脚的模拟信号。 FM-synth 或可波式合成器筛选器,该筛选器在物理上连接到拓扑筛选器的KSPIN_TOPO_SYNTHOUT_SRC引脚类似地将 MIDI 数据转换为它输出到拓扑筛选器的引脚的模拟信号。 拓扑筛选器混合这两个引脚中的模拟信号,并将混合信号输出到扬声器。

拓扑筛选器与表示同一适配器上其他硬件设备的其他筛选器的物理连接卡需要与与筛选器的其他连接类型区分开来。 例如,波形、MIDI 和 Direct音乐 筛选器上的某些引脚可以在软件控制下连接或断开连接。

在设备启动期间,适配器驱动程序通过为每个连接调用 PcRegisterPhysical连接ion 来注册拓扑筛选器的物理连接。 端口驱动程序需要此信息才能响应 KSPROPERTY_PIN_PHYSICALCONNECTION get-property 请求。