Войти
ПрограммированиеФорумЗвук

openAL потоковое воспроизведение ogg (вопрос)

#0
1:52, 21 мар. 2013

Здравствуйте, решил написать простенький движок игры. Начал работать со звуком. Руководствуюсь статьёй
http://www.gamedev.ru/code/articles/OpenAL?page=2#chast__2__forma… _vorbis__i_pr
Всё работает отлично, вот только не могу разобраться, при потоковом воспроизведении когда нужно обновлять буфер с данными. Там реализована функция Update(). Куда её вставлять, где реализовать цикл, и как точно (правильно) разбить файл? Наверное глупый вопрос ;) Но я новичок в этом деле. Помогите пожалуйста, а то при загрузке 3 мин мелодии происходит задержка около 0,5 сек ;)


#1
2:11, 21 мар. 2013

GolemRus
> при загрузке 3 мин мелодии происходит задержка около 0,5 сек
В статье написано о конвейере буферов. Вероятно, что вначале программа загружает конвейер полностью, и это дает задержку. Если уменьшить количество буферов, то задержка должна стать меньше.
(можно попытаться постепенно увеличить их число уже во время воспроизведения)

Я думаю, что Update там просто в цикле. Эта функция все время догружает конвейер, если надо.

#2
7:31, 21 мар. 2013

Я пытался добавить Update() в функцию Play(). Но в результате получал полное зависание. Отсюда и вопрос: где цикл организовать и с чем связать его?

#3
8:30, 21 мар. 2013

Апдейт, если я правильно понял, надо вызывать периодически при приближении воспроизведения к окончанию фрагмента. Или так:

Воспроизводим А, в очередь (alSourceQueueBuffers) сразу ставим Б.
Если воспроизведение дошло до Б - выкидываем А, загружаем В и ставим в очередь.
Если воспроизведение дошло до В - выкидываем Б, загружаем Г и ставим в очередь.
И так далее.

То есть где-то в цикле, или по таймеру, или по callback-функциям обратной связи (не знаю, есть ли такие в OpenAL) проверять, до какого кусочка дошло вопроизведение.

#4
19:11, 21 мар. 2013

ALPINE
> То есть где-то в цикле, или по таймеру, или по callback-функциям обратной связи
там нужно проверять состояние буферов, у нас это было частью update игры.
но думаю можно в отдельном потоке организовать эту проверку

#5
22:56, 21 мар. 2013

Всем спасибо, я разобрался. Вопрос действительно оказался глупым. Занова прочитав статью, и изучив код, я понял свои ошибки. Задержка происходила из-за полного загружения в ОП, т. к. я проинициализировал параметры  (размер буффера) BlockSize  = ov_pcm_total(mVF, -1),  и кол-во буферов  DynBuffs  = 4. Что соответствует в сумме размеру всего файла. И заведомо неправильный мой настрой попытаться засунуть вызов функции Update() в функцию Play() приводил к полному зависанию, т.к. Play(), а точнее alSourcePlay(mSourceID) нужно вызывать только один раз.
Я поставил BlockSize  = ov_pcm_total(mVF, -1)/32;  DynBuffs  = 4.  Лаги исчезли!
А поповоду цикла я даже не стал заморачиваться. В главный цикл, где происходит отрисовка сцен, я просто добавил вызов Update(). Всё отлично, осталось настроить корректный вызов Update(), а то после проигрывания мелодии, происходит неконтролируемое заполнение буферов данными, в результате чего начинаются дикие лаги и ОП перегружается ;)
Вообщем считаю вопрос закрытым, автору статьи огромное спасибо за работающий код.
   

#6
23:48, 21 мар. 2013

GolemRus
Вообще говоря трудно оправдать целесообразность создания более чем 2 буферов объемом более чем 64Кб каждый (хотя - последнее зависит от bitrate).
Я играл с размером 16 Кб, тогда даже 50-60 звуков на сцене отъедают не более 16*2*60 < 2 Мб. SFX/music были 192Килобит/с (или 24Кб/с), и с апдейтом в почти секунду музыка шла без тормозов.

ПрограммированиеФорумЗвук

Тема в архиве.