Программирование звука в DirectSound
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.