Программирование звука в DirectSound
Страница 20. Интерфейс IDirectSoundBuffer


 

Интерфейс 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 дБ. Усиление сигнала относительно исходного уровня в данной реализации не поддерживается.

 

 
« Предыдущая статья   Следующая статья »