Выделение голосовых функций
Большинство драйверов адаптеров, содержащих драйвер минипорта синтезатора, также содержат аппаратное ускорение DirectSound. В связи с этим встает вопрос о распределении голосов между синтезаторными голосами и буферами DirectSound с аппаратным ускорением.
Синтезаторы DirectMusic — как аппаратные, так и программные — должны поддерживать несколько экземпляров, чтобы максимально увеличить число одновременных клиентов. У автора синтезатора может возникнуть соблазн статически выделять голоса для синтезаторов, но, вероятно, следует рассматривать все доступные экземпляры синтезаторов как полученные из общего динамического голосового пула. Затем каждый экземпляр сообщает доступное количество голосов в качестве общего числа доступных в пуле.
При реализации таким образом даже аппаратный синтезатор с ограниченным количеством физических голосов может поддерживать множество экземпляров синтезатора. В режиме реального времени вызов STATS информирует клиента о том, сколько голосов использует каждый экземпляр в настоящее время. Если динамический пул исчерпан и экземпляр синтезатора требует нового голоса, этот экземпляр синтезатора должен реализовать схему кражи голоса, чтобы освободить голос из этого экземпляра.
Следующая схема распределения основана на идее, что голоса, используемые синтезатором, проще совместно использовать, чем буферы DirectSound, так как драйвер контролирует, какие данные передаются в какой голос, и может принимать решения о краже голоса (описано в спецификации уровня 1 DLS).
Все голоса, доступные для драйвера мини-порта (оборудование, программное обеспечение или некоторое сочетание оборудования и программного обеспечения), делятся на два пула. Первый пул, бесплатный пул, состоит из голосов, которые нигде не фиксируются. Второй пул, динамический пул, состоит из голосов, которые зафиксированы для использования экземплярами синтезатора. Эти голоса могут использоваться или не используются экземпляром синтезатора. Динамический пул определяется как максимальное количество голосов, запрашиваемых любым экземпляром синтезатора, в зависимости от текущего содержимого свободного пула. Буферы DirectSound удаляются из свободного пула при выделении и возвращаются при освобождении.
В следующей таблице приведен пример последовательности распределения голосов, иллюстрирующих схему на практике.
Time | Запрос | Бесплатный пул | Динамический пул | Действие драйвера мини-порта |
---|---|---|---|---|
T0 |
Выключение питания |
64 |
0 |
Инициализации. |
T1 |
DSound (4) | 60 |
0 |
Статически выделите четыре голоса для буферов DirectSound. |
T2 |
Синтезатор (32) | 28 |
32 |
Увеличьте динамический пул до 32 голосов. |
T3 |
Синтезатор (24) | 28 |
32 |
Никаких действий не выполняется. В динамическом пуле уже более 24 голосов. |
T4 |
DSound (24) | 4 |
32 |
Статически выделите 24 голоса для буферов DirectSound. |
T5 |
Синтезатор (48) | 0 |
36 |
Увеличьте динамический пул до 36 голосов. (Метод, который создает порт, возвращает S_FALSE и задает DMUS_PORTPARAMS. dwVoices = 36.) |
T6 |
DSound (10) | 0 |
36 |
Неудача. Нет голосов в бесплатном бассейне. |
T7 |
DSound (-5) | 5 |
36 |
Бесплатно пять голосов. Обратите внимание, что они не возвращаются в динамический пул, несмотря на то, что последний запрос (на момент T5) был больше, чем было предоставлено. |
Обратите внимание, что буферы DirectSound фактически выделяются по одному и группируются в таблице для удобства чтения.
Сразу после создания экземпляра контакта синтезатора на его основе не следует выделять голоса. Вскоре после создания получается элемент свойства KSPROPERTY_SYNTH_PORTPARAMETERS . Этот элемент свойства, среди прочего, указывает количество голосов, которые должны быть связаны с этим экземпляром. Этот элемент также дает драйверу минипорта возможность сообщить о фактическом новом размере динамического пула на случай, если не удается выделить все запрошенные голоса.