Получение уведомления о завершении воспроизведения звука в OpenAL
-
20-08-2019 - |
Вопрос
Я использую OpenAL на iPhone для одновременного воспроизведения нескольких звуковых сэмплов.
Могу ли я заставить OpenAL уведомлять меня, когда будет закончено воспроизведение одного сэмпла?
Я бы хотел избежать жесткого кодирования длины выборки и установки таймера.
Решение
Если у вас есть исходный код OpenAL, абстрагированный в класс, я думаю, вы можете просто вызвать performSelector:afterDelay:
когда вы запускаете звук:
- (void) play
{
[delegate performSelector:@selector(soundHasFinishedPlaying)
afterDelay:self.length];
…
}
(Если вы тем временем остановите звук вручную, обратный вызов может быть отменен, см. Ссылка на класс NSObject.) Или вы можете опросить AL_SOURCE_STATE
:
- (void) checkStatus
{
ALint state;
alGetSourcei(source, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING)
return;
[timer invalidate];
[delegate soundHasFinishedPlaying];
}
Я не знаю, как заставить OpenAL перезвонить тебе.Для чего именно вам нужен обратный вызов?Некоторые вещи можно решить лучше без обратного вызова.
Другие советы
Мне не очень повезло с обратными вызовами в OpenAL.В моих автоматах состояний я просто опрашиваю источник и откладываю переход до тех пор, пока это не будет сделано.
- (BOOL)playing {
ALint sourceState;
alGetSourcei(sourceID, AL_SOURCE_STATE, &sourceState);
return sourceState == AL_PLAYING;
}
// ... //
case QSTATE_DYING:
if (![audioSource playing])
[self transitionTo:QSTATE_DEAD];
Если это не то, что вам нужно, то, вероятно, вам лучше всего использовать таймер.Вам не нужно будет жестко кодировать какие-либо значения.Вы можете определить время воспроизведения при заполнении ваших буферов.
Небольшое понимание "почему" этого вопроса может предложить некоторые дополнительные варианты.
Это руководство OpenAL предлагает возможное решение:
Функция 'stream' также сообщает нам, закончено ли воспроизведение потока.
...и предоставляет пример исходного кода для иллюстрации использования.
Подожди, ты говоришь о том, что закончил один образец (например, 1/44100 секунды для звука с частотой 44,1 кГц)?Или вы говорите о знании того, что источник воспроизвел через свой буфер и у него больше нет звука для воспроизведения?
Что касается последнего, у меня были хорошие результаты опроса источника для свойства AL_BUFFERS_PROCESSED при потоковой передаче буферов в источник;для случая с одним буфером может сработать поиск ненулевого значения этого свойства.