分配器

分配器的往来接口是 IMXFIAllocatorMXF。 这些接口允许重复使用 DMUS_KERNEL_EVENT 结构,而无需分配和解除分配内存。 IMXF::PutMessage 为分配器提供一个结构,而 IAllocatorMXF::GetMessage 从分配器中检索新的归零 DMUS_KERNEL_EVENT 结构以供重复使用。 (可使用池中的空 DMUS_KERNEL_EVENT 结构创建分配器,使其永远不会开始为空。)如下图所示,IRP(爱用 DMUS_EVENTHEADER 结构的形式)从 dmusic.dll 进入解压缩程序。

Diagram illustrating the flow of IRPs through port and miniport drivers in the allocator process.

解压缩程序会调用 IAllocatorMXF::GetMessage 来检索空 DMUS_KERNEL_EVENT 结构。 解压缩程序会从 IRP 检索 DMUS_KERNEL_EVENT 结构,填充这些结构(每个 MIDI 事件一个),并将其向下传递到排序器(使用其 MXF 接口)。 排序器根据时间戳对它们重新排序,并在它们到期时通过调用 IMXF::PutMessage 将它们传递给微型端口驱动程序。 微型端口驱动程序将 MIDI 数据从 DMUS_KERNEL_EVENT 结构中拉取出来,以便它可以将其呈现为波次数据。 它使用另一个 IMXF::PutMessage 调用将已用 DMUS_KERNEL_EVENT 结构传递回分配器。

捕获情况则相反。 MIDI 数据从硬件进入微型端口驱动程序,并且微型端口驱动程序会调用 IAllocatorMXF::GetMessage,以获取空 DMUS_KERNEL_EVENT 结构。 DMUS_KERNEL_EVENT 结构将填充时间戳和数据,并通过 IMXF::PutMessage 传递到捕获接收器。 如果微型端口驱动程序在 DMUS_KERNEL_EVENT 结构中设置 DMUS_KEF_EVENT_INCOMPLETE 标志,则每个结构可以传递多条消息。 DMus 端口驱动程序中的捕获接收器会解析此原始数据流,并发出包含带时间戳的 MIDI 消息(每个结构一条)的 DMUS_KERNEL_EVENT 结构。

微型端口驱动程序本身还可以向捕获接收器发出带时间戳的消息。 在这种情况下,驱动程序不会在 DMUS_KERNEL_EVENT 中设置 DMUS_KEF_EVENT_INCOMPLETE 位。 捕获接收器会将带时间戳的结构直接传递到打包器,将消息打包到 IRP 中,并将其发送到 dmusic.dll。 DirectMusic 捕获仅用于录制 MIDI。 对于波次录制,请使用 DirectSound 捕获。

当打包器将数据从 DMUS_KERNEL_EVENT 结构中拉出时,它会使用 IMXF::PutMessage 将使用的 DMUS_KERNEL_EVENT 结构放弃到分配器中。 当 IRP 缓冲区已满时,会将其传递到 dmusic.dll。 包装器会从 dmusic.dll 接收空 IRP,填充它们,并完成它们。 更多的 IRP 会不断下降,以便总有一个要填充。