|
|
|
||||||||||||
|
|
Собственный, легко управляемый и профессионально разработанный сайт – необходимый элемент любого бизнеса. Находитесь ли Вы в командировке, в дороге, дома или на отдыхе имея компьютер, подключенный к сети Internet, Вы получаете доступ к управлению Вашим сайтом! |
|||
Программирование звука в DirectSoundСтатьи → Программирование на С/С++DirectSound - сравнительно новый программный интерфейс, входящий в семейство <мультимедийных> интерфейсов DirectX (DirectDraw, Direct3D, DirectInput и т.п.). Первым продуктом данного семейства является интерфейс Direct Draw, созданный почти одновременно с Windows 95 и предназначенный для оптимизации работы игровых приложений с видеоадаптером. Затем к нему добавились интерфейсы Direct3D, DirectInput, а впоследствии для многих классических интерфейсов с оконечными устройствами были введены Direct-версии. Название DirectX трактуется буквально - <прямой, непосредственный интерфейс X>. Классические системные интерфейсы с видео-, звуковыми и игровыми адаптерами относятся к Windows первых версий, когда внутренняя организация большинства адаптеров была достаточно разношерстной, многие решения находились в стадии отработки, а приложениям требовалось в первую очередь отображать прямоугольные окна, текст и графики, проигрывать длительные непрерывные звукозаписи и т.п. С массовым переходом производителей игр на платформу Windows и развитием видеотехнологий выяснилось, что большинство классических интерфейсов слишком абстрактны, поэтому при работе с конкретным устройством возникают заметные накладные расходы, ощутимо снижающие быстродействие; при частой и хаотичной перерисовке элементов экрана, выводе коротких одновременных звуков выполняется множество лишних операций. Семейство DirectX было разработано именно для того, чтобы приблизить аппаратуру к приложению, предоставив эффективный интерфейс. Ценой эффективности явилось снижение универсальности интерфейсов, более явная привязка их к определенным схемам и протоколам взаимодействия. Для полной поддержки DirectX необходима установка специального расширенного DirectX-драйвера; традиционные драйверы устройств, как правило, для этого не годятся. В первые несколько лет существования DirectX выпуск DirectX-драйверов часто отставал от выпуска устройств; сейчас этот разрыв практически отсутствует, хотя далеко не все драйверы поддерживают полный набор заявленных функций. В случае появления новых технологий вывода изображения и звука может оказаться, что они не укладываются в схему DirectX, и тогда потребуется серьезная переработка как интерфейсов, так и использующих их приложений. Интерфейсы семейства DirectX состоят из общесистемной части - подсистем DirectX, с которыми общаются приложения, и набора драйверов с поддержкой DirectX - обычных драйверов устройств, в которые добавлена поддержка новых объектов и функций. Центральной частью любой подсистемы DirectX является HAL (Hardware Abstraction Layer - уровень отвлечения от аппаратуры) - промежуточный интерфейс, который скрывает частные, непринципиальные особенности используемых аппаратных средств, но сохраняет полный контроль над основными, ключевыми возможностями аппаратуры. HAL реализуется на уровне драйвера устройства. Поддержка DirectX включена в стандартную поставку начиная с Windows 98 и NT 5. В системах Windows 95, OSR2 и NT 4 поддержка DirectX не предусмотрена, однако Microsoft выпускает отдельные расширения для Windows 9x и NT, установка которых восполняет в системе отсутствующие компоненты - собственно подсистемы и распространенные драйверы. Поддержка интерфейсов DirectX есть в большинстве систем программирования C++, Pascal и Basic, выпущенных после 1995 года. Семейство имеет целый ряд версий; в настоящее время используется версия 7. Если в среде программирования поддерживаются только более старые версии, можно заменить включаемые файлы и библиотеки на более новые, содержащие обновленные версии подсистем, взяв их из новой версии DirectX Описания подсистем также имеются в поддерживающих их средах программирования. Более новые версии описаний распространяются Microsoft в составе DirectX SDK. Microsoft поддерживает в Internet справочную систему MSDN Online, где интерфейсы DirectX описаны в разделе http://msdn.microsoft.com/library/psdk/directx/dxstart_1x2d.htm, а сам DirectSound - в Основные черты и понятия DirectSound Назначение и структура Подсистема DirectSound обеспечивает приложениям практически непосредственный доступ к аппаратуре звукового адаптера. Этот факт вовсе не означает, что приложению приходится вникать в детали программирования того или иного адаптера - это остается прерогативой HAL. Вместо этого приложению предоставляется модель современного звукового адаптера, предельно приближенная к реальности, с минимальным уровнем абстракции. При таком подходе общение приложения с адаптером сопровождается минимальными накладными расходами, и в то же время избавляет приложение от излишних подробностей программирования аппаратуры. Подсистема DirectSound построена по объектно-ориентированному принципу в соответствии с моделью COM (Component Object Model - модель объектов-компонентов, или составных объектов) и состоит из набора интерфейсов. Каждый интерфейс отвечает за объект определенного типа - устройство, буфер, службу уведомления и т.п. По сути, интерфейс представляет собой обычный набор управляющих функций, или методов, организованных в класс объектно-ориентированного языка. DirectSound не поддерживает звуковые форматы, отличные от PCM. Назначение DirectSound - исключительно эффективный вывод звука, а операции по преобразованию форматов остаются в ведении приложений, которые могут использовать для этого подсистему сжатия звука Смешивание сигналов Одно из наиболее неудобных ограничений MME/Wave - невозможность проигрывания нескольких звуков на одном устройстве одновременно без их программного смешивания самим приложением. DirectSound снимает это ограничение, позволяя приложению просто задавать несколько источников звука, которые будут проиграны одновременно. Количество таких источников ограничено только доступной памятью и быстродействием аппаратуры. Объемный звук Источники звука, работающие в базовой модели DirectSound, могут быть только моно- стереофоническими. Работа расширенной базовой модели, DirectSound3D, основана на другой концепции, позволяющей размещать монофонические источники звука в пространстве. Для каждого источника, а также для самого слушателя, задаются координаты в пространстве, ориентация, направление и скорость перемещения. DirectSound3D обрабатывает все источники и создает для слушателя объемную и реалистичную звуковую картину с учетом интерференции, затухания, направленности, эффекта Доплера и т.п. В этой статье рассматривается только базовая модель DirectSound. Расширение DirectSound3D будет описано в следующих выпусках. Использование аппаратных ускорителей При наличии у используемого звукового адаптера средств аппаратного ускорения (hardware acceleration) - смешивания нескольких источников звука, обсчета трехмерной модели, создания звуковых эффектов и т.п. - DirectSound всю возможную работу старается переложить на аппаратуру адаптера. Использование аппаратного ускорения остается прозрачным для приложения - DirectSound использует возможности аппаратуры там, где это можно, а в остальных случаях выполняет нужную работу на программном уровне. Тем не менее приложениям, использующим большое количество одновременно звучащих источников или сложную трехмерную картину, имеет смысл упрощать свою модель при отсутствии средств аппаратного ускорения, иначе накладные расходы могут существенно снизить общую производительность системы. Для реализации на аппаратном уровне смешивания и звуковых эффектов необязательно нужен современный адаптер с шиной PCI. Многие комбинированные адаптеры с шиной ISA - семейство Sound Blaster AWE, Turtle Beach Maui/Tropez/Pinnacle, Guillemot MaxiSound - имеют встроенные таблично-волновые синтезаторы с расширяемой оперативной памятью. Если синтезатор свободен и у него достаточно свободной памяти, DirectSound может загрузить туда некоторое количество источников звука и проигрывать их средствами синтезатора. Конфигурация звукоизлучателей Для создания реалистичной звуковой картины DirectSound нуждается в информации о расположении звукоизлучателей - громкоговорителей или наушников - относительно слушателя. Для достижения максимального эффекта звукоизлучатели должны быть установлены и настроены правильно, а приложение должно указать используемую конфигурацию подсистеме DireсtSound. Звуковые буферы Большинство существующих звуковых адаптеров использует для обмена звуком с центральным процессором звуковые буферы, представляющие собой участок памяти, в который заносятся звуковые данные. Обычно буфер является кольцевым, то есть указатель текущей позиции при достижении конца буфера автоматически перебрасывается на его начало, совершая внутри буфера круговое движение. Адаптер и его драйвер работают параллельно с разными частями буфера, стараясь следовать друг за другом и не создавать конфликтов; если их работа достаточно согласованна - получается непрерывное движение сколь угодно длительного звукового потока. В отличие от концепции связанной цепочки программных буферов, принятой в MME, DirectSound предоставляет приложению почти прямой доступ к аппаратным буферам адаптера. В этой концепции просто смещены акценты: вывод коротких и повторяющихся звуков значительно упрощается, а вывод длительных непрерывных звучаний несколько усложняется относительно модели Размещение звуковых буферов Различные адаптеры используют буферы разного типа. Классические адаптеры типа Sound Blaster, Windows Sound System и совместимые с ними используют буфер в основной памяти компьютера с доступом через DMA. Адаптеры архитектуры Hurricane (Turtle Beach Tahiti, Fiji и совместимые) используют буфер в собственной (on-board) памяти, который доступен в виде <окна> в диапазоне адресов внешних устройств. Существуют также адаптеры со встроенным буфером, доступ к которому осуществляется через порты ввода-вывода; обычно так работают таблично-волновые синтезаторы. В зависимости от размещения и способа управления различают аппаратные (hardware) и программные (software) буферы. Аппаратным называют буфер, к которому адаптер имеет прямой доступ; такой буфер располагается либо в памяти самого адаптера, либо в основной памяти с обращением через DMA или Bus Mastering. Программные буферы всегда располагаются в основной памяти и управляются центральным процессором, адаптер к таким буферам прямого доступа не имеет. В документации по DirectSound аппаратными называют только те буферы, которые находятся в памяти адаптера, и нередко путают термин в отношении размещения буфера и способа смешивания звука. Я буду пользоваться выражением <аппаратный буфер> - для обозначения буфера в памяти адаптера и выражением <буфер с аппаратным смешиванием>, когда речь будет идти о буфере, к которому адаптер имеет прямой доступ при извлечении звука. Первичный и вторичные буферы Если в архитектуре адаптера один из аппаратных буферов является основным, его называют первичным (primary). Остальные буферы, занимающие подчиненное положение, называются вторичными (secondary). Обычно звуки из вторичных буферов смешиваются воедино в первичном буфере, откуда и поступают на ЦАП адаптера. Для адаптеров типа SB/WSS, работающих только с одним буфером, он и является первичным; вторичные буферы могут быть только программными и управляются самой подсистемой DirectSound. И наоборот, для современных многоканальных адаптеров PCI, имеющих несколько равноправных каналов вывода звука, первичный буфер недоступен, зато некоторое количество вторичных может быть аппаратными, и управление звуками в них осуществляет непосредственно сам адаптер. Чаще всего приложению не требуется использовать первичный буфер. В типовой схеме взаимодействия для каждого источника звука создается свой вторичный буфер (в DirectSound часто отождествляются понятия <источник звука> и <вторичный звуковой буфер>). Впоследствии приложение в нужные моменты включает и выключает звучание источников, меняет текущую позицию в звуке, параметры звучания и т.п. Вторичные буферы могут иметь произвольные размеры, которые задаются приложением при их создании. Даже если смешивание выполняет DirectSound - оно осуществляется на уровне ядра (VxD или системно). В исключительных случаях возможен прямой доступ к первичному буферу. При этом запрещается использование вторичных буферов - то есть приложение теряет возможность описывать независимые источники звука. Зато наличие доступа к первичному буферу гарантирует, что все изменения в звуковых данных будут услышаны максимально быстро (единицы миллисекунд). Однако первичный буфер имеет фиксированный размер, выбираемый драйвером DirectSound, и размер этот достаточно мал (несколько десятков миллисекунд звучания). Для того чтобы успевать вписывать звук в первичный буфер, приложение должно иметь высокий уровень приоритета. Но даже в этом случае Windows не гарантирует нужной скорости, не являясь системой реального времени. Статические и потоковые буферы Вторичный буфер может быть статическим (static) и потоковым (streaming). Статические буферы предназначены для постоянных звуков, цифровое представление которых не меняется либо меняется достаточно редко. Потоковые буферы ориентированы на часто изменяемые звуки, как правило - на представление длительного звукового потока, который по частям <прогоняется> через буфер. Статические и потоковые буферы различаются только тем, что подсистема старается в первую очередь делать аппаратными статические буферы, загружая их в память адаптера. Таким образом, постоянные и короткие звуки оказываются в распоряжении адаптера, и достаточно лишь дать команду, чтобы они включились в общее звучание. При желании приложение может явно указывать при создании буфера тип памяти для его размещения. Порядок создания вторичных буферов DirectSound оптимизирует использование вторичных буферов в порядке их создания приложением; источники звука, созданные в первую очередь, имеют приоритет в использовании аппаратных средств. Буферы, созданные первыми, подсистема старается по возможности загружать в память адаптера, предоставлять им каналы DMA, ресурсы Bus Mastering и т.п.; при исчерпании аппаратных ресурсов DirectSound переходит на самостоятельную, программную обработку оставшихся буферов. Управление режимами вторичных буферов Поскольку каждый вторичный буфер описывает независимый источник звука, подсистема предоставляет средства управления режимами звучания источника. Для базовых источников DirectSound доступно управление громкостью, панорамой и частотой дискретизации; для источников DirectSound3D еще и пространственными координатами, направленностью и скоростью движения. Набор необходимых для источника методов управления задается при создании буфера и позволяет подсистеме оптимально связывать буферы с аппаратными ресурсами. Впоследствии доступны только заказанные методы управления; для изменения набора необходимо уничтожить буфер и создать его заново. Позиции в буфере DirectSound использует для адресации в звуковых буферах понятие текущих позиций, или курсоров. Различают позицию записи/воспроизведения, отслеживающую проигрывание звука из буфера в адаптер или запись звука из адаптера в буфер, и позицию доступа, отслеживающую чтение/запись (обмен данными) между приложением и буфером. В первичной англоязычной документации первая позиция называется Play/Capture Position, а вторая - Read/Write Position, поэтому отсутствуют коллизии между значениями термина <запись>. Для обозначения ввода звука извне я также буду пользоваться термином <захват> Позиция воспроизведения (play) следует за позицией записи (write) в буфер, а позиция чтения (read) - за позицией захвата (capture). Достижение позицией воспроизведения позиции записи означает полное проигрывание буфера воспроизведения, при этом начинают воспроизводиться <старые> данные, которые приложение не успело перезаписать. Достижение позицией захвата позиции чтения означает переполнение буфера захвата, и последующие данные накладываются на <старые>, которые приложение не успело извлечь из буфера. Уровни взаимодействия DirectSound вводит четыре уровня взаимодействия (cooperation levels) приложений между собой и звуковым адаптером. Когда несколько приложений одновременно используют один и тот же адаптер, соотношение уровней взаимодействия определяет их приоритетность в использовании аппаратуры и создании звучания.
Потеря буферов Когда приложение, запросившее высший (write-primary) уровень взаимодействия, становится активным, подсистеме приходится передавать ему управление первичным буфером, теряя при этом собственный контроль над ним. И наоборот, когда активным становится приложение с менее высоким уровнем, подсистема возвращает себе контроль над буфером, но теперь его теряет <уходящее в фон> приложение. В этой ситуации, называемой потерей буферов (buffer lose), буфер прекращает звучание и его содержимое теряется. Когда приложение высшего уровня становится активным, звучание всех вторичных буферов приложений более низких уровней останавливается, а сами буферы помечаются как потерянные. Это происходит потому, что подсистема не может правильно отслеживать текущие позиции во вторичных буферах, не имея доступа к первичному буферу адаптера. И наоборот, когда приложение высшего уровня становится неактивным, его первичный буфер также помечается как потерянный. Приложения получают сообщение о потере буферов при попытках обращения к ним в виде кода ошибки DSERR_BUFFERLOST. Все приложения должны корректно обрабатывать эту ситуацию и выполнять восстановление потерянных буферов. Эмуляция Подсистема DirectSound может обходиться без поддержки со стороны драйвера. В этом случае нужная функциональность эмулируется через MME - традиционную звуковую подсистему Windows. Однако такая эмуляция крайне неэффективна, поскольку при этом подсистеме DirectSound приходится эмулировать первичный буфер в обычной памяти, смешивать в нем звуки из вторичных буферов, затем представлять его в виде цепочки буферов, передаваемых драйверу MME, который, в свою очередь, разбивает их на фрагменты и переносит в звуковой буфер адаптера. При этом каждое обращение к драйверу MME сопровождается переключением в 16-разрядный режим и обратно. Отметим, что без наличия специализированного DirectSound-драйвера невозможно получить высший (write-primary) уровень взаимодействия с адаптером. Тем не менее поддержка захвата (capture) звука в DirectSound реализована только методом эмуляции. Для драйверов DirectSound VxD определены лишь функции поддержки воспроизведения - дальше в унификации этого интерфейса Microsoft почему-то не пошла. Операции записи и воспроизведения с точки зрения адаптера почти идентичны и различаются в основном направлением движения данных. Однако прямой доступ к буферу адаптера в режиме записи позволил бы значительно повысить эффективность обработки входного сигнала в реальном времени. Поддержка записи звука определена только для драйверов Задержки звука Подсистема MME из-за переключений между 32- и 16-разрядными режимами и неоптимальной с точки зрения адаптера структуры буферов часто дает существенную задержку (latency) между подачей звукового блока драйверу и появлением звука на выходе, равно как и в обратном направлении (при записи). DirectSound, за счет более оптимального управления адаптером, вносит задержки на уровне около 20 мс. Однако при эмуляции, когда работа идет через подсистему MME, задержки могут возрасти до 100-150 мс. Идентификация устройств В отличие от подсистем MME, идентификация устройств в DirectSound следует правилам COM и использует GUID (Globally Unique IDentifier - идентификатор, уникальный в мировом масштабе). Любой объект COM имеет свой идентификатор, по которому приложения могут обращаться к нему. Идентификаторы доступных устройств приложение получает в процессе перебора (enumeration) устройств заданного класса. Уведомление о наступлении событий Событием в подсистеме DirectSound считается достижение одной из заданных позиций в звуковом буфере. Для запроса уведомления о наступлении таких событий приложение может использовать специальный интерфейс IDirectSoundNotify, создавая соответствующие ему следящие объекты. При достижении указанных позиций следящий объект активизирует (set) заданные объекты события (event objects), которые могут быть опрошены приложением непосредственно, либо может быть создана отдельная задача (thread), ожидающая активизации одного или нескольких объектов событий. Наборы свойств DirectSound вводит понятие набора свойств (property set) - параметров, описывающих виды обработки звука. При помощи набора свойств можно описать параметры зала, голоса исполнителя, манеры пения, звучания инструментов и т.п. При наличии необходимых средств обработки одну и ту же звуковую картину можно представлять в разных ракурсах, активизируя нужные наборы свойств. В данное время эти виды обработки почти не поддерживаются; наборы свойств введены в основном на будущее. Именование интерфейсных функций Различные интерфейсы имеют наборы функций (методов) с разными именами, поэтому в ссылках я буду приводить только имена методов, не снабжая их именем интерфейса. В прототипах имена всех методов приводятся полностью, с указанием интерфейса. Поскольку ряд интерфейсов имеет схожую структуру (IDirectSound/IDirectSoundCapture, IDirectSoundBuffer/IDirectSound3DBuffer), многие методы являются общими для нескольких интерфейсов сразу. В таких случаях я буду упоминать имя интерфейса, только если в использовании одного и того же метода в разных интерфейсах существует принципиальная разница. Совместимость Интерфейсы DirecSound доступны для платформ Windows 98 или 2000 и выше. В Windows 95 интерфейсы становятся доступными после установки пакета DirectX. В Windows NT 4/SP3 доступен только базовый уровень функциональности - интерфейсы IDirectSound и Общая схема взаимодействия программы и DirectSound При создании объекта устройства указывается идентификатор устройства, которое будет через него программироваться. Приложение может либо запросить доступ к устройству по умолчанию, либо получить перечень идентификаторов доступных устройств функцией перебора - DirectSoundEnumerate или Функции перебора требуют указания локальной перебирающей функции приложения (callback), которая будет вызываться для каждого доступного устройства. Перебирающая функция может либо самостоятельно выбрать подходящее устройство, либо сформировать полный список устройств, из которого пользователь сделает выбор по своему усмотрению. Созданный объект устройства может быть опрошен методом GetCaps, возвращающим его характеристики и возможности. Таким образом может быть, например, найдено минимально и оптимально подходящее для целей приложения устройство из всех имеющихся в системе. Перед началом работы с устройством необходимо установить уровень взаимодействия методом Работа со звуком начинается с создания объектов звуковых буферов. Если приложение работает на обычном уровне взаимодействия, первичный буфер не создается. На остальных уровнях необходимо создать первичный буфер методом CreateSoundBuffer и задать его формат методом SetFormat. На обычном уровне взаимодействия формат первичного буфера фиксирован - 22 050 Гц, стерео, восемь разрядов. Объекты вторичных звуковых буферов также создаются при помощи метода CreateSoundBuffer - по одному для каждого источника звука; в этом же вызове задаются и форматы буферов. Для коротких звуков длительностью до нескольких секунд удобнее создавать статические буферы, целиком вмещающие цифровое представление звуков. Для длительных звуков рекомендуется создавать небольшие (порядка десятков-сотен килобайт) потоковые буферы, через которые будут непрерывно <прогоняться> фрагменты длительного звучания. Создав вторичный буфер, приложение должно заполнить его звуковыми данными. Процедуру занесения данных в буфер открывает метод Lock, возвращающий указатели доступных участков буфера. Эти участки заполняются данными, после чего вызывается метод Unlock, завершающий процедуру обновления данных. При желании приложение может разделить один и тот же экземпляр звучания между несколькими объектами буферов, создавая объекты-копии методом DuplicateSoundBuffer. Впоследствии, изменяя параметры звучания, можно получать различные звуки на основе одной и той же оцифровки, не расходуя дополнительную память. Для запуска воспроизведения буфера вызывается метод Play, для остановки - Stop. Чтобы определить, какой фрагмент звучит в данный момент, используется метод GetCurrentPosition, для запуска звучания с определенного места - При необходимости приложение может изменить параметры звучания в буфере: частоту дискретизации (SetFrequency), громкость (SetVolume), положение на панораме (SetPan). Для пространственных источников возможно изменение координат, ориентации, скорости движения и т.п. Для корректной работы приложение должно отслеживать ситуацию потери буферов. Получив от методов Lock или Play сообщение о потере буфера, необходимо приостановить генерацию звука и периодически выполнять метод Restore до тех пор, пока он не даст положительного результата. После этого буфер следует вновь заполнить звуковыми данными. Захват (запись) звука производится с помощью объектов устройств IDirectSoundCapture. Здесь нет разделения на первичный и вторичные буферы, поэтому методом CreateCaptureBuffer создается единственный буфер захвата, которому этим же методом приписывается нужный формат. Затем методом Start запускается захват звука, который может быть остановлен методом Stop. Для извлечения звуковых данных из буфера служат методы Lock и Unlock. Процесс захвата во многом симметричен процессу воспроизведения, поэтому в описании интерфейсов захвата упомянуты лишь их отличия от основных интерфейсов. При желании приложение может воспользоваться интерфейсом уведомления IDirectSoundNotify, запрашивая его у объектов тех буферов, для которых требуются уведомления, и заказывая установку заданных объектов программных событий (event objects) по достижении определенных позиций в буфере. Завершая работу, приложение уничтожает методом Release объекты буферов, а затем - объекты устройств. Программирование в DirectSound Средства разработки, включаемые файлы и библиотеки Описывается программирование на языке C++ в среде Microsoft Visual C++. DirectSound поддерживает программирование и из обычного C, однако использование C++ позволяет более естественно оформлять работу с интерфейсами и не ведет к какому бы то ни было увеличению объектного кода по сравнению с C, поскольку модель DirectSound изначально ориентирована на объекты и методы обращения к ним из Полный комплект DirectX 7.0a SDK занимает 128 Мбайт, однако наиболее важные его части доступны отдельно. Набор документации включаемых заголовочных файлов и библиотек занимает 1,3 Мбайт и доступен по ссылке Вместе с демонстрационной программой к статье прилагаются файлы dsound.h и dsound.lib из комплекта DirectX SDK 7.0a. Тем не менее одних этих файлов недостаточно для построения примера; среда разработки должна поддерживать хотя бы одну из версий Структуры, используемые при работе с подсистемой Все структуры имеют поле dwSize, в которое при инициализации структуры необходимо занести ее размер в байтах. Размер используется для определения версии интерфейса. Это единственное поле, которое требует обязательной инициализации во всех структурах; остальные поля заполняются, только если они являются входными. DSCAPS - параметры устройства воспроизведения DWORD dwSize;
DSBCAPS - параметры звукового буфера DWORD dwSize;
Необходимо иметь в виду, что даже если звук источников, помеченных как звучащие в фоне (когда приложение не является текущим), будет слышен при переключении на другое приложение, то этот звук может приводиться к другому формату. Например, если одно приложение использует стереофонический формат и фоновые источники и происходит переключение на приложение, устанавливающее монофонический формат, звук от фоновых источников также станет монофоническим. Если текущее приложение устанавливает менее качественный формат - звук от более качественных фоновых источников может приобретать заметные искажения вследствие понижения разрядности и/или частоты дискретизации;
DSBUFFERDESC - описатель создаваемого буфера DWORD dwSize;
Флаги LOCHARDWARE и LOCSOFTWARE являются взаимоисключающими. Они запрашивают размещение буфера в памяти адаптера или компьютера, однако не гарантируют, что это будет соблюдено. О фактическом размещении буфера можно узнать при помощи его метода Описанный формат структуры используется начиная с DirectX 7.0. До этого использовалась структура, не содержавшая поля guid3DAlgorithm; для совместимости старый формат сохранен под именем DSBUFFERDESC1. Подсистема определяет версию структуры, используя значение поля dwSize, и корректно обрабатывает наличие или отсутствие дополнительного поля. DSCCAPS - параметры устройства захвата DWORD dwSize;
DSCBCAPS - параметры буфера захвата DWORD dwSize;
DSCBUFFERDESC - описатель создаваемого буфера захвата DWORD dwSize; Различия касаются также поля dwFlags, содержащего управляющие флаги. В описываемой структуре оно может содержать только флаг DSBPOSITIONNOTIFY - описатель позиции для уведомления DWORD dwOffset;
Уведомление приложения о наступлении событий В подсистеме DirectSound существует только одно асинхронное событие - это достижение заданной позиции внутри звукового буфера. Как частный случай событие может возникать при остановке звучания буфера - методом Stop, или при естественном достижении конца буфера. Подсистема использует для уведомления только объекты программных событий (event objects). Это не так удобно, как в подсистеме MME, предоставляющей несколько видов уведомлений, однако вполне в духе многозадачной модели Win32, когда для управления буферами и перезагрузки их содержимого создается отдельная задача (thread). Эта задача не занимается ничем посторонним, ожидая установки одного из заданных объектов событий, после которой выполняет обновление отработанной части буфера. Для одного буфера может быть указано сколько угодно позиций, при достижении которых происходит уведомление. Таким образом удобно, например, разделить буфер на две или более частей, и каждое уведомление будет означать, что отработана очередная часть буфера. С помощью такого механизма достигается эффективное и в то же время плавное продвижение длительного звукового потока через буфер небольшого размера, как это и делается в звуковых драйверах низкого уровня. Набор интерфейсных функций подсистемы Описание функций распределено по разделам, каждый из которых, в свою очередь, описывает соответствующий интерфейс DirectSound. Несколько общих функций высшего уровня, не принадлежащих интерфейсам, вынесено в начало описания Перечень базовых интерфейсов DirectSound
Значения, возвращаемые функциями и методами Все функции и методы интерфейсов возвращают результат типа HRESULT, эквивалентный типу LONG. Значение DS_OK равное нулю означает успешное выполнение функции, любое другое значение указывает на ошибку. Константы для кодов ошибок имеют префиксы
Внеинтерфейсные функции высшего уровня Enumerate - перебор устройств воспроизведения или захвата HRESULT DirectSoundEnumerate ( HRESULT DirectSoundCaptureEnumerate (
EnumCallback - перебирающая функция BOOL CALLBACK EnumCallback (
Функция вызывается для каждого найденного устройства заданного класса. Если возвращается значение TRUE - перебор продолжается, если FALSE - прекращается. Create - создание объекта устройства воспроизведения или захвата HRESULT WINAPI DirectSoundCaptureCreate (
Интерфейс IUnknown Является базовым для всех интерфейсов COM и содержит средства фиксации объекта, его освобождения и запроса нужного интерфейса из набора (агрегата). QueryInterface - запрос интерфейса из набора
Обычно в качестве переменной выступает указатель объекта того типа, который имеет запрашиваемый интерфейс в своем составе. Например, при получении интерфейса IDirectSound3DBuffer из объекта с указателем Buf типа IDirectSoundBuffer вызывается метод Buf->QueryInterface (IID_IDirectSound3DBuffer, (LPVOID *)&Buf3D), где Buf3D - указатель объекта типа IDirectSound3DBuffer. Указатели Buf и Buf3D обычно ссылаются на один и тот же объект, однако рассчитывать на это не стоит. При успешном завершении функция возвращает код S_OK (нуль). Возможными кодами ошибки могут быть E_NOINTERFACE (исходный объект не имеет требуемого интерфейса) и E_POINTER (передан недопустимый указатель переменной). Счетчик ссылок полученного объекта увеличивается на единицу. При завершении работы с полученным интерфейсом необходимо освободить объект методом AddRef - фиксация объекта ULONG IUnknown::AddRef (); При завершении работы с объектом должен быть вызван метод Release, уменьшающий счетчик ссылок на единицу. Когда количество ссылок становится нулевым, объект уничтожается. Функция возвращает значение обновленного счетчика ссылок. Release - освобождение объекта ULONG IUnknown::Release (); Интерфейс IDirectSound Обслуживает объекты устройств воспроизведения. Содержит следующие методы:
Initialize - инициализация устройства HRESULT IDirectSound::Initialize (
SetCooperativeLevel - установка уровня взаимодействия HRESULT IDirectSound::SetCooperativeLevel (
CreateSoundBuffer - создание звукового буфера HRESULT IDirectSound::CreateSoundBuffer (
Если заданы флаги DSBCAPS_LOCHARDWARE, DSBCAPS_LOCSOFTWARE, подсистема сразу же пытается разместить буфер в памяти определенного типа. Если задан флаг DSBCAPS_LOCDEFER, размещение буфера откладывается до запуска его звучания. DuplicateSoundBuffer - создание копии объекта HRESULT IDirectSound::DuplicateSoundBuffer (
Метод служит для создания копии объекта, описывающего звуковой буфер, и используется для создания источников, разделяющих между собой один звуковой фрагмент. Оба объекта ссылаются на один и тот же участок памяти, и изначально их параметры полностью совпадают. Впоследствии приложение может изменять параметры каждого из объектов, что дает соответственное изменение звучания. Например, если это звук автомобиля, то методом копирования объектов можно создать звучания нескольких одинаковых автомобилей, различающихся громкостью, высотой, положением в пространстве и т.п., не затрачивая дополнительную память для самой звуковой оцифровки. GetCaps - запрос параметров и состояния устройства HRESULT IDirectSound::GetCaps ( Caps - указатель структуры DSCAPS, которая будет заполнена параметрами устройства. Перед обращением к методу должно быть установлено поле dwSize, определяющее версию интерфейса. GetSpeakerConfig - запрос конфигурации звукоизлучателей HRESULT IDirectSound::GetSpeakerConfig (
В конфигурации STEREO добавляется код расположения громкоговорителей. Имена значений кодов имеют префикс DSSPEAKER_GEOMETRY_:
SetSpeakerConfig - установка конфигурации звукоизлучателей HRESULT IDirectSound::SetSpeakerConfig (
Для объединения кодов конфигурации и расположения используется макрос DSSPEAKER_COMBINED (Config, Compact - уплотнение внутренней памяти адаптера HRESULT IDirectSound::Compact (); Для использования метода приложение должно иметь уровень взаимодействия не ниже приоритетного. Интерфейс IDirectSoundBuffer Обслуживает звуковые буферы устройства воспроизведения. Содержит следующие методы:
Initialize - инициализация объекта буфера HRESULT IDirectSoundBuffer::Initialize (
Метод инициализирует объект звукового буфера в соответствии с заданным описателем. При создании буфера методом IDirectSound::CreateSoundBuffer возвращается уже инициализированный объект буфера. Метод IDirectSoundBuffer::Initialize предназначен для унификации и будущих расширений интерфейса. Restore - восстановление памяти потерянного буфера HRESULT IDirectSoundBuffer::Restore (); После успешного восстановления буфера его содержимое не определено, поэтому необходимо вновь заполнить буфер. Поскольку любая попытка заполнения или запуска буфера может закончиться ошибкой DSERR_BUFFERLOST, рекомендуется организовать эту работу в цикле, работающем до успешного заполнения и запуска буфера, и при неудачах - дожидающегося смены состояния или просто делающего небольшие паузы. GetCaps - запрос параметров буфера HRESULT IDirectSoundBuffer::GetCaps (
Метод заполняет заданный описатель параметрами буфера, по которым можно судить о его размещении и возможностях использования. Поле флагов описывает реальные параметры размещения буфера, которые могут и не совпадать с запрошенными в описателе DSBUFFERDESC при создании буфера. GetFormat - запрос текущего формата буфера HRESULT IDirectSoundBuffer::GetFormat (
Подсистема заполняет не более, чем SizeAllocated, байтов указанной области памяти. Если описатель не помещается в отведенную область, он обрезается. Если указатель области имеет нулевое значение, в переменную по указателю SizeWritten заносится размер области памяти, необходимый для размещения полного описателя. SetFormat - установка формата буфера HRESULT IDirectSoundBuffer::SetFormat (
Метод устанавливает новый формат первичного звукового буфера. Для вторичных буферов задание формата возможно только при их создании; формат существующего объекта вторичного буфера изменить невозможно. Право установки формата первичного буфера имеют только приложения с уровнем взаимодействия не ниже На уровне доступа к первичному буферу перед сменой формата буфера необходимо остановить его работу методом Stop. На более низких уровнях, где нет прямого доступа приложения к буферу, подсистема выполняет остановку и перезапуск самостоятельно. Если первичный буфер не поддерживает устанавливаемый формат, ошибки не возникает. В этом случае подсистема устанавливает наиболее близкий формат и прозрачно преобразует звуковые данные при их занесении в буфер. Определить реально установленный формат можно при помощи метода Lock - запрос обновления данных в буфере HRESULT IDirectSoundBuffer::Lock (
При задании нулевых значений в параметрах Ptr1 и Bytes1 подсистема предоставляет доступ только к непрерывной части буфера, не выполняя <заворачивание> через границу. Метод открывает процедуру обновления данных в буфере. Не гарантируется, что возвращенные указатели будут ссылаться внутрь самого буфера и предоставленный участок памяти будет содержать какие-либо звуковые данные. При запросе обновления программного буфера метод действительно возвращает указатели на его участки, однако при работе с аппаратным буфером, размещенным в памяти адаптера, к которой нет прямого доступа со стороны процессора, подсистема вынуждена создавать временный буфер в основной памяти, указатели на который и возвращаются методом. При успешном завершении метода приложению необходимо в кратчайший срок занести в предоставленные участки буфера нужные звуковые данные, после чего вызвать метод Unlock, который завершает процедуру обновления и, если данные были записаны во временный буфер, - пересылает их в память адаптера. Недостаточно быстрое заполнение буфера может привести к его опустошению и сбоям в звучании. Unlock - завершение обновления данных в HRESULT IDirectSoundBuffer::Unlock (
Метод завершает процедуру обновления данных в буфере. Если буфер расположен в памяти адаптера и к нему нет прямого доступа со стороны процессора, метод выполняет пересылку данных из временного буфера в нужный участок памяти адаптера. Это может потребовать времени, количество которого можно оценить при помощи поля dwUnlockTransferRate описателя параметров буфера. Play - запуск звучания буфера HRESULT IDirectSoundBuffer::Play (
Флаги условий досрочного завершения звучания гарантируют, что источник будет смешиваться аппаратно, однако при нехватке ресурсов его звучание может быть досрочно прекращено. Имена констант имеют префикс DSBPLAY_TERMINATEBY_:
Флаги LOCHARDWARE и LOCSOFTWARE являются взаимоисключающими. Эти два флага, а также флаги TERMINATEBY допускаются только для буферов с отложенным размещением (флаг DSBCAPS_LOCDEFER). Метод запускает проигрывание буфера с текущей позиции воспроизведения. Для приложений, не имеющих прямого доступа к первичному буферу, первичный буфер создается и запускается автоматически при запуске первого вторичного буфера. Приложения, работающие на уровне доступа к первичному буферу, должны сами запускать его, указывая флаг Приложения более низкого уровня доступа могут использовать метод для гарантированного запуска первичного буфера, чтобы при отсутствии активных вторичных буферов адаптер не выключался (в первичном буфере в это время - <тишина>). Это позволяет избежать лишних включений/выключений адаптера и связанных с этим помех. По сути, активность первичного буфера для таких приложений зависит от внутреннего счетчика, к которому каждый последующий запуск любого буфера добавляет единицу, а остановка любого буфера - вычитает ее. При нулевом значении счетчика первичный буфер останавливается и адаптер выключается. Если буфер уже активизирован, метод лишь обновляет флаги режимов проигрывания, не затрагивая текущей позиции буфера. Перед первым с момента создания объекта устройства обращением к методу Play должен быть установлен уровень взаимодействия методом IDirectSound::SetCooperativeLevel. В противном случае метод Play завершается успешно, но звук появляется только после установки уровня взаимодействия. Stop - прекращение проигрывания буфера HRESULT IDirectSoundBuffer::Stop (); GetStatus - запрос состояния буфера HRESULT IDirectSoundBuffer::GetStatus (
Флаги LOCHARDWARE и LOCSOFTWARE являются взаимоисключающими. Они, а также флаг TERMINATED могут быть установлены только для буферов с отложенным размещением (флаг DSBCAPS_LOCDEFER). GetCurrentPosition - запрос текущих позиций буфера HRESULT IDirectSoundBuffer::GetCurrentPosition (
Позиция записи обычно опережает позицию воспроизведения на 10-15 мс. Участок буфера начиная с позиции записи и предшествующей (по правилу закольцовки буфера) позиции воспроизведения считается уже проигранным и может быть обновлен в любой момент. SetCurrentPosition - установка позиции воспроизведения буфера HRESULT IDirectSoundBuffer::SetCurrentPosition (
Метод допустим только для вторичных буферов. Проигрывание первичного буфера всегда начинается с его начала. GetFrequency - запрос частоты дискретизации HRESULT IDirectSoundBuffer::GetFrequency (
SetFrequency - установка частоты дискретизации HRESULT IDirectSoundBuffer::SetFrequency (
Метод применим только к вторичным буферам. Изменение частоты дискретизации изменяет скорость воспроизведения звука и, как следствие, его высоту. Воспроизведение звука с частотой дискретизации, отличной от используемой в первичном буфере, требует интерполяции отсчетов и при отсутствии средств аппаратного ускорения может заметно увеличить накладные расходы системы. GetPan - запрос текущего положения источника на панораме HRESULT IDirectSoundBuffer::GetPan (
SetPan - установка текущего положения источника на панораме HRESULT IDirectSoundBuffer::SetPan (
GetVolume - запрос уровня громкости источника HRESULT IDirectSoundBuffer::GetVolume (
HRESULT IDirectSoundBuffer::SetVolume (
Интерфейс IDirectSoundCapture Обслуживает объекты устройств захвата (записи). Поскольку процессы воспроизведения и захвата в большинстве своем симметричны, методы интерфейса подобны методам IDirectSound. Разница заключается лишь в типизации параметров и структур. Интерфейс содержит следующие методы:
Initialize - инициализация объекта устройства HRESULT IDirectSoundCapture::Initialize ( GetCaps - запрос параметров устройства HRESULT IDirectSoundCapture::GetCaps (
Подобен методу IDirectSound::GetCaps. CreateCaptureBuffer - создание буфера захвата HRESULT IDirectSoundCapture::CreateCaptureBuffer (
Интерфейс IDirectSoundCaptureBuffer Обслуживает буфер захвата. Подобен интерфейсу IDirectSoundBuffer, однако для каждого устройства может существовать только один буфер захвата; и нет разделения на первичный и вторичные буферы. Интерфейс содержит следующие методы:
16.02.2006 |
VSESMI.ru — новости в СМИ.
Tur-Hotel.ru — отзывы об отелях
|
|
Copyright © 2002—2010 ООО "Хостмэйк" Телефон в Москве: +7 (495) 223-46-50 Телефон в Санкт-Петербурге: +7 (812) 448-38-90 Тел./Факс: +7 (8636) 237-836 E-mail: 2006 |