I'm using OpenAL on iPhone to play multiple audio samples simultaneously.
Can I get OpenAL to notify me when a single sample is done playing?
I'd like to avoid hardcoding the sample length and setting a timer.
I'm using OpenAL on iPhone to play multiple audio samples simultaneously.
Can I get OpenAL to notify me when a single sample is done playing?
I'd like to avoid hardcoding the sample length and setting a timer.
If you have the OpenAL source abstracted into a class, I guess you can simply call performSelector:afterDelay:
when you start the sound:
- (void) play
{
[delegate performSelector:@selector(soundHasFinishedPlaying)
afterDelay:self.length];
…
}
(If you stop the sound manually in the meantime, the callback can be cancelled, see the NSObject Class Reference.) Or you can poll the AL_SOURCE_STATE
:
- (void) checkStatus
{
ALint state;
alGetSourcei(source, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING)
return;
[timer invalidate];
[delegate soundHasFinishedPlaying];
}
I don’t know how to have OpenAL call you back. What exactly do you want the callback for? Some things can be solved better without a callback.
I didn't have much luck with callbacks in OpenAL. In my state machines, I simply poll the source and delay the transition until it's done.
- (BOOL)playing {
ALint sourceState;
alGetSourcei(sourceID, AL_SOURCE_STATE, &sourceState);
return sourceState == AL_PLAYING;
}
// ... //
case QSTATE_DYING:
if (![audioSource playing])
[self transitionTo:QSTATE_DEAD];
If this isn't what you need, then you're best bet is probably a timer. You shouldn't need to hardcode any values. You can determine the playback time when you're populating your buffers.
A bit of insight into the "why" of the question might offer some additional choices.
If you have the OpenAL source abstracted into a class, I guess you can simply call performSelector:afterDelay:
when you start the sound:
- (void) play
{
[delegate performSelector:@selector(soundHasFinishedPlaying)
afterDelay:self.length];
…
}
(If you stop the sound manually in the meantime, the callback can be cancelled, see the NSObject Class Reference.) Or you can poll the AL_SOURCE_STATE
:
- (void) checkStatus
{
ALint state;
alGetSourcei(source, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING)
return;
[timer invalidate];
[delegate soundHasFinishedPlaying];
}
I don’t know how to have OpenAL call you back. What exactly do you want the callback for? Some things can be solved better without a callback.
This OpenAL guide suggests a possible solution:
The 'stream' function also tells us if the stream is finished playing.
...and provides sample source code to illustrate the usage.
Wait, are you talking about having finished one sample (e.g., 1/44100 second for 44.1 KHz audio)? Or are you talking about knowing that a source has played through its buffer and has no more audio to play?
For the latter, I've had good results polling a source for the AL_BUFFERS_PROCESSED property when I stream buffers to a source; it might work for the single-buffer case to look for a non-zero value of this property.
© 2022 - 2024 — McMap. All rights reserved.
SourceNotificationsDemo
) that demonstrates this functionality. – Leucoma