I have multiple questions regarding Audio output with Allegro 5.
Is there a way to determine if a stream has played through once? Imagine I have a level with music in the background. Somewhere in the level the user finds an item. I want to pause the currently playing background music, play a jingle and after that jingle resume the original level music.
Can you play a sample instance multiple times parallelly? I planned to use streams for music and sample instances for sound effects. Now imagine a platformer where you can collect coins and you touch multiple coins in a short time. The desired result would be getting the coin sound to play multiple times in succession, each sound overlapping the previous one and not stopping it.
After you exit your application, what do you have to do to properly free up all resources used by your audio system? Right now I'm using one voice and three mixers chained together. Is it enough to just destroy all four resources or do I have to detach everything first?
That's it for now.
A sample instance is a single instance of a sample. So no, you cannot play a sample instance multiple times in parallel. You create one sample and many instances. al_play_sample() does this for you automatically, and works fine for simple sound effects.
I'm not sure if there is a loop or finished event. Try listening to the stream's events to see. Otherwise, you could poll it to see if it is still playing, assuming you don't have it set to loop.
A sample instance is a single instance of a sample. So no, you cannot play a sample instance multiple times in parallel. You create one sample and many instances. al_play_sample() does this for you automatically, and works fine for simple sound effects.
But can I use al_play_sample() in combination with a mixer? I do need one for the sound effects. What about creating sample instances on the fly whenver I need them? Can I do that or is that impossible due to being too time consuming or whatever? Or wait... Can I just use al_set_default_mixer() in combination with my Sound Mixer? After all I don't think I'll be using any samples on my Music Mixer. Also what's a good number for al_reserve_samples()? Do I have to prevent using a too high number?
Otherwise, you could poll it to see if it is still playing, assuming you don't have it set to loop.
So does al_get_audio_stream_playing() return false if a stream has ended?
You need to reserve enough with al_reserve_samples() to cover the number of samples you will be playing simultaneously. There's little overhead involved, other than the tiny bit of memory used by an instance and the linear search that is done when using an ALLEGRO_SAMPLE_ID.
If you run out of reserved instances, then al_play_sample() will return false. So play around to figure out what you need in your application.
So does al_get_audio_stream_playing() return false if a stream has ended?
I don't know. Try it. If the stream's play mode is set to ONCE, then probably.
You need to reserve enough with al_reserve_samples() to cover the number of samples you will be playing simultaneously.
So I pretty much have to guess? For example: I have to assume that not more than X sound effects will ever be played at the same time? And is there some way to set sample priority like in Allegro 4 to prevent a sample from not getting played when all slots are used up?
There is no built-in concept of priority. Anything you play with al_play_sample_instance() will get played. So you can use that for top priority samples.
Or you can just reserve a sufficiently high number of samples. Are you really going to have (for example) 100 samples playing at the same time? Would it even sound good?
Probably not, but at least up to 10 sound effects at the same time doesn't seem that unlikely to me.
Well, I guess I'll just go with the sample instance method than and create them on the fly, storing each new instance in a vector or something. After they've played through I'll then just destroy them again. Seems to best solution for my needs.
I'd also go with the sample instance method. My method uses fixed ones though. E.g. if I say I want at most 8 bullet sounds at the same time and at most 4 explosion sounds at the same time, I create 8 bullet instances and 4 explosion instances.
Then when I play a bullet sound and there is an unused instance, I use that. Otherwise I stop the oldest of the 8 playing bullet sounds and replace it with the new one.
Releated to priority, A5 also makes it very easy to use different mixers. For example, use one mixer for sound effects, one mixer for user-interface sounds, one for voice overlays, one for ambient sounds, one for music. Then attach all of those mixers to the default mixer. That way you can control the volume of all your sound channels independently (e.g. to allow the user setting the volumes in the configuration). Or also do things like lower the effects volume while a user interface sound is playing.
True. I could just create additional mixers for all important samples like voices (if I had any). So that's one way to handle priority.
EDIT:
Alright. I just implemented the sample instance method and it's working fine. However, when I play a few sound effects in rapid succession/at the same time (maybe around 5 or 6) I get a buzzing sound and the more I play at the same time, the worse it gets. With around 10 simultanous sound effects (or probably even less) it's already at an unbearable level. Is there a way to avoid this? This here is my audio implementation:
And to play a sound I use:
Does ALLEGRO_AUDIO_DEPTH_FLOAT32 for the mixers help?
Does ALLEGRO_AUDIO_DEPTH_FLOAT32 for the mixers help?
It does indeed. The buzzing is completely gone now. Thank you! Now I only get stuttering when a lot of sound effects are playing, but that's OK and not too annoying actually.
Also this reminds me: When using al_load_sample() or al_load_stream() to load music files from my disk: Do I have to care about their format? Like, do they have to match the mixers' format in some kind or can they be in any format?
The stuttering can be overcome by increasing the number or size of buffers via the Allegro config options. (Each driver has its own settings, unfortunately...) It will increase the latency of course, but that's usually not very noticeable when simply playing sound effects.
You can load any format of audio file when it is attached to a mixer.
The stuttering can be overcome by increasing the number or size of buffers via the Allegro config options.
Well, as I said the stuttering (I think stuttering is not even the right word for this, but I can't think of a better one) isn't that bad plus I was testing under extreme conditions (probably around 30 sound effects at the same time). That number is way more than I'll ever need, so I'll just stay with the current settings. Even if I had that many sound effects it's barely noticable (and probably is only the overlapping of all sound effects, anyways).
And thanks for the help again!