Steps3D - Tutorials - Програмування 3D-звуку за допомогою OpenAL

Бібліотека OpenAL (Open Audio Library), розроблена та підтримувана компаніями Creative Labs та Loki Entertainment, є безкоштовною, кросплатформовою бібліотекою для роботи з 3D-звуком з відкритим кодом. Існують версії OpenAL для платформ Mac OS 8/9, Mac OS X, Linux, BSD, Solaris, IRIX та M$ Windows.

Ця бібліотека була використана в ряді ігор, таких як Unreal II, Unreal Tournament 2003/2004, Doom III версії для Linux.

Великими плюсами цієї бібліотеки (крім підтримки такої компанії як Creative Labs) є її простота, так і те, що за стилем вона дуже сильно нагадує бібліотеку OpenGL. Тому для програмістів, які вже знайомі з OpenGL, освоєння OpenAL стає дуже простим і швидким.

Для початку роботи з OpenAL завантажте OpenAL SDK для використовуваної Вами платформи. Усі приклади до цієї статті компілювалися як Windows, так Linux.

Основними поняттями OpenAL є аудіопристрій (audio device), аудіоконтекст (audio context), слухач (listener), джерела звуку (sources) та буфера (buffers).

Поняття контексту в OpenAL дуже близьке до свого аналога OpenGL. Усі зміни параметрів відбуваються в межах певного контексту, пов'язаного з аудіопристроєм. Можливе наявність кількох аудіоконтекстів для одного аудіопристрою, між якими можна перемикатися.

Для найпростіших прикладів всю роботу з аудіо пристроями та контекстами можна перекласти на бібліотеку alut, що входить до складу OpenAL SDK.

Бібліотека OpenAL дозволяє задавати в тривимірному просторі різні джерела звуку та слухача. І для кожного джерела звуку та для слухача можна задати рядпараметрів (таких як, положення, швидкість тощо), що впливають на звук, що виходить в результаті.

Бібліотека OpenAL на основі цієї інформації здійснює обробку звуку (враховуючи при цьому як взаємне розташування слухача та джерел звуку, так і їх швидкість). Після обробки відбувається змішання звуку від різних джерел отримання вихідного сигналу для кожного з вихідних каналів.

Крім інтуїтивно зрозумілих понять слухача та джерел, у OpenAL важливу роль відіграє поняття буфера. Саме за допомогою буферів здійснюється завдання безпосередніх звукових даних (Raw PCM), які повинні виводитись для кожного з джерел.

Можна для джерела задати відразу кілька буферів, організувавши в чергу. Тоді після того, як усі дані з одного буфера будуть виведені, відбувається автоматичне перемикання на наступний буфер.

Розглянемо спочатку кілька простих прикладів роботи з OpenAL, заснованих на використанні бібліотеки alut, наприкінці статті буде наведено кілька класів на С++, які помітно полегшують використання OpenAL.

Найпростіший випадок - одне нерухоме джерело звуку

У цьому й ряді таких прикладів ми активно використовуватимемо бібліотеку alut для спрощення роботи з OpenAL.

Першим кроком при роботі з OpenAL є ініціалізація – отримання пристрою та створення контексту. При використанні alut для цього можна використовувати лише одну функцію -alutInit.

Вхідними параметрами цієї функції є покажчик на аргументargcі аргументargvфункціїmain(повністю аналогічно функціїglutInit).

Ця функція здійснює створення пристрою (під M$ Windows зазвичай використовується DirectSound3D) та контексту для нього.

Для перевірки успішностівикликуalutInit(як і практично будь-якої функції OpenAL) служить функціяalGetError. За відсутності помилок вона повертає значення AL_NO_ERROR.

Для завершення роботи з OpenAL можна використовувати функціюalutExit:

Після ініціалізації OpenAL необхідно створити джерело звуку та буфер для нього, а також задати їх властивості.

Кожне джерело звуку (і буфер) задається цілим числом беззнаковим (типу ALuint). Для створення джерел та буферів служать такі функції.

Кожна з цих функцій приймає два параметри - скільки відповідних об'єктів (джерел або буферів) треба створити (n) і покажчик на масив, в який треба помістити ідентифікатори створених об'єктів (sourcesабоbuffers).

Як і раніше, для перевірки успішності створення об'єктів слід використовувати функціюalGetError.

Наступні функції служать знищення створених джерел і буферів.

Сама бібліотека OpenAL не містить функцій для роботи зі звуковими файлами різних форматів (таких якwav,mp3,oggі т.п.). Завданням користувача є декодування таких файлів (на щастя для цього вистачає бібліотек) і передачі декодованих PCM-даних в OpenAL.

Однак для зручності бібліотеку alut входять функції, що дозволяють завантажувати звукові дані з популярного формату wav.

Вхідний параметрfileNameвизначає ім'я файлу, з якого слід завантажити звукові дані. Параметрformatє вказівником на змінну, в яку буде записано формат звукових даних (див. далі опис функціїalBufferData). Параметрsizeє вказівником на змінну, в яку буде записано обсяг декодованих даних у байтах.

Параметрbitsєвказівником на змінну, в яку буде записано кількість біт, що служить для представлення одиниці даних (sample) - 8 або 16 біт. Параметрfreqвизначає частоту відтворення даних. Останній параметрloopвизначає чи треба зациклити цей звук (тобто постійно повторювати).

ФункціяalutUnloadWAVFileслужить для звільнення пам'яті, виділеної при декодуванніwav-файлу.

Використовуючи ці функції, легко здійснювати завантаження звукових даних у буфер. Для цього OpenAL служить функціяalBufferData.

Параметрbufferє ідентифікатором буфера, дані для якого задаються цією командою. Параметрformatвизначає формат звукових даних і може приймати одне з наступних значень - AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8 та AL_FORMAT_STEREO16.

Параметрdataє вказівником на буфер зі звуковими даними. Зверніть увагу, що ця команда копіює дані, тому після цієї команди пам'ять, на яку вказує цей параметр, можна змінювати або звільнити.

Інші параметри мають той самий сенс, що й у командіalutLoadWAVFile.

Нижче наводиться фрагмент коду, що здійснює завантаженняwav-файлу у створений буфер.

Після створення буфера та заповнення його звуковими даними слід задати параметри джерела звуку. І тому служать такі функції.

Параметрsourceзадає для якого саме джерела звуку задається значення.

Параметрpnameзадає ім'я властивостей, що змінюються. У наведеній нижче таблиці наводяться допустимі значення для даного параметра.