14: /** В этот момент драйвер запускает АЦП адаптера, и звуковые отсчеты начинают поступать в первый буфер из очереди. **/
15: получить уведомление от драйвера;
16: определить размер данных; /* dwBytesRecorded */
17: обработать записанные данные;
18: освободить буфер;
19: передать буферы приложению;
20: Если <цикл воспроизведения> то
21: Пока <воспроизведение> выполняем
22: заполнить буферы звуковыми данными;
23: передать буферы драйверу устройства вывода; /* Write */
24: /** После получения первого же буфера драйвер запускает ЦАП адаптера, который начинает извлекать звуковые отсчеты. **/
25: воспроизвести буфер полностью; /* dwBufferLength */
26: освободить буфер;
27: передать буферы приложению;
28: освободить буферы; /* Unprepare */
29: закрыть устройство; /* Close */
При необходимости приостановить движение потока вызывается функция Stop/Pause. При этом устройство ввода сразу же возвращает очередной буфер приложению — возможно, заполненный лишь частично. Не полностью проигранный буфер устройства вывода остается в очереди. Остальные буферы устройств обоих типов также остаются в очереди и включаются в работу только после перезапуска потока функциями Start/Restart.
Для устройств вывода, поддерживающих расширенные функции управления, программа может регулировать громкость звука функцией SetVolume, а также изменять высоту тона и скорость воспроизведения функциями SetPitch или SetPlaybackRate. Более общим способом регулировки громкости является обращение к микшеру (mixer), который является устройством класса Aux.
Для аварийного прерывания обработки потока используется функция Reset, немедленно останавливающая процесс записи или воспроизведения и возвращающая все буферы из очереди приложению.
23.1. Назначение, структура, особенности
Подсистема DirectSound обеспечивает приложениям практически непосредственный доступ к аппаратуре звукового адаптера. Предоставляется модель современного звукового адаптера, предельно приближенная к реальности, с минимальным уровнем абстракции.
Подсистема DirectSound построена по объектно-ориентированному принципу в соответствии с моделью COM[42] и состоит из набора интерфейсов.
Каждый интерфейс отвечает за объект определенного типа:
• устройство,
• буфер,
• службу уведомления и т.п.
Интерфейс — набор управляющих функций, или методов, организованных в класс объектно-ориентированного языка.
DirectSound не поддерживает звуковые форматы, отличные от PCM. Назначение DirectSound — исключительно эффективный вывод звука.
Основные преимущества DirectSound:
• задание несколько источников звука;
• объемный звук (в DirectSound3D это преимущество усилено).
23.2. Аппаратная поддержка
DirectSound всю возможную работу старается переложить на аппаратуру адаптера.
Однако, строит заметить, что приложениям, использующим большое количество одновременно звучащих источников или сложную трехмерную картину, имеет смысл упрощать свою модель при отсутствии средств аппаратного ускорения, иначе накладные расходы могут существенно снизить общую производительность системы.
При отсутствии каких любо звуков у адаптера DirectSound эмулирует их на синтезаторе адаптера. Для создания реалистичной звуковой картины DirectSound нуждается в информации о расположении звукоизлучателей — громкоговорителей или наушников — относительно слушателя.
23.3. Звуковые буферы
Большинство существующих звуковых адаптеров использует для обмена звуком с центральным процессором звуковые буферы, представляющие собой участок памяти, в который заносятся звуковые данные.
Обычно буфер — кольцевой.
Адаптер и его драйвер работают параллельно с разными частями буфера, стараясь следовать друг за другом и не создавать конфликтов. Если их работа согласованна — получается непрерывное движение сколь угодно длительного звукового потока.
DirectSound предоставляет приложению почти прямой доступ к аппаратным буферам адаптера.
В отличие от модели MME: вывод коротких и повторяющихся звуков значительно упрощается, а вывод длительных непрерывных звучаний несколько усложняется.
23.3.1. Аппаратные и программные
Различные адаптеры используют буферы разного типа:
• Классические адаптеры типа Sound Blaster, Windows Sound System и совместимые с ними используют буфер в основной памяти компьютера с доступом через DMA[43].
• Адаптеры архитектуры Hurricane (Turtle Beach Tahiti, Fiji и совместимые) используют буфер в собственной (on-board) памяти, который доступен в виде «окна» в диапазоне адресов внешних устройств.
• Существуют также адаптеры со встроенным буфером, доступ к которому осуществляется через порты ввода-вывода; обычно так работают таблично-волновые синтезаторы.
В зависимости от размещения и способа управления различают аппаратные и программные буферы.
Аппаратным буфер — буфер, к которому адаптер имеет прямой доступ. Такой буфер располагается либо в памяти самого адаптера, либо в основной памяти с обращением через DMA.
Программный буфер — буфер, к которому адаптер имеет доступ через процессор. Программные буферы всегда располагаются в основной памяти.
В документации по DirectSound аппаратными называют только те буферы, которые находятся в памяти адаптера, и нередко путают термин «hardware» в отношении размещения буфера и способа смешивания звука.
23.3.2. Первичный и вторичные
Если в архитектуре адаптера один из аппаратных буферов является основным, его называют первичным (primary). Остальные буферы, занимающие подчиненное положение, называются вторичными (secondary).
Обычно звуки из вторичных буферов смешиваются воедино в первичном буфере, откуда и поступают на ЦАП адаптера.
Для адаптеров, работающих только с одним буфером, он и является первичным. Вторичные буферы могут быть только программными и управляются самой подсистемой DirectSound.
Для современных многоканальных адаптеров PCI, имеющих несколько равноправных каналов вывода звука, первичный буфер недоступен, зато некоторое количество вторичных может быть аппаратными, и управление звуками в них осуществляет непосредственно сам адаптер. Чаще всего приложению не требуется использовать первичный буфер.
В типовой схеме взаимодействия для каждого источника звука создается свой вторичный буфер (в DirectSound часто отождествляются понятия «источник звука» и «вторичный звуковой буфер»). Впоследствии приложение в нужные моменты включает и выключает звучание источников, меняет текущую позицию в звуке, параметры звучания и т.п.
Вторичные буферы могут иметь произвольные размеры, которые задаются приложением при их создании. Даже если смешивание выполняет DirectSound — оно осуществляется на уровне ядра.
Прямой доступ к первичному буферу возможен только в исключительных случаях. При этом запрещается использование вторичных буферов — то есть приложение теряет возможность описывать независимые источники звука. Зато наличие доступа к первичному буферу гарантирует, что все изменения в звуковых данных будут услышаны максимально быстро. Однако первичный буфер имеет фиксированный размер,выбираемый драйвером DirectSound, и размер этот достаточно мал.
Для того чтобы успевать вписывать звук в первичный буфер, приложение должно иметь высокий уровень приоритета. Но даже в этом случае Windows не гарантирует нужной скорости.
Вторичный буфер может быть статическим (static) и потоковым (streaming). Статические буферы предназначены для постоянных звуков, цифровое представление которых не меняется либо меняется достаточно редко. Потоковые буферы ориентированы на часто изменяемые звуки, как правило — на представление длительного звукового потока, который по частям «прогоняется» через буфер.
Статические и потоковые буферы различаются только тем, что подсистема старается в первую очередь делать аппаратными статические буферы, загружая их в память адаптера.
Таким образом, постоянные и короткие звуки оказываются в распоряжении адаптера, и достаточно лишь дать команду, чтобы они включились в общее звучание.
Приложение может явно указывать при создании буфера тип памяти для его размещения.
DirectSound оптимизирует использование вторичных буферов в порядке их создания приложением. Источники звука, созданные в первую очередь, имеют приоритет в использовании аппаратных средств. Буферы, созданные первыми, подсистема старается по возможности загружать в память адаптера, предоставлять им каналы DMA. При исчерпании аппаратных ресурсов DirectSound переходит на самостоятельную, программную обработку оставшихся буферов.
Поскольку каждый вторичный буфер описывает независимый источник звука, подсистема предоставляет средства управления режимами звучания источника.
• Для базовых источников DirectSound доступно управление
I громкостью,
I панорамой,
I частотой дискретизации;
• для источников DirectSound3D еще
I пространственными координатами, I направленностью, I скоростью движения.
Набор необходимых для источника методов управления задается при создании буфера и позволяет подсистеме оптимально связывать буферы с аппаратными ресурсами. Впоследствии доступны только заказанные методы управления; для изменения набора необходимо уничтожить буфер и создать его заново.