Перейти на главную   
  helloworld.ru - документация и книги по программированию  
helloworld.ru - документация и книги по программированию    
    главная     хостинг     создание сайтов    
Поиск по сайту:  
Смотрите также
Языки программирования
C#
MS Visual C++
Borland C++
C++ Builder
Visual Basic
Quick Basic
Turbo Pascal
Delphi
JavaScript
Java
PHP
Perl
Assembler
AutoLisp
Fortran
Python
1C

Интернет-технологии
HTML
VRML
HTTP
CGI
FTP
Proxy
DNS
протоколы TCP/IP
Apache

Web-дизайн
HTML
Дизайн
VRML
PhotoShop
Cookie
CGI
SSI
CSS
ASP
PHP
Perl

Программирование игр
DirectDraw
DirectSound
Direct3D
OpenGL
3D-графика
Графика под DOS

Алгоритмы
Численные методы
Обработка данных

Системное программирование
Драйверы

Базы данных
MySQL
SQL

Другое

Хостинг


Друзья
demaker.ru
Реклама

Лучший хостинг. Аренда серверов




helloworld.ru

Программирование звука в DirectSound

Основные черты и понятия DirectSound

   Назначение и структура

   Смешивание сигналов

   Объемный звук

   Использование аппаратных ускорителей

   Конфигурация звукоизлучателей

   Звуковые буферы

   Размещение звуковых буферов

   Первичный и вторичные буферы

   Статические и потоковые буферы

   Порядок создания вторичных буферов

   Управление режимами вторичных буферов

   Позиции в буфере

   Уровни взаимодействия

   Потеря буферов

   Эмуляция

   Задержки звука

   Идентификация устройств

   Уведомление о наступлении событий

   Наборы свойств

   Именование интерфейсных функций

   Совместимость

Общая схема взаимодействия программы и DirectSound

Программирование в DirectSound

   Средства разработки, включаемые файлы и библиотеки

   Структуры, используемые при работе с подсистемой

      DSCAPS — параметры устройства воспроизведения

      DSBCAPS — параметры звукового буфера

      DSBUFFERDESC — описатель создаваемого буфера

      DSCCAPS — параметры устройства захвата

      DSCBCAPS — параметры буфера захвата

      DSCBUFFERDESC — описатель создаваемого буфера захвата

      DSBPOSITIONNOTIFY — описатель позиции для уведомления

   Уведомление приложения о наступлении событий

   Набор интерфейсных функций подсистемы

      Перечень базовых интерфейсов DirectSound

      Перечень внеинтерфейсных функций высшего уровня

      Значения, возвращаемые функциями и методами

   Внеинтерфейсные функции высшего уровня

      Enumerate — перебор устройств воспроизведения или захвата

      EnumCallback — перебирающая функция

      Create — создание объекта устройства воспроизведения или захвата

   Интерфейс IUnknown

      QueryInterface — запрос интерфейса из набора

      AddRef — фиксация объекта

      Release — освобождение объекта

   Интерфейс IDirectSound

      Initialize — инициализация устройства

      SetCooperativeLevel — установка уровня взаимодействия

      CreateSoundBuffer — создание звукового буфера

      DuplicateSoundBuffer — создание копии объекта буфера

      GetCaps — запрос параметров и состояния устройства

      GetSpeakerConfig — запрос конфигурации звукоизлучателей

      SetSpeakerConfig — установка конфигурации звукоизлучателей

      Compact — уплотнение внутренней памяти адаптера

   Интерфейс IDirectSoundBuffer

      Initialize — инициализация объекта буфера

      Restore — восстановление памяти потерянного буфера

      GetCaps — запрос параметров буфера

      GetFormat — запрос текущего формата буфера

      SetFormat — установка формата буфера

      Lock — запрос обновления данных в буфере

      Unlock — завершение обновления данных в буфере

      Play — запуск звучания буфера

      Stop — прекращение проигрывания буфера

      GetStatus — запрос состояния буфера

      GetCurrentPosition — запрос текущих позиций буфера

      SetCurrentPosition — установка позиции воспроизведения буфера

      GetFrequency — запрос частоты дискретизации

      SetFrequency — установка частоты дискретизации

      GetPan — запрос текущего положения источника на панораме

      SetPan — установка текущего положения источника на панораме

      GetVolume — запрос уровня громкости источника

      SetVolume — установка уровня громкости источника

   Интерфейс IDirectSoundCapture

      Initialize — инициализация объекта устройства

      GetCaps — запрос параметров устройства

      CreateCaptureBuffer — создание буфера захвата

   Интерфейс IDirectSoundCaptureBuffer

      Initialize — инициализация объекта буфера

      GetCaps — запрос параметров буфера

      GetFormat — запрос формата буфера

      GetCurrentPosition — запрос текущих позиций буфера

      GetStatus — запрос состояния буфера

      Lock — открывание процедуры извлечения данных

      Unlock — завершение процедуры извлечения данных

      Start — запуск захвата в буфер

      Stop — остановка захвата в буфер

   Интерфейс IDirectSoundNotify

      SetNotificationPositions — заказ позиций уведомления

   Интерфейс IKsPropertySet

      QuerySupport — опрос наличия поддержки свойства

      Get — запрос свойства

      Set — установка свойства

Недостатки DirectSound

Типичные применения DirectSound

Оптимизация вывода звука в DirectSound

   Оптимизация форматов

   Непрерывная работа первичного буфера

Пример программы, использующей 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 SDK.

Описания подсистем также имеются в поддерживающих их средах программирования. Более новые версии описаний распространяются Microsoft в составе DirectX SDK. Microsoft поддерживает в Internet справочную систему MSDN Online, где интерфейсы DirectX описаны в разделе http://msdn.microsoft.com/library/psdk/directx/dxstart_1x2d.htm, а сам DirectSound — в http://msdn.microsoft.com/library/psdk/directx/dsover_9dno.htm.

Основные черты и понятия DirectSound

Назначение и структура

Подсистема DirectSound обеспечивает приложениям практически непосредственный доступ к аппаратуре звукового адаптера. Этот факт вовсе не означает, что приложению приходится вникать в детали программирования того или иного адаптера — это остается прерогативой HAL. Вместо этого приложению предоставляется модель современного звукового адаптера, предельно приближенная к реальности, с минимальным уровнем абстракции. При таком подходе общение приложения с адаптером сопровождается минимальными накладными расходами, и в то же время избавляет приложение от излишних подробностей программирования аппаратуры.

Подсистема DirectSound построена по объектно-ориентированному принципу в соответствии с моделью COM (Component Object Model — модель объектов-компонентов, или составных объектов) и состоит из набора интерфейсов. Каждый интерфейс отвечает за объект определенного типа — устройство, буфер, службу уведомления и т.п. По сути, интерфейс представляет собой обычный набор управляющих функций, или методов, организованных в класс объектно-ориентированного языка.

DirectSound не поддерживает звуковые форматы, отличные от PCM. Назначение DirectSound — исключительно эффективный вывод звука, а операции по преобразованию форматов остаются в ведении приложений, которые могут использовать для этого подсистему сжатия звука (ACM).

В начало

В начало

Смешивание сигналов

Одно из наиболее неудобных ограничений 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 предоставляет приложению почти прямой доступ к аппаратным буферам адаптера. В этой концепции просто смещены акценты: вывод коротких и повторяющихся звуков значительно упрощается, а вывод длительных непрерывных звучаний несколько усложняется относительно модели MME.

В начало

В начало

Размещение звуковых буферов

Различные адаптеры используют буферы разного типа. Классические адаптеры типа Sound Blaster, Windows Sound System и совместимые с ними используют буфер в основной памяти компьютера с доступом через DMA. Адаптеры архитектуры Hurricane (Turtle Beach Tahiti, Fiji и совместимые) используют буфер в собственной (on-board) памяти, который доступен в виде «окна» в диапазоне адресов внешних устройств. Существуют также адаптеры со встроенным буфером, доступ к которому осуществляется через порты ввода-вывода; обычно так работают таблично-волновые синтезаторы.

В зависимости от размещения и способа управления различают аппаратные (hardware) и программные (software) буферы. Аппаратным называют буфер, к которому адаптер имеет прямой доступ; такой буфер располагается либо в памяти самого адаптера, либо в основной памяти с обращением через DMA или Bus Mastering. Программные буферы всегда располагаются в основной памяти и управляются центральным процессором, адаптер к таким буферам прямого доступа не имеет.

В документации по DirectSound аппаратными называют только те буферы, которые находятся в памяти адаптера, и нередко путают термин «hardware» в отношении размещения буфера и способа смешивания звука. Я буду пользоваться выражением «аппаратный буфер» — для обозначения буфера в памяти адаптера и выражением «буфер с аппаратным смешиванием», когда речь будет идти о буфере, к которому адаптер имеет прямой доступ при извлечении звука.

В начало

В начало

Первичный и вторичные буферы

Если в архитектуре адаптера один из аппаратных буферов является основным, его называют первичным (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, поэтому отсутствуют коллизии между значениями термина «запись». Для обозначения ввода звука извне я также буду пользоваться термином «захват» (capture).

Позиция воспроизведения (play) следует за позицией записи (write) в буфер, а позиция чтения (read) — за позицией захвата (capture). Достижение позицией воспроизведения позиции записи означает полное проигрывание буфера воспроизведения, при этом начинают воспроизводиться «старые» данные, которые приложение не успело перезаписать. Достижение позицией захвата позиции чтения означает переполнение буфера захвата, и последующие данные накладываются на «старые», которые приложение не успело извлечь из буфера.

В начало

В начало

Уровни взаимодействия

DirectSound вводит четыре уровня взаимодействия (cooperation levels) приложений между собой и звуковым адаптером. Когда несколько приложений одновременно используют один и тот же адаптер, соотношение уровней взаимодействия определяет их приоритетность в использовании аппаратуры и создании звучания.

  • Обычный (normal) уровень фиксирует формат первичного буфера адаптера — 22 050 Гц, стерео, 8-разрядные отсчеты. Форматы вторичных буферов преобразуются в этот формат, и при переключении приложений подсистеме нет необходимости изменять формат первичного буфера. На этом уровне достигается наибольшая универсальность и, кроме того, эффективность, однако качество звука в таком формате весьма посредственно и не допускается уплотнение (оптимизация) внутренней памяти адаптера.
  • Приоритетный (priority) уровень позволяет приложению устанавливать формат первичного буфера и уплотнять внутреннюю память адаптера — то есть предоставляет приоритетный доступ к аппаратным ресурсам, когда окно приложения становится активным (foreground). Если происходит переключение между приложениями этого уровня, установившими различные форматы первичного буфера, — подсистема вынуждена переключать форматы, для чего необходим перезапуск адаптера, нередко порождающий щелчки и тому подобные помехи.
  • Исключительный (exclusive) уровень подобен приоритетному, но на время активности окна приложения ему предоставляется исключительный доступ к адаптеру, и звучание источников всех остальных приложений заглушается (но не останавливается).
  • Уровень доступа к первичному буферу (write-primary) разрешает приложению прямую запись в первичный буфер адаптера. Этот уровень доступен только для устройств, имеющих специализированный DirectSound-драйвер. На этом уровне приложение может работать только с первичным буфером, активизация вторичных буферов запрещена.
В начало

В начало

Потеря буферов

Когда приложение, запросившее высший (write-primary) уровень взаимодействия, становится активным, подсистеме приходится передавать ему управление первичным буфером, теряя при этом собственный контроль над ним. И наоборот, когда активным становится приложение с менее высоким уровнем, подсистема возвращает себе контроль над буфером, но теперь его теряет «уходящее в фон» приложение. В этой ситуации, называемой потерей буферов (buffer lose), буфер прекращает звучание и его содержимое теряется.

Когда приложение высшего уровня становится активным, звучание всех вторичных буферов приложений более низких уровней останавливается, а сами буферы помечаются как потерянные. Это происходит потому, что подсистема не может правильно отслеживать текущие позиции во вторичных буферах, не имея доступа к первичному буферу адаптера. И наоборот, когда приложение высшего уровня становится неактивным, его первичный буфер также помечается как потерянный.

Приложения получают сообщение о потере буферов при попытках обращения к ним в виде кода ошибки DSERR_BUFFERLOST. Все приложения должны корректно обрабатывать эту ситуацию и выполнять восстановление потерянных буферов.

В начало

В начало

Эмуляция

Подсистема DirectSound может обходиться без поддержки со стороны драйвера. В этом случае нужная функциональность эмулируется через MME — традиционную звуковую подсистему Windows. Однако такая эмуляция крайне неэффективна, поскольку при этом подсистеме DirectSound приходится эмулировать первичный буфер в обычной памяти, смешивать в нем звуки из вторичных буферов, затем представлять его в виде цепочки буферов, передаваемых драйверу MME, который, в свою очередь, разбивает их на фрагменты и переносит в звуковой буфер адаптера. При этом каждое обращение к драйверу MME сопровождается переключением в 16-разрядный режим и обратно.

Отметим, что без наличия специализированного DirectSound-драйвера невозможно получить высший (write-primary) уровень взаимодействия с адаптером.

Тем не менее поддержка захвата (capture) звука в DirectSound реализована только методом эмуляции. Для драйверов DirectSound VxD определены лишь функции поддержки воспроизведения — дальше в унификации этого интерфейса Microsoft почему-то не пошла. Операции записи и воспроизведения с точки зрения адаптера почти идентичны и различаются в основном направлением движения данных. Однако прямой доступ к буферу адаптера в режиме записи позволил бы значительно повысить эффективность обработки входного сигнала в реальном времени. Поддержка записи звука определена только для драйверов WDM.

В начало

В начало

Задержки звука

Подсистема 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 и IDirectSoundBuffer.

В начало

В начало

Общая схема взаимодействия программы и DirectSound

Приложение начинает работу с DirectSound, создавая объект устройства с интерфейсом IDirectSound — для воспроизведения звука или IDirectSoundCapture — для захвата (записи) звука. Объект устройства воспроизведения создается функцией DirectSoundCreate, объект устройства захвата — DirectSoundCaptureCreate.

При создании объекта устройства указывается идентификатор устройства, которое будет через него программироваться. Приложение может либо запросить доступ к устройству по умолчанию, либо получить перечень идентификаторов доступных устройств функцией перебора — DirectSoundEnumerate или DirectSoundCaptureEnumerate.

Функции перебора требуют указания локальной перебирающей функции приложения (callback), которая будет вызываться для каждого доступного устройства. Перебирающая функция может либо самостоятельно выбрать подходящее устройство, либо сформировать полный список устройств, из которого пользователь сделает выбор по своему усмотрению.

Созданный объект устройства может быть опрошен методом GetCaps, возвращающим его характеристики и возможности. Таким образом может быть, например, найдено минимально и оптимально подходящее для целей приложения устройство из всех имеющихся в системе.

Перед началом работы с устройством необходимо установить уровень взаимодействия методом SetCooperativeLevel.

Работа со звуком начинается с создания объектов звуковых буферов. Если приложение работает на обычном уровне взаимодействия, первичный буфер не создается. На остальных уровнях необходимо создать первичный буфер методом CreateSoundBuffer и задать его формат методом SetFormat. На обычном уровне взаимодействия формат первичного буфера фиксирован — 22 050 Гц, стерео, восемь разрядов.

Объекты вторичных звуковых буферов также создаются при помощи метода CreateSoundBuffer — по одному для каждого источника звука; в этом же вызове задаются и форматы буферов. Для коротких звуков длительностью до нескольких секунд удобнее создавать статические буферы, целиком вмещающие цифровое представление звуков. Для длительных звуков рекомендуется создавать небольшие (порядка десятков-сотен килобайт) потоковые буферы, через которые будут непрерывно «прогоняться» фрагменты длительного звучания.

Создав вторичный буфер, приложение должно заполнить его звуковыми данными. Процедуру занесения данных в буфер открывает метод Lock, возвращающий указатели доступных участков буфера. Эти участки заполняются данными, после чего вызывается метод Unlock, завершающий процедуру обновления данных.

При желании приложение может разделить один и тот же экземпляр звучания между несколькими объектами буферов, создавая объекты-копии методом DuplicateSoundBuffer. Впоследствии, изменяя параметры звучания, можно получать различные звуки на основе одной и той же оцифровки, не расходуя дополнительную память.

Для запуска воспроизведения буфера вызывается метод Play, для остановки — Stop. Чтобы определить, какой фрагмент звучит в данный момент, используется метод GetCurrentPosition, для запуска звучания с определенного места — SetCurrentPosition.

При необходимости приложение может изменить параметры звучания в буфере: частоту дискретизации (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 изначально ориентирована на объекты и методы обращения к ним из C++.

Полный комплект DirectX 7.0a SDK занимает 128 Мбайт, однако наиболее важные его части доступны отдельно. Набор документации включаемых заголовочных файлов и библиотек занимает 1,3 Мбайт и доступен по ссылке http://download.microsoft.com/download/win98SE/DXSDK/7.0/W9X/EN-US/dx7libhdr.exe.

Вместе с демонстрационной программой к статье прилагаются файлы dsound.h и dsound.lib из комплекта DirectX SDK 7.0a. Тем не менее одних этих файлов недостаточно для построения примера; среда разработки должна поддерживать хотя бы одну из версий DirectX.

В начало

В начало

Структуры, используемые при работе с подсистемой

Все структуры имеют поле dwSize, в которое при инициализации структуры необходимо занести ее размер в байтах. Размер используется для определения версии интерфейса. Это единственное поле, которое требует обязательной инициализации во всех структурах; остальные поля заполняются, только если они являются входными.

В начало

В начало

DSCAPS — параметры устройства воспроизведения

Данная структура описывает возможности и параметры устройства воспроизведения. Для удобства определен тип LPCDSCAPS — константный указатель на тип DSCAPS.

DWORD   dwSize;
 DWORD   dwFlags;
 DWORD   dwMinSecondarySampleRate;
 DWORD   dwMaxSecondarySampleRate;
 DWORD   dwPrimaryBuffers;
 DWORD   dwMaxHwMixingAllBuffers;
 DWORD   dwMaxHwMixingStaticBuffers;
 DWORD   dwMaxHwMixingStreamingBuffers;
 DWORD   dwFreeHwMixingAllBuffers;
 DWORD   dwFreeHwMixingStaticBuffers;
 DWORD   dwFreeHwMixingStreamingBuffers;
 DWORD   dwMaxHw3DAllBuffers;
 DWORD   dwMaxHw3DStaticBuffers;
 DWORD   dwMaxHw3DStreamingBuffers;
 DWORD   dwFreeHw3DAllBuffers;
 DWORD   dwFreeHw3DStaticBuffers;
 DWORD   dwFreeHw3DStreamingBuffers;
 DWORD   dwTotalHwMemBytes;
 DWORD   dwFreeHwMemBytes;
 DWORD   dwMaxContigFreeHwMemBytes;
 DWORD   dwUnlockTransferRateHwBuffers;
 DWORD   dwPlayCpuOverheadSwBuffers;
 DWORD   dwReserved1;
 DWORD   dwReserved2;
  • dwSize — размер структуры в байтах;
  • dwFlags — флаги характеристик устройства. Имена флагов имеют префикс DSCAPS_:

CONTINUOUSRATE

Устройство поддерживает любые значения частоты дискретизации — от минимальной до максимальной с точностью примерно до 10 Гц. Отсутствие этого флага означает поддержку только стандартных частот — 8000, 11 025, 22 050 и т.д.

PRIMARY16BIT

В первичном буфере поддерживаются 16-разрядные форматы

PRIMARY8BIT

В первичном буфере поддерживаются 8-разрядные форматы

PRIMARYMONO

В первичном буфере поддерживаются монофонические форматы

PRIMARYSTEREO

В первичном буфере поддерживаются стереофонические форматы

SECONDARY16BIT

Аппаратный микшер поддерживает вторичные буферы в 16-разрядных форматах

SECONDARY8BIT

Аппаратный микшер поддерживает вторичные буферы в 8-разрядных форматах

SECONDARYMONO

Аппаратный микшер поддерживает вторичные буферы в монофонических форматах

SECONDARYSTEREO

Аппаратный микшер поддерживает вторичные буферы в стереофонических форматах

EMULDRIVER

Устройство не имеет специализированного драйвера, и DirectSound эмулирует интерфейсы посредством стандартной подсистемы MME/Wave

CERTIFIED

Драйвер устройства проверен и сертифицирован Microsoft

  • dwMinSecondarySampleRate, dwMaxSecondarySampleRate — минимальная и максимальная частота дискретизации, поддерживаемая для аппаратных вторичных буферов;
  • dwPrimaryBuffers — количество поддерживаемых первичных буферов. В текущей модели всегда равно единице;
  • dwMaxHwMixingAllBuffers — максимальное общее количество поддерживаемых буферов с аппаратным смешиванием. Может быть меньше суммы числа статических и потоковых буферов из-за различия способов их организации в аппаратуре;
  • dwMaxHwMixingStaticBuffers — максимальное количество статических звуковых буферов с аппаратным смешиванием;
  • dwMaxHwMixingStreamingBuffers — максимальное количество потоковых звуковых буферов с аппаратным смешиванием;
  • dwFreeHwMixingAllBuffers, dwFreeHwMixingStaticBuffers, dwFreeHwMixingStreamingBuffers — количество свободных буферов с аппаратным смешиванием — всех, статических и потоковых;
  • dwMaxHw3DAllBuffers, dwMaxHw3DStaticBuffers, dwMaxHw3DStreamingBuffers — максимальное количество аппаратных буферов для источников объемного звука — всех, статических и потоковых;
  • dwFreeHw3DAllBuffers, dwFreeHw3DStaticBuffers, dwFreeHw3DStreamingBuffers — количество свободных аппаратных буферов для источников объемного звука — всех, статических и потоковых.
  • dwTotalHwMemBytes — общий объем внутренней памяти адаптера, доступной для размещения статических буферов;
  • dwFreeHwMemBytes — объем свободной внутренней памяти адаптера;
  • dwMaxContigFreeHwMemBytes — объем наибольшего непрерывного участка внутренней памяти адаптера;
  • dwUnlockTransferRateHwBuffers — скорость пересылки данных из основной памяти в память адаптера (Кбайт/с). Пересылка выполняется при вызове метода Unlock, время отработки метода может быть определено из значения этого поля и объема занесенных в буфер звуковых данных;
  • dwPlayCpuOverheadSwBuffers — приблизительная доля времени центрального процессора (в %), необходимая для смешивания звука из буферов, расположенных в основной памяти;
  • dwReserved1, dwReserved2 — служебные поля.
В начало

В начало

DSBCAPS — параметры звукового буфера

Структура описывает возможности и параметры существующего звукового буфера. Для удобства определен тип LPCDSBCAPS — константный указатель на тип DSBCAPS.

DWORD   dwSize;
 DWORD   dwFlags;
 DWORD   dwBufferBytes;
 DWORD   dwUnlockTransferRate;
 DWORD   dwPlayCpuOverhead;
  • dwSize — размер структуры в байтах;
  • dwFlags — флаги возможностей, параметров и режимов буфера. Имена констант флагов имеют префикс DSBCAPS_:/

PRIMARYBUFFER

Буфер является первичным. Если флаг не установлен — буфер является вторичным

STATIC

Буфер является статическим

LOCHARDWARE

Буфер размещается в памяти адаптера

LOCSOFTWARE

Буфер размещается в основной памяти

LOCDEFER

Размещение буфера в определенном типе памяти отложено до момента его активизации

CTRL3D

Допускается управление пространственным звучанием (координаты, скорость, ориентация и т.п.). Флаг относится к расширению DirectSound3D

CTRLFREQUENCY

Допускается управление частотой дискретизации

CTRLPAN

Допускается управление панорамой (стереобалансом)

CTRLVOLUME

Допускается управление громкостью

CTRLPOSITIONNOTIFY

Допускается заказ уведомлений о достижении заданных позиций буфера. Перед проигрыванием такого буфера необходимо заказать уведомление посредством интерфейса IDirectSoundNotify

GETCURRENTPOSITION2

Метод GetCurrentPosition возвращает более правильное положение позиции воспроизведения для эмулируемых устройств. В первой версии DirectX, за счет задержек при эмуляции метод возвращал позицию, значительно опережающую реальное звучание. В последующих версиях была введена компенсация, вычисление которой включается при задании этого флага

GLOBALFOCUS

Источник звука, представленный буфером, является глобальным и будет звучать независимо от того, является приложение текущим (foreground) или нет. Однако, если текущим становится приложение с исключительным или более высоким уровнем взаимодействия, «чужие» источники звука всегда заглушаются

STICKYFOCUS

Источник звука, представленный буфером, будет звучать при переключении на приложения, не использующие DirectSound. Обычные источники, не объявленные глобальными, заглушаются, если текущим становится другое приложение. Этим флагом рекомендуется снабжать источники фонового звука — например, музыки. Однако, если текущим становится приложение, использующее DirectSound, источники с этим флагом также заглушаются

MUTE3DATMAXDISTANCE

Звучание источника должно быть остановлено при достижении максимального расстояния от слушателя, где звук перестает быть слышимым. В этот момент DirectSound прекращает снижать громкость источника и останавливает его, во избежание лишних расходов. При уменьшении расстояния звучание будет запущено автоматически. Этот флаг относится только к буферам, описывающим пространственные источники

Необходимо иметь в виду, что даже если звук источников, помеченных как звучащие в фоне (когда приложение не является текущим), будет слышен при переключении на другое приложение, то этот звук может приводиться к другому формату. Например, если одно приложение использует стереофонический формат и фоновые источники и происходит переключение на приложение, устанавливающее монофонический формат, звук от фоновых источников также станет монофоническим. Если текущее приложение устанавливает менее качественный формат — звук от более качественных фоновых источников может приобретать заметные искажения вследствие понижения разрядности и/или частоты дискретизации;

  • dwBufferBytes — размер буфера в байтах;
  • dwUnlockTransferRate — скорость загрузки данных в буфер (килобайт в секунду). Для буферов, расположенных в основной памяти, скорость обычно значительно выше, чем для расположенных в памяти адаптера. Это значение позволяет оценить время выполнения метода Unlock, осуществляющего пересылку данных в буфер;
  • dwPlayCpuOverhead — доля процессорного времени (в %), необходимая для добавления (смешивания) звучания данного буфера в общий звук. Для буферов с аппаратным смешиванием это значение равно нулю, для программно смешиваемых оно зависит от скорости процессора, формата этого и первичного буферов.
В начало

В начало

DSBUFFERDESC — описатель создаваемого буфера

Структура описывает конфигурацию и свойства создаваемого звукового буфера. Для удобства определен тип LPDSBUFFERDESC — указатель на тип DSBUFFERDESC.

DWORD dwSize;
 DWORD dwFlags;
 DWORD dwBufferBytes;
 DWORD dwReserved;
 LPWAVEFORMATEX lpwfxFormat;
 GUID guid3DAlgorithm;
  • dwSize — размер структуры в байтах;
  • dwFlags — флаги параметров и режимов работы буфера. Определены в описании слова флагов структуры DSBCAPS;
  • dwBufferBytes — размер буфера в байтах. При создании первичного буфера должно быть задано нулевое значение, так как размеры первичных буферов определяются подсистемой. Фактический размер созданного первичного буфера можно узнать посредством его метода GetCaps. Для вторичных буферов размер должен лежать в диапазоне от DSBSIZE_MIN до DSBSIZE_MAX;
  • dwReserved — служебное поле;
  • lpwfxFormat — адрес структуры WAVEFORMATEX, описывающей формат буфера. Для первичного буфера поле должно иметь нулевое значение — формат первичного буфера всегда устанавливается методом SetFormat;
  • guid3DAlgorithm — алгоритм моделирования объемного звука системой из двух звукоизлучателей (громкоговорителей или наушников). Относится только к буферам пространственных источников, используемых в DirectSound3D. Для обычных моно- и стереоисточников значение поля игнорируется.

Флаги LOCHARDWARE и LOCSOFTWARE являются взаимоисключающими. Они запрашивают размещение буфера в памяти адаптера или компьютера, однако не гарантируют, что это будет соблюдено. О фактическом размещении буфера можно узнать при помощи его метода GetCaps.

Описанный формат структуры используется начиная с DirectX 7.0. До этого использовалась структура, не содержавшая поля guid3DAlgorithm; для совместимости старый формат сохранен под именем DSBUFFERDESC1. Подсистема определяет версию структуры, используя значение поля dwSize, и корректно обрабатывает наличие или отсутствие дополнительного поля.

В начало

В начало

DSCCAPS — параметры устройства захвата

Описывает возможности и параметры устройства записи (захвата). Для удобства определен тип LPCDSCCAPS — константный указатель на тип DSCCAPS.

DWORD   dwSize;
 DWORD   dwFlags;
 DWORD   dwFormats;
 DWORD   dwChannels;
  • dwSize — размер структуры в байтах;
  • dwFlags — флаги параметров устройства. Имена констант имеют префикс DSCCAPS_:

EMULDRIVER

Для устройства нет специализированного драйвера DirectSound, и интерфейсы эмулируются подсистемой через стандартные функции MME

CERTIFIED

Драйвер является сертифицированным драйвером WDM

  • dwFormats — стандартные форматы, поддерживаемые устройством. Флаги форматов эквивалентны используемым в структуре MME WAVEINCAPS. Имена констант флагов имеют вид WAVE_FORMAT_fcnn, где f — символ частоты дискретизации (1 — 11025 Гц, 2 — 22050 Гц, 4 — 44100 Гц), c — символ количества каналов (M — моно, S — стерео), а nn — разрядность отсчета (08 или 16). Таким образом, всего определено 12 стандартных форматов;
  • dwChannels — количество каналов устройства (1 — моно, 2 — стерео, и т.п.).
В начало

В начало

DSCBCAPS — параметры буфера захвата

Описывает параметры существующего буфера захвата. Для удобства определен тип LPCDSCBCAPS — константный указатель на тип DSCBCAPS.

DWORD   dwSize;
 DWORD   dwFlags;
 DWORD   dwBufferBytes;
 DWORD   dwReserved;
  • dwSize — размер структуры в байтах;
  • dwFlags — флаги параметров. Пока определен только один флаг — DSCBCAPS_WAVEMAPPED, разрешающий использование Wave Mapper для форматов, не поддерживаемых устройством непосредственно и для которых в работу неявно может быть включена подсистема сжатия ACM;
  • dwBufferBytes — размер буфера в байтах;
  • dwReserved — служебное поле.
В начало

В начало

DSCBUFFERDESC — описатель создаваемого буфера захвата

Описывает конфигурацию и свойства создаваемого буфера захвата. Для удобства определен тип LPDSCBUFFERDESC — указатель на тип DSCBUFFERDESC.

DWORD dwSize;
 DWORD dwFlags;
 DWORD dwBufferBytes;
 DWORD dwReserved;
 LPWAVEFORMATEX   lpwfxFormat.

Как видно, структура аналогична DSBUFFERDESC, за исключением поля guid3DAlgorithm. В версиях DirectX до 7.0, где в структуре DSBUFFERDESC этого поля не было, форматы описателей создаваемых буферов для устройств воспроизведения и записи были тождественны.

Различия касаются также поля dwFlags, содержащего управляющие флаги. В описываемой структуре оно может содержать только флаг DSCBCAPS_WAVEMAPPED.

В начало

В начало

DSBPOSITIONNOTIFY — описатель позиции для уведомления

Описывает позицию звукового буфера, при достижении которой выполняется уведомление. Определен также вспомогательный тип LPDSBPOSITIONNOTIFY — указатель структуры.

DWORD   dwOffset;
 HANDLE   hEventNotify;
  • dwOffset — смещение от начала буфера, при достижении которого должно быть выполнено уведомление. Специальное значение DSBPN_OFFSETSTOP запрашивает уведомление в момент остановки звучания — либо методом Stop, либо при достижении конца буфера;
  • hEventNotify — ключ объекта события (event object handle), который устанавливается (set) для выполнения уведомления.

Если для буфера разрешено досрочное прекращение звучания при нехватке аппаратных ресурсов и звучание буфера прекращается по этой причине, уведомление не выполняется.

В начало

В начало

Уведомление приложения о наступлении событий

В подсистеме DirectSound существует только одно асинхронное событие — это достижение заданной позиции внутри звукового буфера. Как частный случай событие может возникать при остановке звучания буфера — методом Stop, или при естественном достижении конца буфера.

Подсистема использует для уведомления только объекты программных событий (event objects). Это не так удобно, как в подсистеме MME, предоставляющей несколько видов уведомлений, однако вполне в духе многозадачной модели Win32, когда для управления буферами и перезагрузки их содержимого создается отдельная задача (thread). Эта задача не занимается ничем посторонним, ожидая установки одного из заданных объектов событий, после которой выполняет обновление отработанной части буфера.

Для одного буфера может быть указано сколько угодно позиций, при достижении которых происходит уведомление. Таким образом удобно, например, разделить буфер на две или более частей, и каждое уведомление будет означать, что отработана очередная часть буфера. С помощью такого механизма достигается эффективное и в то же время плавное продвижение длительного звукового потока через буфер небольшого размера, как это и делается в звуковых драйверах низкого уровня.

В начало

В начало

Набор интерфейсных функций подсистемы

Описание функций распределено по разделам, каждый из которых, в свою очередь, описывает соответствующий интерфейс DirectSound. Несколько общих функций высшего уровня, не принадлежащих интерфейсам, вынесено в начало описания.

В начало

В начало

Перечень базовых интерфейсов DirectSound

IUnknown

Базовый интерфейс для всех объектов COM

IDirectSound

Интерфейс устройства воспроизведения

IDirectSoundBuffer

Интерфейс буфера воспроизведения

IDirectSoundCapture

Интерфейс устройства захвата

IDirectSoundCaptureBuffer

Интерфейс буфера захвата

IDirectSoundNotification

Интерфейс уведомления

IKsPropertySet

Интерфейс дополнительных наборов свойств

В начало

В начало

Перечень внеинтерфейсных функций высшего уровня

DirectSoundEnumerate

Перебор устройств воспроизведения

DirectSoundCreate

Создание объекта устройства воспроизведения

DirectSoundCaptureEnumerate

Перебор устройств захвата

DirectSoundCaptureCreate

Создание объекта устройства захвата

В начало

В начало

Значения, возвращаемые функциями и методами

Все функции и методы интерфейсов возвращают результат типа HRESULT, эквивалентный типу LONG. Значение DS_OK равное нулю означает успешное выполнение функции, любое другое значение указывает на ошибку. Константы для кодов ошибок имеют префиксы DSERR_:

 

ACCESSDENIED

Доступ запрещен

ALLOCATED

Запрошенный ресурс занят

ALREADYINITIALIZED

Объект уже инициализирован

BADFORMAT

Запрошенный формат не поддерживается

BUFFERLOST

Буфер потерян и должен быть восстановлен

CONTROLUNAVAIL

Запрошенный вид управления буфером недоступен — не поддерживается или не был заказан при создании буфера

GENERIC

Неустановленная ошибка внутри подсистемы

HWUNAVAIL

Аппаратура адаптера недоступна

INVALIDCALL

Метод недопустим в текущем состоянии объекта

INVALIDPARAM

Функции передан неверный параметр

NOAGGREGATION

Объект не поддерживает дополнительных интерфейсов

NODRIVER

Нет доступного драйвера

NOINTERFACE

Запрошенный интерфейс COM недоступен

OTHERAPPHASPRIO

Другое приложение имеет более высокий уровень взаимодействия

OUTOFMEMORY

Недостаточно памяти

PRIOLEVELNEEDED

Недостаточно высок уровень взаимодействия приложения

UNINITIALIZED

Объект не инициализирован

UNSUPPORTED

Операция не поддерживается

В начало

В начало

Внеинтерфейсные функции высшего уровня

Enumerate — перебор устройств воспроизведения или захвата

HRESULT DirectSoundEnumerate (
    LPDSENUMCALLBACK EnumCallback,
    LPVOID Context
 );

HRESULT DirectSoundCaptureEnumerate (
    DSENUMCALLBACK EnumCallback,
    VOID *Context
 );
  • EnumCallback — указатель перебирающей функции, которая будет вызываться для каждого обнаруженного устройства;
  • Context — произвольное 32-разрядное значение, которое будет передаваться перебирающей функции при каждом вызове. Например, это может быть описатель параметров искомого устройства, указатель области памяти для найденного идентификатора и т.п.
В начало

В начало

EnumCallback — перебирающая функция

BOOL CALLBACK EnumCallback (
    LPGUID GUID,
    LPCSTR Description,
    LPCSTR Module,
    VOID *Context
 );
  • GUID — указатель идентификатора очередного найденного устройства;
  • Description — строка названия устройства;
  • Module — строка имени модуля драйвера устройства;
  • Context — 32-разрядное значение, заданное в функции Enumerate.

Функция вызывается для каждого найденного устройства заданного класса. Если возвращается значение TRUE — перебор продолжается, если FALSE — прекращается.

В начало

В начало

Create — создание объекта устройства воспроизведения или захвата

HRESULT WINAPI DirectSoundCreate (
    LPCGUID GUID,
    LPDIRECTSOUND *Dev,
    LPUNKNOWN   Outer
 );

HRESULT WINAPI DirectSoundCaptureCreate (
    LPCGUID GUID,
    LPDIRECTSOUNDCAPTURE *Dev,
    LPUNKNOWN Outer
 );
  • GUID — указатель идентификатора устройства либо нулевое значение для использования стандартного устройства;
  • Dev — указатель переменной, в которую будет занесен указатель созданного объекта;
  • Outer — указатель наружного интерфейса COM. Не используется, должен иметь нулевое значение.

После успешного создания устройства воспроизведения, до начала проигрывания звуковых источников приложение должно установить уровень взаимодействия методом SetCooperativeLevel.

В начало

В начало

Интерфейс IUnknown

Является базовым для всех интерфейсов COM и содержит средства фиксации объекта, его освобождения и запроса нужного интерфейса из набора (агрегата).

В начало

В начало

QueryInterface — запрос интерфейса из набора

HRESULT IUnknown::QueryInterface (
      REFIID IID,
      LPVOID *Obj
   );
  • IID — идентификатор (GUID) требуемого интерфейса;
  • Obj — указатель переменной, в которую будет занесен указатель объекта, имеющего требуемый интерфейс.

Если объект, для которого интерфейс IUnknown является базовым, имеет указанный интерфейс, то в заданную переменную заносится указатель объекта, через который доступен запрашиваемый интерфейс.

Обычно в качестве переменной выступает указатель объекта того типа, который имеет запрашиваемый интерфейс в своем составе. Например, при получении интерфейса IDirectSound3DBuffer из объекта с указателем Buf типа IDirectSoundBuffer вызывается метод

Buf->QueryInterface (IID_IDirectSound3DBuffer, (LPVOID *)&Buf3D),

где Buf3D — указатель объекта типа IDirectSound3DBuffer. Указатели Buf и Buf3D обычно ссылаются на один и тот же объект, однако рассчитывать на это не стоит.

При успешном завершении функция возвращает код S_OK (нуль). Возможными кодами ошибки могут быть E_NOINTERFACE (исходный объект не имеет требуемого интерфейса) и E_POINTER (передан недопустимый указатель переменной).

Счетчик ссылок полученного объекта увеличивается на единицу. При завершении работы с полученным интерфейсом необходимо освободить объект методом Release.

В начало

В начало

AddRef — фиксация объекта

ULONG IUnknown::AddRef ();

Увеличивает счетчик ссылок объекта на единицу. При создании объекта счетчик устанавливается в единицу, при получении нового интерфейса счетчик автоматически увеличивается на единицу.

При завершении работы с объектом должен быть вызван метод Release, уменьшающий счетчик ссылок на единицу. Когда количество ссылок становится нулевым, объект уничтожается.

Функция возвращает значение обновленного счетчика ссылок.

В начало

В начало

Release — освобождение объекта

ULONG IUnknown::Release ();

Уменьшает счетчик ссылок объекта на единицу. При обнулении счетчика объект уничтожается. Метод должен вызываться для всех объектов, полученных приложением, при завершении работы с ними.

В начало

В начало

Интерфейс IDirectSound

Обслуживает объекты устройств воспроизведения. Содержит следующие методы:

 

Initialize

Инициализация устройства

SetCooperativeLevel

Установка уровня взаимодействия с аппаратурой

CreateSoundBuffer

Создание звукового буфера

DuplicateSoundBuffer

Создание копии объекта буфера

GetCaps

Запрос возможностей и параметров устройства

Compact

Уплотнение внутренней памяти звукового адаптера

GetSpeakerConfig

Запрос конфигурации звукоизлучателей

SetSpeakerConfig

Установка конфигурации звукоизлучателей

В начало

В начало

Initialize — инициализация устройства

HRESULT IDirectSound::Initialize (
    LPCGUID GUID
 );
  • GUID — идентификатор устройства либо нулевое значение для выбора стандартного устройства.

Метод используется для объектов, созданных не специальной функциями Create, а стандартным для COM методом CoCreateInstance. Функции Create возвращают инициализированный объект, в то время как CoCreateInstance — объект-заготовку, который не связан с конкретным устройством.

В начало

В начало

SetCooperativeLevel — установка уровня взаимодействия

HRESULT IDirectSound::SetCooperativeLevel (
    HWND Win,
    DWORD Level
 );
  • Win — ключ окна (window handle), по положению которого определяется состояние приложения. Когда окно становится текущим (foreground), приложение также считается текущим, и наоборот. Если приложение использует DirectDraw, то в методах установки уровня DirectDraw и DirectSound должно использоваться одно и то же окно.
  • Level — запрашиваемый уровень взаимодействия. Имена констант кодов уровней имеют префикс DSSCL_:;

NORMAL

Обычный уровень. Формат первичного буфера фиксирован. Когда приложение является текущим, звучат только его собственные источники, а также источники других приложений, помеченные флагом DSBCAPS_GLOBALFOCUS

PRIORITY

Приоритетный уровень. Подобен обычному, но допускаются смена формата первичного буфера и уплотнение памяти адаптера. Когда приложение становится текущим, подсистема переключает формат выводимого через адаптер звука

EXCLUSIVE

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

WRITEPRIMARY

Уровень доступа к первичному буферу. Разрешается прямой доступ к первичному буферу, однако запрещается использование вторичных буферов. Установка уровня допускается только для устройств, имеющих драйвер DirectSound (флаг DSCAPS_EMULDRIVER в свойствах устройства не установлен)

В начало

В начало

CreateSoundBuffer — создание звукового буфера

HRESULT IDirectSound::CreateSoundBuffer (
    LPCDSBUFFERDESC BufferDesc,
    LPDIRECTSOUNDBUFFER *Buffer,
    IUnknown *Outer
 );
  • BufferDesc — указатель заполненного описателя создаваемого буфера (структура DSBUFFERDESC);
  • Buffer — указатель переменной, в которую будет занесен указатель созданного объекта буфера;
  • Outer — указатель объекта «наружного» интерфейса IUnknown. Не используется, должен иметь нулевое значение.

Метод создает звуковой — первичный или вторичный буфер, в зависимости от состояния флага DSBCAPS_PRIMARYBUFFER. При создании буфера должны быть указаны способы управления (флаги DSBCAPS_CTRLxxx), которые будут использоваться при проигрывании буфера.

Если заданы флаги DSBCAPS_LOCHARDWARE, DSBCAPS_LOCSOFTWARE, подсистема сразу же пытается разместить буфер в памяти определенного типа. Если задан флаг DSBCAPS_LOCDEFER, размещение буфера откладывается до запуска его звучания.

В начало

В начало

DuplicateSoundBuffer — создание копии объекта буфера

HRESULT IDirectSound::DuplicateSoundBuffer (
    LPDIRECTSOUNDBUFFER Original,
    LPLPDIRECTSOUNDBUFFER Duplicate
 );
  • Original — указатель копируемого объекта;
  • Duplicate — указатель переменной, в которую заносится указатель объекта-копии.

Метод служит для создания копии объекта, описывающего звуковой буфер, и используется для создания источников, разделяющих между собой один звуковой фрагмент. Оба объекта ссылаются на один и тот же участок памяти, и изначально их параметры полностью совпадают. Впоследствии приложение может изменять параметры каждого из объектов, что дает соответственное изменение звучания. Например, если это звук автомобиля, то методом копирования объектов можно создать звучания нескольких одинаковых автомобилей, различающихся громкостью, высотой, положением в пространстве и т.п., не затрачивая дополнительную память для самой звуковой оцифровки.

В начало

В начало

GetCaps — запрос параметров и состояния устройства

HRESULT IDirectSound::GetCaps (
    DSCAPS *Caps
 );
  • Caps — указатель структуры DSCAPS, которая будет заполнена параметрами устройства. Перед обращением к методу должно быть установлено поле dwSize, определяющее версию интерфейса.
В начало

В начало

GetSpeakerConfig — запрос конфигурации звукоизлучателей

HRESULT IDirectSound::GetSpeakerConfig (
    DWORD *Config
 );
  • Config — адрес переменной, в которую будет занесен код текущей конфигурации звукоизлучателей для данного устройства. Имена констант значений кодов имеют префикс DSSPEAKER_:;

MONO

Одиночный громкоговоритель

STEREO

Стереофонические громкоговорители; (стандартно)

HEADPHONE

Наушники

QUAD

Квадрафонические громкоговорители

SURROUND

Громкоговорители, включенные по системе Surround

5POINT1

Громкоговорители Surround с добавлением общего низкочастотного (subwoofer)

В конфигурации STEREO добавляется код расположения громкоговорителей. Имена значений кодов имеют префикс DSSPEAKER_GEOMETRY_:

 

MIN

Под углом в 5°

NARROW

Под углом в 10°

WIDE

Под углом в 20°

MAX

Под углом в 180°

Для выделения из двойного слова кодов конфигурации и расположения используются макросы DSSPEAKER_CONFIG и DSSPEAKER_GEOMETRY.

В начало

В начало

SetSpeakerConfig — установка конфигурации звукоизлучателей

HRESULT IDirectSound::SetSpeakerConfig (
    DWORD Config
 );
  • Config — набор флагов, описывающих конфигурацию.

Метод устанавливает новую конфигурацию звукоизлучателей, которая будет учитываться при создании результирующей звуковой картины.

Для объединения кодов конфигурации и расположения используется макрос DSSPEAKER_COMBINED (Config, Geometry).

В начало

В начало

Compact — уплотнение внутренней памяти адаптера

HRESULT IDirectSound::Compact ();

Метод выполняет уплотнение внутренней памяти адаптера, устраняя фрагментацию и собирая все неиспользуемые фрагменты в один непрерывный участок.

Для использования метода приложение должно иметь уровень взаимодействия не ниже приоритетного.

В начало

В начало

Интерфейс IDirectSoundBuffer

Обслуживает звуковые буферы устройства воспроизведения. Содержит следующие методы:

 

Initialize

Инициализация объекта буфера

Restore

Восстановление памяти потерянного буфера

GetCaps

Запрос параметров буфера

GetFormat

Запрос формата буфера

SetFormat

Установка формата буфера

GetStatus

Запрос состояния буфера

GetCurrentPosition

Запрос текущих позиций в буфере

SetCurrentPosition

Установка текущей позиции воспроизведения в буфере

Lock

Запрос обновления данных в буфере

Unlock

Завершение обновления данных в буфере

Play

Запуск воспроизведения буфера

Stop

Остановка воспроизведения буфера

GetVolume

Запрос текущей громкости звука

SetVolume

Установка текущей громкости звука

GetPan

Запрос текущей позиции на панораме

SetPan

Установка текущей позиции на панораме

GetFrequency

Запрос текущей частоты дискретизации

SetFrequency

Установка текущей частоты дискретизации

В начало

В начало

Initialize — инициализация объекта буфера

HRESULT IDirectSoundBuffer::Initialize (
    DIRECTSOUND *DevObj,
    LPCDSBUFFERDESC BufferDesc
 );
  • DevObj — указатель объекта устройства DirectSound;
  • BufferDesc — указатель описателя буфера (структура DSBUFFERDESC).

Метод инициализирует объект звукового буфера в соответствии с заданным описателем. При создании буфера методом IDirectSound::CreateSoundBuffer возвращается уже инициализированный объект буфера. Метод IDirectSoundBuffer::Initialize предназначен для унификации и будущих расширений интерфейса.

В начало

В начало

Restore — восстановление памяти потерянного буфера

HRESULT IDirectSoundBuffer::Restore ();

Метод восстанавливает память и параметры потерянного звукового буфера. Попытка восстановления буфера также может завершиться ошибкой DSERR_BUFFERLOST; это означает, что текущим в данный момент по-прежнему является приложение с более высоким уровнем взаимодействия. В этом случае необходимо дождаться, пока приложение само станет текущим либо конкурирующее приложение снизит свой уровень.

После успешного восстановления буфера его содержимое не определено, поэтому необходимо вновь заполнить буфер. Поскольку любая попытка заполнения или запуска буфера может закончиться ошибкой DSERR_BUFFERLOST, рекомендуется организовать эту работу в цикле, работающем до успешного заполнения и запуска буфера, и при неудачах — дожидающегося смены состояния или просто делающего небольшие паузы.

В начало

В начало

GetCaps — запрос параметров буфера

HRESULT IDirectSoundBuffer::GetCaps (
    DSBCAPS *Caps
 );
  • Caps — указатель описателя параметров буфера (структура DSBCAPS), который будет заполнен подсистемой. Поле dwSize должно быть установлено до обращения к методу.

Метод заполняет заданный описатель параметрами буфера, по которым можно судить о его размещении и возможностях использования. Поле флагов описывает реальные параметры размещения буфера, которые могут и не совпадать с запрошенными в описателе DSBUFFERDESC при создании буфера.

В начало

В начало

GetFormat — запрос текущего формата буфера

HRESULT IDirectSoundBuffer::GetFormat (
    WAVEFORMATEX *Format,
    DWORD SizeAllocated,
    DWORD *SizeWritten
 );
  • Format — указатель области памяти для описателя формата (структура WAVEFORMATEX), который будет заполнен параметрами формата буфера, или нуль;
  • SizeAllocated — размер в байтах области памяти описателя;
  • SizeWritten — указатель переменной, в которую будет занесен реальный размер заполненного описателя, или нуль, если размер не требуется.

Подсистема заполняет не более, чем SizeAllocated, байтов указанной области памяти. Если описатель не помещается в отведенную область, он обрезается.

Если указатель области имеет нулевое значение, в переменную по указателю SizeWritten заносится размер области памяти, необходимый для размещения полного описателя.

В начало

В начало

SetFormat — установка формата буфера

HRESULT IDirectSoundBuffer::SetFormat (
    LPCWAVEFORMATEX Format
 );
  • Format — указатель описателя формата (структура WAVEFORMATEX).

Метод устанавливает новый формат первичного звукового буфера. Для вторичных буферов задание формата возможно только при их создании; формат существующего объекта вторичного буфера изменить невозможно.

Право установки формата первичного буфера имеют только приложения с уровнем взаимодействия не ниже приоритетного. Подсистема поддерживает только форматы PCM.

На уровне доступа к первичному буферу перед сменой формата буфера необходимо остановить его работу методом Stop. На более низких уровнях, где нет прямого доступа приложения к буферу, подсистема выполняет остановку и перезапуск самостоятельно.

Если первичный буфер не поддерживает устанавливаемый формат, ошибки не возникает. В этом случае подсистема устанавливает наиболее близкий формат и прозрачно преобразует звуковые данные при их занесении в буфер. Определить реально установленный формат можно при помощи метода GetFormat.

В начало

В начало

Lock — запрос обновления данных в буфере

HRESULT IDirectSoundBuffer::Lock (
    DWORD WriteCursor,
    DWORD WriteBytes,
    LPVOID *Ptr1,
    DWORD *Bytes1,
    LPVOID *Ptr2,
    DWORD *Bytes2,
    DWORD Flags
 );
  • Cursor — смещение (относительно начала буфера) участка, к которому запрашивается прямой доступ;
  • Bytes — размер участка в байтах;
  • Ptr1, Ptr2 — указатели переменных, в которых будут возвращены указатели частей полученного участка памяти. Поскольку буферы фактически являются кольцевыми, полученный участок может пересекать границу буфера и «заворачиваться» на его начало. Если получен непрерывный участок, в переменной Ptr2 возвращается нулевое значение, иначе этот указатель всегда ссылается на начало буфера;
  • Bytes1, Bytes2 — указатели переменных, в которых будут возвращены размеры частей полученного участка памяти. Если получен непрерывный участок, в переменной Bytes2 возвращается нулевое значение;
  • Flags — флаги, уточняющие операцию. Имена констант флагов имеют префикс DSBLOCK_:

FROMWRITECURSOR

Запрашивается участок буфера начиная с позиции (курсора) записи. В этом случае параметр Cursor игнорируется

ENTIREBUFFER

Запрашивается доступ ко всему доступному для записи участку буфера. В этом случае параметр Bytes игнорируется

При задании нулевых значений в параметрах Ptr1 и Bytes1 подсистема предоставляет доступ только к непрерывной части буфера, не выполняя «заворачивание» через границу.

Метод открывает процедуру обновления данных в буфере. Не гарантируется, что возвращенные указатели будут ссылаться внутрь самого буфера и предоставленный участок памяти будет содержать какие-либо звуковые данные. При запросе обновления программного буфера метод действительно возвращает указатели на его участки, однако при работе с аппаратным буфером, размещенным в памяти адаптера, к которой нет прямого доступа со стороны процессора, подсистема вынуждена создавать временный буфер в основной памяти, указатели на который и возвращаются методом.

При успешном завершении метода приложению необходимо в кратчайший срок занести в предоставленные участки буфера нужные звуковые данные, после чего вызвать метод Unlock, который завершает процедуру обновления и, если данные были записаны во временный буфер, — пересылает их в память адаптера. Недостаточно быстрое заполнение буфера может привести к его опустошению и сбоям в звучании.

В начало

В начало

Unlock — завершение обновления данных в буфере

HRESULT IDirectSoundBuffer::Unlock (
    VOID *Ptr1,
    DWORD Bytes1,
    VOID *Ptr2,
    DWORD Bytes2
 );
  • Ptr1, Ptr2 — указатели обновленных участков буфера, возвращенные ранее методом Lock;
  • Bytes1, Bytes2 — количества байтов, реально записанных в обновленные участки.

Метод завершает процедуру обновления данных в буфере. Если буфер расположен в памяти адаптера и к нему нет прямого доступа со стороны процессора, метод выполняет пересылку данных из временного буфера в нужный участок памяти адаптера. Это может потребовать времени, количество которого можно оценить при помощи поля dwUnlockTransferRate описателя параметров буфера.

В начало

В начало

Play — запуск звучания буфера

HRESULT IDirectSoundBuffer::Play (
    DWORD Reserved,
    DWORD Priority,
    DWORD Flags
 );
  • Reserved — зарезервированный параметр, должен иметь нулевое значение;
  • Priority — приоритет данного источника звука, если при создании буфера был указан флаг отложенного размещения DSBCAPS_LOCDEFER. В этом случае подсистема стремится обеспечить аппаратное смешивание для источников с наибольшими значениями приоритета. Если флаг отложенного размещения не был указан, этот параметр должен иметь нулевое значение;
  • Flags — флаги, уточняющие операцию. Имена констант флагов имеют префикс DSBPLAY_:

LOOPING

Циклическое проигрывание. Буфер проигрывается непрерывно, по достижении конца позиция воспроизведения автоматически перебрасывается в начало. Первичный буфер может работать только в циклическом режиме

LOCHARDWARE

Требует обязательного аппаратного смешивания для данного источника. При нехватке ресурсов аппаратного смешивания и отсутствии условий досрочного завершения звучания операция завершается с ошибкой

LOCSOFTWARE

Разрешает программное смешивание для данного источника. Выбор конкретного способа смешивания остается за подсистемой

Флаги условий досрочного завершения звучания гарантируют, что источник будет смешиваться аппаратно, однако при нехватке ресурсов его звучание может быть досрочно прекращено. Имена констант имеют префикс DSBPLAY_TERMINATEBY_:

 

TIME

Разрешает прекращать звучание источника, которому осталось меньше всего времени до естественного завершения

DISTANCE

Разрешает прекращать звучание источника, наиболее удаленного от слушателя и имеющего в свойствах флаг DSBCAPS_ MUTE3DBYDISTANCE. Допускается только для буферов пространственных источников. Этот флаг несовместим с предыдущим

PRIORITY

Разрешает прекращать звучание источника, если требуется запустить источник более высокого приоритета (параметр Priority)

Флаги LOCHARDWARE и LOCSOFTWARE являются взаимоисключающими. Эти два флага, а также флаги TERMINATEBY допускаются только для буферов с отложенным размещением (флаг DSBCAPS_LOCDEFER).

Метод запускает проигрывание буфера с текущей позиции воспроизведения. Для приложений, не имеющих прямого доступа к первичному буферу, первичный буфер создается и запускается автоматически при запуске первого вторичного буфера. Приложения, работающие на уровне доступа к первичному буферу, должны сами запускать его, указывая флаг LOOPING.

Приложения более низкого уровня доступа могут использовать метод для гарантированного запуска первичного буфера, чтобы при отсутствии активных вторичных буферов адаптер не выключался (в первичном буфере в это время — «тишина»). Это позволяет избежать лишних включений/выключений адаптера и связанных с этим помех. По сути, активность первичного буфера для таких приложений зависит от внутреннего счетчика, к которому каждый последующий запуск любого буфера добавляет единицу, а остановка любого буфера — вычитает ее. При нулевом значении счетчика первичный буфер останавливается и адаптер выключается.

Если буфер уже активизирован, метод лишь обновляет флаги режимов проигрывания, не затрагивая текущей позиции буфера.

Перед первым с момента создания объекта устройства обращением к методу Play должен быть установлен уровень взаимодействия методом IDirectSound::SetCooperativeLevel. В противном случае метод Play завершается успешно, но звук появляется только после установки уровня взаимодействия.

В начало

В начало

Stop — прекращение проигрывания буфера

HRESULT IDirectSoundBuffer::Stop ();

Метод останавливает проигрывание буфера. Для вторичного буфера сохраняется текущая позиция воспроизведения. Для первичного буфера, к которому приложение имеет уровень прямого доступа, позиция при остановке сбрасывается в нуль. Для приложений менее высоких уровней взаимодействия метод уменьшает счетчик активности первичного буфера на единицу; то же самое происходит и при остановке любого из вторичных буферов. При достижении счетчиком нулевого значения первичный буфер останавливается. При ненулевом значении счетчика и отсутствии активных вторичных буферов в первичном буфере проигрывается тишина.

В начало

В начало

GetStatus — запрос состояния буфера

HRESULT IDirectSoundBuffer::GetStatus (
    DWORD *Status
 );
  • Status — указатель переменной, в которую будут возвращены флаги состояния буфера. Имена констант флагов имеют префикс DSBSTATUS_:

LOCHARDWARE

Используется аппаратное смешивание

LOCSOFTWARE

Используется программное смешивание

PLAYING

Буфер активен (проигрывается)

LOOPING

Буфер проигрывается циклически. Может быть установлен только при наличии предыдущего флага

TERMINATED

Проигрывание буфера досрочно прекращено из-за нехватки аппаратных ресурсов

BUFFERLOST

Буфер потерян

Флаги LOCHARDWARE и LOCSOFTWARE являются взаимоисключающими. Они, а также флаг TERMINATED могут быть установлены только для буферов с отложенным размещением (флаг DSBCAPS_LOCDEFER).

В начало

В начало

GetCurrentPosition — запрос текущих позиций буфера

HRESULT IDirectSoundBuffer::GetCurrentPosition (
    DWORD *PlayCursor,
    DWORD *WriteCursor
 );
  • PlayCursor — указатель переменной, в которой будет возвращено смещение позиции воспроизведения буфера;
  • WriteCursor — указатель переменной, в которой будет возвращено смещение позиции записи (обновления данных) буфера.

Позиции в буфере возвращаются в виде байтовых смещений. Если какая-либо позиция не нужна, соответствующий указатель может быть нулевым.

Позиция записи обычно опережает позицию воспроизведения на 10-15 мс. Участок буфера начиная с позиции записи и предшествующей (по правилу закольцовки буфера) позиции воспроизведения считается уже проигранным и может быть обновлен в любой момент.

В начало

В начало

SetCurrentPosition — установка позиции воспроизведения буфера

HRESULT IDirectSoundBuffer::SetCurrentPosition (
    DWORD PlayPosition
 );
  • PlayPosition — новая позиция воспроизведения в виде байтового смещения от начала буфера.

Метод допустим только для вторичных буферов. Проигрывание первичного буфера всегда начинается с его начала.

В начало

В начало

GetFrequency — запрос частоты дискретизации

HRESULT IDirectSoundBuffer::GetFrequency (
    DWORD *Frequency
 );
  • Frequency — указатель переменной, в которой будет возвращено текущее значение частоты дискретизации буфера (в Гц, или отсчетах в секунду).
В начало

В начало

SetFrequency — установка частоты дискретизации

HRESULT IDirectSoundBuffer::SetFrequency (
    DWORD Frequency
 );
  • Frequency — новое значение частоты дискретизации буфера (в Гц, или отсчетов в секунду). Должно быть в диапазоне между DSBFREQUENCY_MIN (обычно 100) и DSBFREQUENCY_MAX (обычно 100000). Значение DSBFREQUENCY_ORIGINAL возвращает частоту, заданную исходным форматом при создании буфера.

Метод применим только к вторичным буферам. Изменение частоты дискретизации изменяет скорость воспроизведения звука и, как следствие, его высоту. Воспроизведение звука с частотой дискретизации, отличной от используемой в первичном буфере, требует интерполяции отсчетов и при отсутствии средств аппаратного ускорения может заметно увеличить накладные расходы системы.

В начало

В начало

GetPan — запрос текущего положения источника на панораме

HRESULT IDirectSoundBuffer::GetPan (
    LONG *Pan
 );
  • Pan — указатель переменной, в которой возвращается текущее положение источника звука на стереопанораме. Смысл значения раскрыт в описании метода SetPan.
В начало

В начало

SetPan — установка текущего положения источника на панораме

HRESULT IDirectSoundBuffer::SetPan (
    LONG Pan
 );
  • Pan — новое положение источника на стереопанораме. Знак значения задает ослабляемый канал (минус — правый, плюс — левый), абсолютная величина — степень ослабления громкости канала в сотых долях децибела. Значение DSBPAN_CENTER (нуль) означает центральное положение (оба канала имеют полную громкость). Значения DSBPAN_LEFT (минус 10000) и DSBPAN_RIGHT (10000) дают ослабление правого/левого канала на 100 дБ.
В начало

В начало

GetVolume — запрос уровня громкости источника

HRESULT IDirectSoundBuffer::GetVolume (
    LONG *Volume
 );
  • Volume — указатель переменной, в которой возвращается текущее значение уровня громкости источника. Смысл значения раскрыт в описании метода SetVolume.
В начало

В начало

SetVolume — установка уровня громкости источника

HRESULT IDirectSoundBuffer::SetVolume (
    LONG Volume
 );
  • Volume — новое значение уровня громкости источника в сотых долях децибела. Уровень 0 дБ (DSBVOLUME_MAX) соответствует исходному уровню цифрового сигнала в буфере. Определена также константа DSBVOLUME_MIN (минус 10000), задающая уровень —100 дБ. Усиление сигнала относительно исходного уровня в данной реализации не поддерживается.
В начало

В начало

Интерфейс IDirectSoundCapture

Обслуживает объекты устройств захвата (записи). Поскольку процессы воспроизведения и захвата в большинстве своем симметричны, методы интерфейса подобны методам IDirectSound. Разница заключается лишь в типизации параметров и структур.

Интерфейс содержит следующие методы:

 

Initialize

Инициализация объекта устройства

GetCaps

Запрос параметров и возможностей устройства

CreateCaptureBuffer

Создание буфера захвата

В начало

В начало

Initialize — инициализация объекта устройства

HRESULT IDirectSoundCapture::Initialize (
    LPCGUID GUID
 );

Подобен методу IDirectSound::Initialize.

В начало

В начало

GetCaps — запрос параметров устройства

HRESULT IDirectSoundCapture::GetCaps (
    DSCCAPS *Caps
 );
  • Caps — указатель описателя параметров устройства захвата (структура DSCCAPS).

Подобен методу IDirectSound::GetCaps.

В начало

В начало

CreateCaptureBuffer — создание буфера захвата

HRESULT IDirectSoundCapture::CreateCaptureBuffer (
    DSCBUFFERDESC *BufferDesc,
    LPDIRECTSOUNDCAPTUREBUFFER *Buffer,
    UNKNOWN *Outer
 );
  • BufferDesc — указатель описателя создаваемого буфера (структура DSCBUFFERDESC);
  • Buffer — указатель переменной, в которой будет возвращен указатель созданного объекта буфера;
  • Outer — указатель объекта «наружного» интерфейса IUnknown. Не используется, должен иметь нулевое значение.

Подобен методу IDirectSound::CreateSoundBuffer. В отличие от процесса воспроизведения, допускающего смешивание нескольких источников, процесс захвата допускает наличие только одного буфера, и здесь нет разделения на первичный и вторичные буферы.

В начало

В начало

Интерфейс IDirectSoundCaptureBuffer

Обслуживает буфер захвата. Подобен интерфейсу IDirectSoundBuffer, однако для каждого устройства может существовать только один буфер захвата; и нет разделения на первичный и вторичные буферы.

Интерфейс содержит следующие методы:

 

Initialize

Инициализация объекта буфера

GetCaps

Запрос параметров буфера

GetFormat

Запрос формата буфера

GetCurrentPosition

Запрос текущих позиций в буфере

GetStatus

Запрос состояния буфера

Lock

Запрос обновления данных в буфере

Unlock

Завершение обновления данных в буфере

Start

Запуск захвата в буфер

Stop

Остановка захвата в буфер

В начало

В начало

Initialize — инициализация объекта буфера

HRESULT IDirectSoundCaptureBuffer::Initialize (
    DIRECTSOUNDCAPTURE *CaptureDev,
    LPCDSCBUFFERDESC BufferDesc
 );
  • CaptureDev — указатель объекта устройства захвата;
  • BufferDesc — указатель описателя буфера (структура DSCBUFFERDESC).

Метод подобен IDirectSoundBuffer::Initialize.

В начало

В начало

GetCaps — запрос параметров буфера

HRESULT IDirectSoundCaptureBuffer::GetCaps (
    DSCBCAPS *Caps
 );
  • Caps — указатель описателя параметров буфера захвата (структура DSCBCAPS).

Метод подобен IDirectSoundBuffer::GetCaps.

В начало

В начало

GetFormat — запрос формата буфера

HRESULT IDirectSoundCaptureBuffer::GetFormat (
    WAVEFORMATEX *Format,
    DWORD SizeAllocated,
    DWORD *SizeWritten
 );
  • Format — указатель области памяти для описателя формата (структура WAVEFORMATEX), который будет заполнен параметрами формата буфера, или;
  • SizeAllocated — размер в байтах области памяти описателя;
  • SizeWritten — указатель переменной, в которую будет занесен реальный размер заполненного описателя, или нуль, если размер не требуется;

Метод подобен IDirectSoundBuffer::GetFormat.

В начало

В начало

GetCurrentPosition — запрос текущих позиций буфера

HRESULT IDirectSoundCaptureBuffer::GetCurrentPosition (
    DWORD *CaptureCursor,
    DWORD *ReadCursor
 );
  • CaptureCursor — указатель переменной, в которой будет возвращено смещение позиции захвата буфера;
  • ReadCursor — указатель переменной, в которой будет возвращено смещение позиции чтения буфера.

Метод подобен IDirectSoundBuffer::GetCurrentPosition. Разница заключается в изменении положения позиций: при захвате позиция чтения следует за позицией захвата, «догоняя» ее.

В начало

В начало

GetStatus — запрос состояния буфера

HRESULT IDirectSoundCaptureBuffer::GetStatus (
    DWORD *Status
 );
  • Status — указатель переменной, в которую будут возвращены флаги состояния буфера. Имена констант флагов имеют префикс DSCBSTATUS_:

CAPTURING

Буфер активен (идет захват)

LOOPING

Буфер зациклен (по достижении конца позиция захвата перебрасывается в начало)

Метод подобен IDirectSoundBuffer::GetStatus.

В начало

В начало

Lock — открывание процедуры извлечения данных

HRESULT IDirectSoundCaptureBuffer::Lock (
    DWORD Cursor,
    DWORD Bytes,
    LPVOID *Ptr1,
    DWORD *Bytes1,
    LPVOID *Ptr2,
    DWORD *Bytes2,
    DWORD Flags
 );
  • Cursor — смещение (относительно начала буфера) участка, к которому запрашивается прямой доступ;
  • Bytes — размер участка в байтах;
  • Ptr1, Ptr2 — указатели переменных, в которых будут возврашены указатели частей полученного участка памяти;
  • Bytes1, Bytes2 — указатели переменных, в которых будут возвращены размеры частей полученного участка памяти;
  • Flags — флаги, уточняющие операцию. Имена констант флагов имеют префикс DSCBLOCK_:

ENTIREBUFFER

Запрашивается доступ ко всей доступной для чтения части буфера. Параметр Bytes игнорируется

Метод подобен IDirectSoundBuffer::Lock.

В начало

В начало

Unlock — завершение процедуры извлечения данных

HRESULT IDirectSoundCaptureBuffer::Unlock (
    VOID *Ptr1,
    DWORD Bytes1,
    VOID *Ptr2,
    DWORD Bytes2
 );
  • Ptr1, Ptr2 — указатели прочитанных участков буфера, возвращенные ранее методом Lock;
  • Bytes1, Bytes2 — количества байтов, реально считанных из участков

Метод подобен IDirectSoundBuffer::Unlock.

В начало

В начало

Start — запуск захвата в буфер

HRESULT IDirectSoundCaptureBuffer::Start (
    DWORD Flags
 );
  • Flags — флаги, уточняющие операцию. Имена констант флагов имеют префикс DSCBSTART_:

LOOPING

Циклический захват — позиция захвата по достижении конца буфера автоматически перебрасывается в начало. Захват продолжается до тех пор, пока не будет остановлен методом Stop

Метод подобен IDirectSoundBuffer::Play.

В начало

В начало

Stop — остановка захвата в буфер

HRESULT IDirectSoundCaptureBuffer::Stop ();

Метод подобен IDirectSoundBuffer::Stop.

В начало

В начало

Интерфейс IDirectSoundNotify

Обслуживает объекты уведомления. Имеет единственный метод SetNotificationPositions.

В начало

В начало

SetNotificationPositions — заказ позиций уведомления

HRESULT IDirectSoundNotify::SetNotificationPositions (
    DWORD NumOfNotifies,
    LPCDSBPOSITIONNOTIFY Notifies
 );
  • NumOfNotifies — количество заказанных описателей уведомления в массиве Notifies;
  • Notifies — массив описателей уведомления, по одному на позицию.

Метод описывает позиции воспроизведения или захвата, по достижении которых должны быть установлены указанные объекты событий. В момент выполнения метода буфер должен быть неактивным (остановленным).

Если заказано уведомление в случае остановки буфера (DSBPN_OFFSETSTOP), такой описатель должен быть в массиве последним.

Повторные вызовы метода заменяют список уведомлений для буфера.

Если поддержка DirectSound для устройства реализована в виде драйвера VxD, уведомление доступно только для буферов, размещенных в основной памяти. При поддержке в виде драйвера WDM буфер может находиться в памяти адаптера.

В начало

В начало

Интерфейс IKsPropertySet

Обслуживает объекты звуковых буферов DirectSound и является частью модели WDM KS (Windows Driver Model, Kernel Streaming). Позволяет связывать с источниками звука различные наборы свойств.

Интерфейс запрашивается у объекта буфера воспроизведения или записи посредством метода QueryInterface и содержит следующие методы:

 

QuerySupport

Опрос наличия поддержки указанного набора свойств

Get

Опрос свойства

Set

Установка свойства

В начало

В начало

QuerySupport — опрос наличия поддержки свойства

HRESULT IKsPropertySet::QuerySupport (
    REFGUID SetGUID,
    ULONG Index,
    ULONG *Support
 );
  • SetGUID — ссылка (в C++) или адрес (C) GUID опрашиваемого набора свойств;
  • Index — индекс (номер) нужного свойства в наборе — начиная с нуля;
  • Support — указатель переменной, в которой возвращается информация о поддержке указанного свойства.

При успешном завершении метод возвращает в переменную Support информацию о поддержке указанного свойства и о возможных операциях с ним. При отсутствии указанного набора или свойства возвращается нуль, иначе возвращается комбинация из флагов KSPROPERTY_SUPPORT_GET (свойство допускает опрос) и KSPROPERTY_SUPPORT_SET (свойство допускает установку).

При отсутствии поддержки свойства или набора некоторые реализации могут возвращать код ошибки E_NOTIMPL.

В начало

В начало

Get — запрос свойства

HRESULT IKsPropertySet::Get (
    REFGUID SetGUID,
    ULONG Index,
    VOID *Instance,
    ULONG InstanceLength,
    VOID *Property,
    ULONG PropertyLength,
    ULONG *BytesReturned
 );
  • SetGUID — ссылка (в C++) или адрес (C) GUID опрашиваемого набора свойств;
  • Index — индекс (номер) нужного свойства в наборе — начиная с нуля;
  • Instance — указатель области данных, уточняющих операцию запроса свойства;
  • InstanceLength — размер области уточняющих данных;
  • Property — указатель области данных, в которой возвращается описание свойства;
  • PropertyLength — размер области данных для описания свойства;
  • BytesReturned — указатель переменной, в которой возвращается количество байтов, реально занесенное в область описания свойства.

Возвращаемое методом значение и содержимое области описания свойства зависят от реализации набора свойств и самого опрашиваемого свойства.

В начало

В начало

Set — установка свойства

HRESULT IKsPropertySet::Set (
    REFGUID SetGUID,
    ULONG Index,
    VOID *Instance,
    ULONG InstanceLength,
    VOID *Property,
    ULONG PropertyLength,
 );
  • SetGUID — ссылка (в C++) или адрес (C) GUID опрашиваемого набора свойств;
  • Index — индекс (номер) нужного свойства в наборе — начиная с нуля;
  • Instance — указатель области данных, уточняющих операцию установки свойства;
  • InstanceLength — размер области уточняющих данных;
  • Property — указатель области данных, содержащей описание свойства.
  • PropertyLength — размер области описания свойства.
В начало

В начало

Недостатки DirectSound

В основном недостатки DirectSound являются обратной стороной достоинств подсистемы. Ориентация на существующие звуковые ускорители впоследствии может оказаться несовместимой с новыми моделями аппаратуры, а текущая модель DirectSound — неэффективной.

Упор на работу с короткими звуками несколько затрудняет работу с длительными звуковыми потоками, однако это достаточно легко преодолевается.

В начало

В начало

Типичные применения DirectSound

Основным применением, ради которого разрабатывалась подсистема, являются игры. Созданная модель позволяет очень удобно описать множество источников звука, снабдить их параметрами, разместить в пространстве, а в ходе игры — оперативно включать и выключать их, управлять параметрами звучания, изменяя звуковую картину.

DirectSound находит также массовое применение в программах синтеза звука и музыки, которым средства подсистемы позволяют описывать звучания отдельных музыкальных инструментов или их частей, а затем в реальном времени сводить эти звучания воедино.

Благодаря возможности смешивания звука и более эффективного использования аппаратуры, с помощью DirectSound удобно реализуется одновременное воспроизведение длительных звуковых фрагментов и управление ими. Например, естественно строятся программы имитации звуковых микшерных пультов, аппаратуры для дискотек и тому подобные средства управления звуком.

В начало

В начало

Оптимизация вывода звука в DirectSound

Оптимизация форматов

Поскольку звучания всех вторичных буферов в конечном итоге смешиваются в первичном буфере адаптера, подсистеме или адаптеру приходится преобразовывать звуковые данные к единому формату. Адаптеры с поддержкой аппаратного смешивания всегда делают это с достаточной скоростью, обеспечивая одновременное звучание заявленного количества каналов. Однако при программном смешивании все преобразования выполняет сама подсистема, а это требует интерполяции отсчетов и специального способа суммирования (так называемое суммирование с насыщением). Все это отнимает изрядную долю процессорного времени и при количестве каналов больше нескольких единиц начинает заметно сказываться на скорости работы системы.

Для предотвращения роста накладных расходов при программном смешивании рекомендуется придерживаться унифицированных форматов первичного и вторичных буферов. Более всего времени отнимает преобразование частоты дискретизации, затем количества каналов; преобразование разрядности отсчетов почти не вносит задержек.

Для оптимизации работы ускорителя полезно определить методом IDirectSound::GetCaps аппаратно поддерживаемые форматы и использовать только их.

Помимо этого для коротких и постоянных по составу звуков рекомендуется создавать буферы статического типа.

В начало

В начало

Непрерывная работа первичного буфера

По умолчанию DirectSound включает воспроизведение первичного буфера при активизации одного или нескольких вторичных буферов и выключает первичный буфер, когда активных вторичных буферов не остается. При большой динамичности чередования звуков из вторичных буферов рост частоты включений/выключений может вызвать существенные накладные расходы. Кроме того, многие звуковые адаптеры издают достаточно громкие щелчки при запуске и остановке процесса воспроизведения.

Указанных проблем можно избежать, установив первичный буфер в режим непрерывной работы при помощи метода Play. С этого момента буфер будет «прокручиваться» непрерывно; при отсутствии активных вторичных буферов в первичном буфере будет только «тишина» (нулевые, нейтральные звуковые отсчеты). Перевод буфера в стандартный режим осуществляется методом Stop.

В начало

В начало

Пример программы, использующей DirectSound

В качестве примера приведена программа PlaySound, демонстрирующая использование DirectSound.

Программа работает с устройством на приоритетном уровне взаимодействия, чтобы иметь возможность установить формат 44100/16/моно. Стандартный формат 22 050/8/стерео дает слишком низкое качество звучания.

Для оптимизации аппаратного ускорения вторичные буферы сделаны статическими. Звуковой фрагмент зацикливается, так что образуется непрерывное органное звучание.

Для простоты программа не обрабатывает ситуацию потери буферов, поэтому в случае конфликта с приложением высшего уровня взаимодействия звучание прекратится до перезапуска каждого из буферов.

Звук выводится на стандартное системное устройство DirectSound.

Программа написана на C++ в среде Microsoft Visual C++ 4.2.

КомпьютерПресс 12'2000










helloworld.ru © 2001-2016
Все права защищены
Rambler's Top100 TopList Rambler's Top100