Распределитель

Интерфейсы к и из распределителя — IMXF и IAllocatorMXF. Эти интерфейсы позволяют повторно использовать DMUS_KERNEL_EVENT структуры без выделения и освобождения памяти. IMXF::PutMessage предоставляет структуру для распределителя и IAllocatorMXF::GetMessage получает обнулённую структуру DMUS_KERNEL_EVENT из распределителя для повторного использования. (Распределитель создается с пустыми структурами DMUS_KERNEL_EVENT в пуле, чтобы он никогда изначально не был пустым.) Как показано на следующей схеме, IRPs (в виде структур DMUS_EVENTHEADER) приходят из dmusic.dll в распаковщик.

Схема, иллюстрирующая поток IRP через драйверы порта и минипорта в процессе распределения.

Распаковщик вызывает IAllocatorMXF::GetMessage, чтобы получить пустую структуру DMUS_KERNEL_EVENT. Распаковщик извлекает структуры DMUS_KERNEL_EVENT из IRP, заполняет эти структуры (по одной на событие MIDI) и передает их сиквенсеру (с использованием его интерфейса MXF). Последователь упорядочивает их на основе меток времени и, когда наступает время, передает их минипорт драйверу посредством вызова IMXF::PutMessage. Минипорт-драйвер извлекает данные MIDI из структур DMUS_KERNEL_EVENT, чтобы преобразовать их в волновые данные. Он передает структуры, использованные из DMUS_KERNEL_EVENT, обратно в аллокатор с другим вызовом IMXF::PutMessage.

Обратная ситуация возникает при захвате. Данные MIDI приходят из оборудования к драйверу минипорта, а драйвер минипорта вызывает IAllocatorMXF::GetMessage чтобы получить пустую структуру DMUS_KERNEL_EVENT. DMUS_KERNEL_EVENT структуры заполняются временными метками и данными и передаются в приемник данных через IMXF::PutMessage. Минипорт-драйвер может передавать несколько сообщений для каждой структуры, если он задает флаг DMUS_KEF_EVENT_INCOMPLETE в структуре DMUS_KERNEL_EVENT. Приемник записи в драйвере порта DMus анализирует этот необработанный поток данных и выдает структуры DMUS_KERNEL_EVENT, содержащие MIDI сообщения с временной меткой (по одному на структуру).

Кроме того, драйвер минипорта может выдавать сообщения с меткой времени в приемник захвата. В этом случае драйвер не задает бит DMUS_KEF_EVENT_INCOMPLETE в DMUS_KERNEL_EVENT. Устройство приема данных передает структуры с меткой времени непосредственно упаковщику, который упаковывает сообщения в IRPs и отправляет их в dmusic.dll. Захват DirectMusic используется только для записи MIDI. Для записи волн используйте запись DirectSound.

Когда упаковщик извлекает данные из структуры DMUS_KERNEL_EVENT, он удаляет использованную структуру DMUS_KERNEL_EVENT в распределитель с помощью IMXF::PutMessage. Когда буфер IRP заполнен, он передается в dmusic.dll. Упаковщик получает пустые IRP из dmusic.dll, заполняет их и завершает. Больше IRPs продолжают поступать, чтобы всегда было чем их заполнить.