Программирование звука в DirectSound
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 заносится размер области памяти, необходимый для размещения полного описателя.