Archive for the ‘Программизмы’ Category

Программирование под OpenAL

28 August 2007

Я решил немного пособирать часто задаваемые вопросы и некоторые неочевидные факты про OpenAL. Как говорится: “мыши плакали кололись, но продолжали есть кактус” - это всё про OpenAL :)
Прежде всего, что вы получаете используя OpenAL в сравнению с другими библиотеками ?

  1. Простота и минималистичность API
  2. Кроссплатформенность.
  3. Бесплатность и открытость кода.

Минусы будут перечислены в этом faq :)

Как определить количество источников доступных для OpenAL?
К сожалению, в документации этот вопрос не освящён вообще. Многие люди используют alut для инициализации OpenAL, хотя на самом деле инициализация “руками” занимает совсем немного места и позволяет контролировать разные аспекты типа перечисления устройств. Не используйте alut для этого :)

  1. Выбираете устройство (как показано в следующем пункте, либо NULL для устройства по умолчанию, вызываете alcOpenDevice(name)
  2. Необязательный шаг : создание массива атрибутов типа :
    ALCint attrs[] = {
    ALC_STEREO_SOURCES, stereo_sources,
    ALC_MONO_SOURCES, mono_sources,
    ALC_INVALID, ALC_INVALID,
    }; // stereo_sources и mono_sources - хинты OpenAL. Минимально
    “работающее везде” решение - 16 источников суммарно. Учтите что один
    стерео источник тратит 2 реальных. Итого, по умолчанию стоит ставить
    хинты так чтобы stereo_sources * 2 + mono_sources == 16. Вы можете
    предложить пользователю попробовать увеличить это значение, или
    попробовать угадать в процессе исполнения.
  3. создаёте контекст alcCreateContext(alc_device, attrs);
  4. Теперь надо получить обратно атрибуты :)
    ALCInt attr_size;
    alcGetIntegerv(alc_device, ALC_ATTRIBUTES_SIZE, sizeof(attr_size), &attr_size);
    const ALCInt * attributes = (ALCint *)malloc(attr_size * sizeof(ALCint));
    alcGetIntegerv(alc_device, ALC_ALL_ATTRIBUTES, attr_size, attributes);
    по указателю attributes теперь лежат атрибуты в том же формате в котором они передаются в OpenAL в п.2. Теперь циклом до ALC_INVALID бежим по attributes и ищем ALC_MONO/STEREO_SOURCES. Если вам повезёт и у вас не linux - вуаля! OpenAL вернул реальные числа для устройства.

Как выбрать устройство используемое OpenAL ?

alcGetString(NULL, ALC_DEVICE_SPECIFIER) возвращает не только устройство по умолчанию. Оно возвращает указатель на массив всех устройств следующим образом:
“Generic Hardware”, 0, “Generic Software”, 0, 0
Для чистоты эксперимента можно проверить наличие ALC_ENUMERATION_EXT, но если мне не изменяет память, спецификация OpenAL 1.1 сделала его обязательным. (поправьте?)

Я хочу заниматься микшированием в своём треде. Я не хочу чтобы OpenAL создавал тред!

Проще простого: поставьте контексту атрибут ALC_SYNC, AL_TRUE, и периодически вызывайте alcProcessContext(context);

У меня возникают случайные очень странные ошибки, которые никак не относятся к делу.

Решений могу предложить несколько, применять их следует в этой же последовательности:

  1. После каждого вызова OpenAL вызывать alGetError(), например используя макросы для экономии места.
  2. Выделять источники один раз, при инициализации звука. Не динамически. Учтите это при проектировании приложения.
  3. у вас 64 битный linux ? попробуйте мою сборку openAL и не забудьте написать в bugtracker openal, дистрибутива, чего угодно чтобы выключили MMX в openal на x86_64 :)

16 источников это очень мало - у меня “сто звучащих” обьектов на уровне.

Больше вам вряд ли надо :) OpenAL не содержит менеджера источников, поэтому вам эту сущность придётся написать самим или взять из какого-нибудь проекта. Чем эта сущность должна заниматься ?

  1. Инициализацией OpenAL и созданием источников.
  2. Отслеживать расстояние до обьектов и реально играть только самыми близкими обьектами.
  3. Перезапускать приблизившиеся обьекты с зациклеными звуками (например вертолёт)

Как сделать источник звучащий слушателю “в голову” ?

Ключевые моменты инициализации:
alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE);
alSourcef (source, AL_ROLLOFF_FACTOR, 0.0);
По умолчанию эти значения выставлены в AL_FALSE и 1.0 соответственно.

©2007 Меньшаков Владимир, Netive Media Group.

Comments: 7509 Comments