Программирование звука в DirectSound
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 и содержит средства фиксации объекта, его освобождения и запроса нужного интерфейса из набора (агрегата).