2009-06-25 9 views
6

Ich verwende OpenAL auf dem iPhone, um mehrere Audio-Samples gleichzeitig abzuspielen.Benachrichtigung erhalten, wenn ein Sound in OpenAL wiedergegeben wird

Kann ich OpenAL bekommen, um mich zu benachrichtigen, wenn ein einzelnes Sample abgespielt wurde?

Ich möchte vermeiden, die Sample-Länge hart zu codieren und einen Timer zu setzen.

+0

Diese Frage ist zu diesem Zeitpunkt 5 Jahre alt, aber für newbs zu OpenAL wie mir gibt es nun ein Objective-C APi für OpenAL und eine Klasse im Demoprojekt ('SourceNotificationsDemo'), die diese Funktionalität demonstriert. – livingtech

+0

@livingtech könnten Sie einen Link zur Verfügung stellen? – Zorayr

+0

Projekt hier: https://github.com/kenenerud/ObjectAL-for-iPhone – livingtech

Antwort

3

Wenn Sie die OpenAL Quelle in eine Klasse abstrahiert haben, ich denke, man einfach performSelector:afterDelay: anrufen können, wenn Sie den Sound starten:

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

(Wenn Sie den Ton manuell in der Zwischenzeit stoppen, kann der Rückruf sein siehe abgebrochen, die NSObject Class Reference) Oder Sie können abfragen, die AL_SOURCE_STATE.

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

ich weiß nicht, wie Sie OpenAL zurückrufen haben. Für was genau möchtest du den Rückruf? Manche Dinge lassen sich besser ohne Rückruf lösen.

1

This OpenAL guide deutet auf eine mögliche Lösung:

Die 'Stream' Funktion sagt uns auch, wenn der Strom zu spielen ist beendet.

... und Beispiel-Quellcode zur Veranschaulichung der Verwendung.

+0

(Die verknüpfte Lösung ist Abfrage mit AlGetSourcei (Quelle, AL_SOURCE_STATE, & Ergebnis), was ich auch empfehlen würde. +1 – RJFalconer

1

Warte, sprichst du über eine Probe fertig (z. B. 1/44100 Sekunde für 44,1 kHz Audio)? Oder sprichst du davon, dass eine Quelle ihren Puffer durchgespielt hat und keinen Ton mehr zu spielen hat?

Für letztere, hatte ich gute Ergebnisse polling eine Quelle für die AL_BUFFERS_PROCESSED Eigenschaft, wenn ich Puffer zu einer Quelle streamen; Es könnte für den Fall mit einem einzelnen Puffer funktionieren, nach einem von Null verschiedenen Wert dieser Eigenschaft zu suchen.

+1

Sobald Sie haben In der Warteschlange eingereihte Puffer zu einer Quelle, AL_BUFFERS_RPOCESSED wird niemals 0 zurückgeben, auch wenn Sie die Quelle stoppen oder pausieren oder den Puffer vervollständigen.Der Wert verringert sich nur, wenn Sie die Quell- oder Pufferlöschung zurückspulen.Ein Wert ungleich Null zeigt nur diesen Wert an Ein Puffer ist irgendwann zu Ende gespielt. – RJFalconer

4

Ich hatte nicht viel Glück mit Rückrufen in OpenAL. In meinen Zustandsautomaten stimme ich einfach die Quelle ab und verzögere den Übergang, bis es fertig ist.


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

// ... // 

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

Wenn dies nicht das ist, was Sie brauchen, dann ist die beste Wette wahrscheinlich ein Timer. Sie sollten keine Werte fest codieren müssen. Sie können die Wiedergabezeit bestimmen, wenn Sie Ihre Puffer auffüllen.

Ein bisschen Einblick in das "Warum" der Frage könnte einige zusätzliche Möglichkeiten bieten.

Verwandte Themen