MIDI 和 DirectMusic 筛选器

MIDI 和 DirectMusic 筛选器表示合成、输出或捕获 MIDI 音乐数据的设备。 应用程序通常通过 DirectMusic API 或通过 Microsoft Windows 多媒体 midiOutXxxmidiInXxx 函数访问这些设备的功能。 有关这些接口的详细信息,请参阅 Microsoft Windows SDK 文档。

MIDI 或 DirectMusic 合成器筛选器将接收包含带时间戳的 MIDI 事件的 MIDI 流作为输入。 筛选器输出以下任一项:

  • 波次格式的数字音频流

  • 可驱动一组扬声器的模拟音频信号

MIDI 或 DirectMusic 输出筛选器将接收包含带时间戳的 MIDI 事件的 MIDI 流作为输入。 筛选器将原始 MIDI 消息输出到外部 MIDI 声音模块。

MIDI 或 DirectMusic 捕获筛选器采用来自 MIDI 键盘或其他外部 MIDI 设备的一系列原始 MIDI 消息作为输入。 筛选器输出包含带时间戳的 MIDI 事件的 MIDI 流。

单个 MIDI 或 DirectMusic 筛选器可以执行三个函数(合成、输出和捕获)的组合,具体取决于筛选器所表示的设备的功能。 例如,纯 MPU-401 设备执行输出和捕获,但不执行合成。

MIDI 筛选器

MIDI 筛选器以端口/微型端口驱动程序对的形式实现。 MIDI 筛选器工厂会创建 MIDI 筛选器,具体如下:

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

  • 它通过调用 GUID 值为 CLSID_PortMidiPcNewPort 来实例化 MIDI 端口驱动程序对象。

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

Subdevice Creation 中的代码示例演示了此过程。 端口和微型端口驱动程序通过其 IPortMidiIMiniportMidi 接口相互通信。

为了支持 MIDI 输出和合成器设备,MIDI 端口驱动程序包含一个软件排序器,该软件排序器会将原始 MIDI 消息输出到微型端口驱动程序,其中计时器分辨率为 1 毫秒。

DirectMusic 筛选器

DirectMusic 筛选器提供 MIDI 筛选器功能的超集。 该超集包括以下附加功能:

  • DLS(可下载的声音)资源,其中包含描述 MIDI 乐器的波形和发音数据。 KSPROPERTY_SYNTH_DLS_DOWNLOAD set-property 请求会将 DLS 资源下载到筛选器。

  • 用于扩展可选择乐器数的声道组。 DMUS_KERNEL_EVENT 结构用于打包 MIDI 流中每条带时间戳的 MIDI 消息,指定要用于该消息的声道组。

  • 支持硬件 MIDI 排序的 64 位时间戳,其分辨率为 100 纳秒。 DMUS_KERNEL_EVENT 结构指定 MIDI 消息的高分辨率时间戳。

使用声道组时,可以同时播放的注释数不再局限于原始 MIDI 规范的 16 个声道。 它仅受合成器中提供的语音数的限制。

DirectMusic 筛选器以端口/微型端口驱动程序对的形式实现。 DirectMusic 筛选器工厂会创建 DirectMusic 筛选器,具体如下:

  • 它会实例化 DMus (DirectMusic) 微型端口驱动程序对象。

  • 它通过调用 GUID 值为 CLSID_PortDMusPcNewPort 来实例化 DMus 端口驱动程序对象。

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

Subdevice Creation 中的代码示例演示了此过程。 端口和微型端口驱动程序通过其 IPortDMusIMiniportDMus 接口相互通信。

为了支持 DirectMusic 合成器设备,DMus 端口驱动程序包含一个低分辨率(一毫秒)软件排序器,该排序器可以提前于计划的播放时间将带时间戳的 MIDI 事件输出到硬件排序器的缓冲区。 为了支持 DirectMusic 输出设备,还可以将端口驱动程序的软件排序器配置为在播放原始 MIDI 消息时输出原始 MIDI 消息。

枚举 MIDI 和 DirectMusic 设备

通过 Windows 多媒体 midiInXxxmidiOutXxx 函数枚举 MIDI 输入或输出设备时,应用程序只能看到其微型端口驱动程序公开 MIDI 引脚的 WDM 设备。 这些是管理原始 MIDI 流的引脚,但不支持 DLS 和声道组等高级功能。 但是,通过 DirectMusic 枚举设备时,应用程序可以看到具有 MIDI 引脚和 DirectMusic 引脚的 WDM 设备。 DirectMusic 引脚管理带时间戳的 MIDI 流,并支持 DLS 和声道组。

实现自定义微型端口驱动程序时,硬件供应商通常会编写 MIDI 微型端口驱动程序或 DMus 微型端口驱动程序,但不能同时写入这两者。 MIDI 微型端口驱动程序只能公开 MIDI 引脚。 但是,DMus 微型端口驱动程序可以同时公开 MIDI 和 DirectMusic 引脚,这样就无需编写单独的 MIDI 微型端口驱动程序。 有关 DirectMusic 筛选器上的 MIDI 引脚示例,请参阅 Windows 驱动程序工具包 (WDK) 中的 Dmusuart 示例音频驱动程序。

指定 MIDI 或 DirectMusic 引脚的数据范围时,MIDI 或 DMus 微型端口驱动程序会为 MIDI 引脚指定一种类型为 KSDATAFORMAT_TYPE_MUSIC 的主要格式,以及一种类型为 KSDATARANGE_SUBTYPE_MIDI 的子格式,或者为 DirectMusic 引脚指定 KSDATARANGE_SUBTYPE_DIRECTMUSIC。 MIDI 和 DirectMusic 引脚的数据范围描述符示例分别出现在 MIDI 流数据范围DirectMusic 流数据范围中。

MIDI 筛选器上的 MIDI 引脚实例会公开 IMiniportMidiStream 接口。 DirectMusic 筛选器上的 MIDI 或 DirectMusic 引脚实例会公开 IMXF 接口。

在 Windows Me/98 中,DirectMusic 有时会枚举同一 MPU-401 设备两次。 原因是某些硬件供应商将其 MPU-401 设备作为 WDM MIDI 之前的旧版设备和 WDM 设备公开。 对于旧版设备,DirectMusic 会枚举一个 MPU-401 设备,该设备表示从 DMusic.dll 到 Ihvaudio.dll 的直接路径。 对于 WDM 设备,DirectMusic 会通过由以下组件序列组成的线路路径枚举相同的 MPU-401 设备:

  1. DMusic.dll

  2. DMusic16.dll

  3. MMSystem.dll

  4. WDMAud.drv

  5. WDMAud.sys

  6. 供应商的微型端口驱动程序

Windows 多媒体控制面板 (Mmsys.cpl) 中显示的 MIDI 合成器的名称将与 WDM 设备相同。

系统提供的端口和微型端口驱动程序

PortCls 系统驱动程序中内置了多个系统提供的 MIDI 和 DMus 微型端口驱动程序:

  • FMSynth 微型端口驱动程序为实现 OPL3 样式 FM 合成的 MIDI 设备提供接口。

  • UART 微型端口驱动程序支持具有 MPU-401 硬件接口的 MIDI 设备,但此驱动程序现已过时(Windows 98 Gold 之后),仅现有适配器驱动程序支持。 新的适配器驱动程序代码应改用 DMusUART 微型端口驱动程序(在 Windows 98 SE 和 Windows Me 以及 Windows 2000 及更高版本中),这将取代 UART 并实现其功能的超集。

适配器驱动程序可以调用 PcNewMiniport 函数来访问系统提供的微型端口驱动程序。 FMSynth 和 DMusUART 微型端口驱动程序也作为示例音频驱动程序包含在 Windows 驱动程序工具包 (WDK) 中。 通过修改这些示例中的源代码,硬件供应商可以扩展驱动程序,以管理其设备的专有功能。

DMusUART 是 DMus 微型端口驱动程序的一个示例,该驱动程序会公开 MIDI 和 DirectMusic 引脚,但不支持 DLS 下载或硬件排序。 微型端口驱动程序的 DirectMusic 呈现引脚具有支持多个 KSPROPSETID_Synth 属性的合成器节点 (KSNODETYPE_SYNTHESIZER)。 微型端口驱动程序包括在 KSCATEGORY_RENDER 和 KSCATEGORY_CAPTURE 中,但不包括在 KSCATEGORY_SYNTHESIZER 中(因为它不包含内部合成器)。 有关详细信息,请参阅 WDK 中的 DMusUART 示例音频驱动程序。

请注意,在 Windows XP 及更高版本中,MIDI 和 DMus 端口驱动程序使用相同的内部软件实现。 这意味着,调用 PcNewPort 时,CLSID_PortMidiCLSID_PortDMus GUID 等效。 为早期版本的 Windows 编写的应用程序不能看到因整合 MIDI 和 DMus 端口驱动程序而导致的任何行为变化。