2009-06-25 11 views
6

Estoy usando OpenAL en iPhone para reproducir varias muestras de audio simultáneamente.Recibir notificaciones cuando se reproduce un sonido en OpenAL

¿Puedo obtener OpenAL para notificarme cuando se reproduce una sola muestra?

Me gustaría evitar la codificación de la duración de la muestra y la configuración de un temporizador.

+0

Esta pregunta tiene 5 años en este punto, pero para los principiantes de OpenAL como yo, ahora hay un AP de Objective-C para OpenAL, y una clase en el proyecto de demostración ('SourceNotificationsDemo') que demuestra esta funcionalidad. – livingtech

+0

@livingtech ¿podría proporcionar un enlace? – Zorayr

+0

Proyecto aquí: https://github.com/kstenerud/ObjectAL-for-iPhone – livingtech

Respuesta

3

Si ha la fuente OpenAL abstraído en una clase, supongo que se puede llamar simplemente performSelector:afterDelay: cuando se inicia el sonido:

- (void) play 
{ 
    [delegate performSelector:@selector(soundHasFinishedPlaying) 
     afterDelay:self.length]; 
    … 
} 

(Si se detiene el sonido manualmente, mientras tanto, la devolución de llamada puede ser cancelado, ver el NSObject Class Reference) o puede consultar la AL_SOURCE_STATE:.

- (void) checkStatus 
{ 
    ALint state; 
    alGetSourcei(source, AL_SOURCE_STATE, &state); 
    if (state == AL_PLAYING) 
     return; 
    [timer invalidate]; 
    [delegate soundHasFinishedPlaying]; 
} 

no saben cómo pasar OpenAL le devuelva la llamada. ¿Para qué quieres exactamente la devolución de llamada? Algunas cosas se pueden resolver mejor sin una devolución de llamada.

1

This OpenAL guide sugiere una posible solución:

La función 'arroyo' también nos dice si la corriente está terminado de jugar.

... y proporciona un código fuente de muestra para ilustrar el uso.

+0

(La solución vinculada está sondeando con alGetSourcei (fuente, AL_SOURCE_STATE, y resultado) que es lo que también recomendaría. +1 – RJFalconer

1

Espera, ¿estás hablando de haber terminado una muestra (por ejemplo, 1/44100 segundos para audio a 44.1 KHz)? ¿O estás hablando de saber que una fuente ha jugado a través de su buffer y no tiene más audio para jugar?

Para este último, he tenido buenos resultados al buscar una fuente para la propiedad AL_BUFFERS_PROCESSED cuando envío buffers a una fuente; podría funcionar para que el caso de un solo búfer busque un valor distinto de cero de esta propiedad.

+1

Una vez que tenga búferes en cola a una fuente, AL_BUFFERS_RPOCESSED nunca devolverá 0. Incluso si detiene o detiene la fuente, o completa su búfer. El valor solo disminuye si rebobina los búferes de origen o de eliminación de la secuencia. Un valor distinto de cero solo muestra que al menos un buffer ha terminado de jugar en algún punto. – RJFalconer

4

No tuve mucha suerte con las devoluciones de llamada en OpenAL. En mis máquinas de estado, simplemente sondeo la fuente y atrasar la transición hasta que esté hecho.


    - (BOOL)playing { 
     ALint sourceState; 
     alGetSourcei(sourceID, AL_SOURCE_STATE, &sourceState); 
     return sourceState == AL_PLAYING; 
    } 

// ... // 

    case QSTATE_DYING: 
     if (![audioSource playing]) 
      [self transitionTo:QSTATE_DEAD]; 

Si esto no es lo que necesita, entonces la mejor opción es probablemente un temporizador. No debería necesitar codificar ningún valor. Puedes determinar el tiempo de reproducción cuando estés poblando tus buffers.

Un poco de comprensión del "por qué" de la pregunta podría ofrecer algunas opciones adicionales.

Cuestiones relacionadas