语音分配
包含合成器微型端口驱动程序的大多数适配器驱动程序也包含 DirectSound 硬件加速。 这提出了合成器语音与硬件加速 DirectSound 缓冲区之间的语音分配问题。
DirectMusic 合成器(硬件和软件)应支持多个实例,以便最大化并发客户端的数量。 合成器编写人员可能倾向于将语音静态分配给合成器,但应该将合成器的所有可用实例视为从通用动态语音池中绘制。 然后,每个实例将可用语音数报告为池中可用的总数。
以这种方式实现时,即使是具有有限物理语音的硬件合成器,也可以支持许多合成器实例。 STATS 调用会实时通知客户端每个实例当前使用的语音数。 如果动态池已耗尽,并且合成器实例需要新的语音,则该合成器实例必须实现语音窃取方案,以便从该实例中释放语音。
以下分配方案基于合成器使用的语音比 DirectSound 缓冲区更容易共享的想法,因为驱动程序可以控制在哪些语音中有哪些数据,并且可以做出有关语音窃取的决定(DLS 级别 1 规范中概述)。
微型端口驱动程序(硬件、软件,或者硬件和软件的某种组合)提供的所有语音分为两个池。 第一个池(可用池)由未在任何地方提交的语音组成。 第二个池(动态池)由合成器实例承诺使用的语音组成。 合成器实例当前可能在也可能不在使用这些语音。 动态池的大小是任何合成器实例请求的最大语音数,但受可用池的当前内容的约束。 分配后,将从可用池中删除 DirectSound 缓冲区,并在解除分配时将其返回。
下表包含一个语音分配示例序列,用于说明实际方案。
时间 | 请求 | 可用池 | 动态池 | 微型端口驱动程序操作 |
---|---|---|---|---|
T0 |
开启 |
64 |
0 |
Initialize。 |
T1 |
DSound (4) | 60 |
0 |
以静态方式将四个语音分配给 DirectSound 缓冲区。 |
T2 |
Synth (32) | 28 |
32 |
将动态池增加到 32 个语音。 |
T3 |
Synth (24) | 28 |
32 |
无操作。 动态池中已经有 24 个以上的语音。 |
T4 |
DSound (24) | 4 |
32 |
以静态方式将 24 个语音分配给 DirectSound 缓冲区。 |
T5 |
Synth (48) | 0 |
36 |
将动态池增加到 36 个语音。 (创建端口的方法将返回 S_FALSE and sets DMUS_PORTPARAMS.dwVoices = 36。) |
T6 |
DSound (10) | 0 |
36 |
Fail. 可用池中没有语音。 |
T7 |
DSound (-5) | 5 |
36 |
可用五个语音。 请注意,即使最后一个请求(时间 T5)超过授予,但这些请求也不会返回到动态池中。 |
请注意,DirectSound 缓冲区实际上是逐个分配的,并在表中组合在一起以实现可读性。
在创建合成器引脚实例后,不能立即基于该实例分配任何语音。 创建后不久,会收到 KSPROPERTY_SYNTH_PORTPARAMETERS 属性项。 此属性项指示要与此实例关联的语音数,等等。 此项还使微型端口驱动程序有机会报告动态池的实际新大小,以防无法分配所有请求的语音。