Будучи уведомленным, когда звук сделан, играя в OpenAL

Если вы используете Modernizr , очень просто использовать Modernizr.touch, как упоминалось ранее.

Однако я предпочитаю использовать комбинацию Modernizr.touch и тестирование пользовательского агента, просто чтобы быть в безопасности.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

Если вы не используете Modernizr, вы можете просто заменить приведенную выше функцию Modernizr.touch на ('ontouchstart' in document.documentElement)

Также обратите внимание, что тестирование пользовательского агента iemobile даст вам более широкий диапазон обнаружил мобильные устройства Microsoft, чем Windows Phone.

Также см. Этот вопрос SO

6
задан Mel 25 June 2009 в 21:19
поделиться

4 ответа

Если у вас есть исходный код 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 перезвонит вам. Для чего именно вам нужен обратный звонок? Некоторые вещи можно решить лучше без обратного вызова.

3
ответ дан 10 December 2019 в 02:52
поделиться

Это руководство OpenAL предлагает возможные варианты решение:

Функция 'stream' также сообщает нам, закончилось ли воспроизведение потока.

... и предоставляет образец исходного кода для иллюстрации использования.

1
ответ дан 10 December 2019 в 02:52
поделиться

Подождите, вы говорите о завершении одного сэмпла (например, 1/44100 секунды для звука 44,1 кГц)? Или вы говорите о знании того, что источник проиграл свой буфер и у него больше нет звука для воспроизведения?

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

1
ответ дан 10 December 2019 в 02:52
поделиться

Мне не очень повезло с обратными вызовами в 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];

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

Небольшое понимание «почему» вопроса может предложить некоторые дополнительные варианты.

4
ответ дан 10 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: