Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming / GameProg / RPG_Programming_2ed.pdf
Скачиваний:
240
Добавлен:
12.02.2016
Размер:
12.06 Mб
Скачать

Глава 4. Воспроизведение звуков и музыки с DirectX Audio и Direct Show

Установка уровня кооперации — это работа функции IDirectSound8::SetCooperativeLevel. Есть четыре возможных уровня

кооперации, и они перечислены в таблице 4.2. Каждому соответствует собственный макрос, определенный в DirectSound.

Вот прототип функции IDirectSound8::SetCooperativeLevel:

IDirectSound8::SetCooperativeLevel(

HWND hwnd, // Дескриптор родительского окна DWORD dwLevel); // Уровень кооперации из таблицы 4.2

Какой уровень кооперации использовать? Вообще-то это зависит от типа создаваемого приложения. Для полноэкранных приложений используйте монопольный уровень. В других случаях я рекомендую приоритетный уровень. Будьте бдительны, когда используете уровень отличный от нормального — помните, что в таком случае вам надо задать формат воспроизведения. Я покажу вам, как это делается в следующем разделе, «Установка формата воспроизведения».

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

А теперь пример установки приоритетного уровня кооперации с использованием ранее инициализированного объекта IDirectSound8:

//g_pDS = ранее инициализированный объект IDirectSound8

//hWnd = ранее инициализированный дескриптор родительского окна

if(FAILED(g_pDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY))) {

// Произошла ошибка

}

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

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

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

затем используете интерфейс для модификации формата.

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

Объект IDirectSoundBuffer представляет первичный звуковой буфер.

Здесь не требуется интерфейс восьмой версии, поскольку система микширования в разных версиях DX не менялась. Звуковой буфер (как

202

netlib.narod.ru

Джим Адамс

первичный, так и вторичный) создает функция

IDirectSound8::CreateSoundBuffer, которая выглядит так:

HRESULT IDirectSound8::CreateSoundBuffer(

LPCDSBUFFERDESC pcDSBufferDesc,

// Описание буфера

LPDIRECTSOUNDBUFFER *ppDSBuffer,

// Создаваемый объект буфера

LPUNKNOWN pUnkOuter);

// NULL - не используется

В параметре pcDSBufferDesc передается указатель на структуру DSBUFFERDESC, хранящую различную информацию о создаваемом буфере.

Для первичного буфера вы не будете использовать все возможности, предоставляемые объектом звукового буфера, но тем не менее, взглянем на всю структуру целиком:

typedef struct {

// Размер структуры

DWORD dwSize;

DWORD dwFlags;

// Флаги, описывающие возможности буфера

DWORD dwBufferBytes;

// Размер звукового буфера

DWORD dwReserved;

// Не используется, установите 0

LPWAVEFORMATEX lpwfxFormat;

// Формат воспроизвелдения

GUID guid3DAlgorithm;

// GUID_NULL

} DSBUFFERDESC, *LPDSBUFFERDESC;

// (Алгоритм 3D-воспроизведения)

 

Назначение полей ясно из их названий, за исключением lpwfxFormat. Это указатель на структуру, описывающую формат

воспроизведения создаваемого буфера. Поскольку пока мы не имеем дела с ней, оставим подробное описание на потом. Что касается dwBufferBytes,

первичный звуковой буфер уже существует, так что присвойте dwBufferBytes значение 0.

ПРИМЕЧАНИЕ DirectSound автоматически создает буфер данных,

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

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

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

Сейчас мы будем использовать только флаги

DSBCAPS_PRIMARYBUFFER и DSBCAPS_CTRLVOLUME. Эти флаги

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

ВНИМАНИЕ! Некоторые флаги, такие как флаг контроля частоты, нельзя использовать для первичного буфера. Указание таких флагов приведет к возникновению ошибки при создании первичного буфера.

netlib.narod.ru

203

Глава 4. Воспроизведение звуков и музыки с DirectX Audio и Direct Show

Таблица 4.3. Флаги для создания звукового буфера

Флаг

Описание

 

 

 

 

 

 

 

DSBCAPS_CTRL3D

У буфера есть трехмерные возможности.

 

DSBCAPS_CTRLFREQUENCY

Позволяет менять частоту в ходе

 

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

 

 

DSBCAPS_CTRLFX

Буфер позволяет обработку эффектов.

 

DSBCAPS_CTRLPAN

У буфера есть возможность пози-

 

ционирования.

 

 

 

DSBCAPS_CTRLPOSITIONNOTIFY

Буфер может использовать уведомления.

DSBCAPS_CTRLVOLUME

Позволяет

на

лету

регулировать

 

громкость для буфера.

 

 

DSBCAPS_GETCURRENTPOSITION2

Позволяет

запрашивать

буфер

о

 

местонахождении

позиции

воспроизве-

 

дения.

 

 

 

 

DSBCAPS_GLOBALFOCUS

DSBCAPS_LOCDEFER

DSBCAPS_LOCHARDWARE

DSBCAPS_LOCSOFTWARE

DSBCAPS_MUTE3DATMAXDISTANCE

DSBCAPS_PRIMARYBUFFER

DSBCAPS_STATIC

DSBCAPS_STICKYFOCUS

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

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

Заставляет использовать аппаратные ресурсы, такие как микшер и память звуковой карты.

Заставляет использовать программные ресурсы, такие как программное микширование и системная память.

Выключает трехмерный звук, если его источник находится слишком далеко от слушателя.

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

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

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

204

netlib.narod.ru

Джим Адамс

Давайте пойдем дальше и создадим интерфейс первичного звукового буфера:

IDirectSoundBuffer

g_pDSPrimary; // Глобальный доступ

DSBUFFERDESC

dsbd;

// Описание буфера

ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));

// Обнуляем структуру

dsbd.dwSize

=

sizeof(DSBUFFERDESC); // Устанавливаем размер

dsbd.dwFlags

=

 

 

// структуры

DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;

dsbd.dwBufferBytes =

0;

 

// Не задаем размер буфера

dsbd.lpwfxFormat

=

NULL;

 

// Не задаем формат

if(FAILED(g_pDS->CreateSoundBuffer(&dsbd,

 

&g_pDSPrimary, NULL))) {

// Произошла ошибка

}

Установка формата

Теперь, когда вы получили возможность управлять первичным звуковым буфером, пришло время установить формат воспроизведения. У вас есть несколько вариантов, но я рекомендую использовать осмысленные значения, такие как 11 025 Гц, 16-разрядная выборка, моно или 22 050 Гц, 16-разрядная выборка, моно.

Выбирая формат, постарайтесь не использовать стереофонию. Она создает ненужную нагрузку на процессор, поскольку настоящие стереофонические звуки достаточно сложно записать. Также старайтесь всегда использовать 16-разрядную выборку, поскольку ее качество значительно выше, чем у 8-разрядной. Никогда не соглашайтесь на меньшее! Что касается частоты, то чем она выше — тем лучше, но не стоит выбирать частоту выше 22 050 Гц. Даже звуки с CD-качеством прекрасно воспроизводятся на 22 050 Гц без заметных потерь.

Все сказано, пойдем дальше. Вы устанавливаете формат воспроизведения через вызов IDirectSoundBuffer::SetFormat:

HRESULT IDirectSoundBuffer::SetFormat(

LPCWAVEFORMATEX pcfxFormat);

ВНИМАНИЕ! Функция SetFormat должна вызываться только для объекта первичного звукового буфера.

Первый и единственный аргумент — это указатель на структуру WAVEFORMATEX, содержащую сведения о формате, который вы хотите

установить:

typedef struct {

// Укажите WAVE_FORMAT_PCM

 

WORD

wFormatTag;

 

WORD

nChannels;

// 1 для моно, 2 для стерео

 

DWORD

nSamplesPerSec;

// Частота дискретизации

 

DWORD

nAvgBytesPerSec;

// Количество байт в секунду для формата

 

WORD

nBlockAlign;

// Размер данных выборки

 

WORD

wBitsPerSample;

// 8 или 16

 

WORD

cbSize;

// Не используется

 

} WAVEFORMATEX;

 

 

 

 

 

 

netlib.narod.ru

205

Соседние файлы в папке GameProg