Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Delay when playing a sound effect using "al_play_sample"

Credits go to Elias and SiegeLord for helping out!
This thread is locked; no one can reply to it. rss feed Print
Delay when playing a sound effect using "al_play_sample"
David Couzelis
Member #10,079
August 2008
avatar

There is a delay / latency when I use "al_play_sample" to play a WAV file. It's just a split second, but the fact that the sound doesn't match up with what is occurring on screen is VERY noticeable. :(

Should I expect latency when using "al_play_sample"? Is there a better or faster way to play sound effects?

There was a similar thread a couple years ago here: https://www.allegro.cc/forums/thread/614392 but I'm afraid I don't understand what the resolution was, if any.

About my setup:
Arch Linux with allegro 5.0.11
WAV (PCM) file, constant bit rate of 705 Kbps, 44.1 KHz, 16 bits, NO silent "gap" at the beginning of the file.
Preloading the sound effect early in an ALLEGRO_SAMPLE doesn't make a difference.

Thank you for any help! :)

SiegeLord
Member #7,827
October 2006
avatar

ALLEGRO_VOICE has an internal buffer for some audio backends that can cause some audio delay. In many cases it's hard coded, but in a few cases you can modify it using the system configuration. You're probably using PulseAudio as your backend (it typically has lagging issues), but perhaps not.

Try one of these before you initialize your audio and see if it makes a difference:

al_set_config_value(al_get_system_config(), "audio", "driver", "oss")
al_set_config_value(al_get_system_config(), "audio", "driver", "alsa")
al_set_config_value(al_get_system_config(), "audio", "driver", "pulseaudio")

For pulseaudio also try this (change the 512 to lower if you want, default is 1024):

al_set_config_value(al_get_system_config(), "pulseaudio", "buffer_size", "512")

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

David Couzelis
Member #10,079
August 2008
avatar

Thank you for the suggestion. I added this code shortly after calling "al_install_audio" (since I am using ALSA):

#SelectExpand
1al_set_config_value(al_get_system_config(), "audio", "driver", "alsa"); 2al_set_config_value(al_get_system_config(), "alsa", "buffer_size", "512");

It had no discernible effect. I also tried "oss", "pulseaudio", and many many variations of buffer sizes (down to 32, up to 2048...) with no discernible effect as well. :(

...I've been studying the Allegro examples, namely "ex_acodec.c" (which can be seen by selecting it here), and had good results. By creating an ALLEGRO_VOICE, ALLEGRO_MIXER, and ALLEGRO_SAMPLE_INSTANCE I'm able to play my pre-loaded ALLEGRO_SAMPLE instantly.

Unfortunately, I haven't quite got the hang of all those parts yet. :-/ Does every instance of a sound effect need its own instance of an ALLEGRO_SAMPLE_INSTANCE? But can they all share the same ALLEGRO_VOICE and ALLEGRO_MIXER?

And why is this different from just using the default mixer and the default voice (with "al_play_sample")?

EDIT: If I create a mixer and set it as the default:

#SelectExpand
1voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); 2mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); 3al_attach_mixer_to_voice(mixer, voice); 4al_set_default_mixer(mixer);

And THEN call "al_play_sample" the sound effect plays INSTANTLY! ...but only ONCE...? Any time I play a sound effect after that it's laggy again. ???

SiegeLord
Member #7,827
October 2006
avatar

Thank you for the suggestion. I added this code shortly after calling "al_install_audio" (since I am using ALSA):

It needs to come before al_install_audio. For ALSA, there is no configurable buffer size, so that setting won't really help.

Quote:

Does every instance of a sound effect need its own instance of an ALLEGRO_SAMPLE_INSTANCE? But can they all share the same ALLEGRO_VOICE and ALLEGRO_MIXER?

Yes. There's a bit of a writeup here which explains the relationship between these concepts: http://liballeg.org/a5docs/trunk/audio.html

Still thinking about why you'd get lag-free playback only once and why creating a new voice helps...

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

David Couzelis
Member #10,079
August 2008
avatar

SiegeLord said:

There's a bit of a writeup here which explains the relationship between these concepts: http://liballeg.org/a5docs/trunk/audio.html

Oh, excellent! That documentation seems to have more information than the docs at allegro.cc. I'll study it it detail.

SiegeLord said:

Still thinking about why you'd get lag-free playback only once and why creating a new voice helps...

I did another test:

#SelectExpand
1ALLEGRO_VOICE *voice; 2ALLEGRO_MIXER *mixer; 3 4if (voice != NULL && mixer != NULL) { 5 al_detach_voice(voice); 6 al_destroy_voice(voice); 7 al_destroy_mixer(mixer); 8} 9 10voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); 11mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); 12al_attach_mixer_to_voice(mixer, voice); 13al_set_default_mixer(mixer); 14al_reserve_samples(1);

If I run this code before EVERY TIME I play a sound effect using "al_play_sample" it plays absolutely perfectly. :) But, of course, needing to do all this before I play any sound effect seems pretty overkill...

Is there anything else I can do get to the bottom of this? Post more code? Do another test? Collect any logs? Wait patiently? ;)

Elias
Member #358
May 2000

Are you sure you are using the Alsa and not the PulseAudio driver? The Alsa driver is very old and a bit untested at this point.

There's for example this comment [1]:

   // TODO: Setting this to 256 causes (extreme, about than 10 seconds)
   // lag if the alsa device is really pulseaudio.
   //
   // pw: But there are calls later which expect this variable to be set an on
   // my machine (without PulseAudio) the driver doesn't work properly with
   // anything lower than 32.
   ex_data->frag_len = 32;

So someone just randomly set some setting called "frag_len" to 32. I couldn't figure out what buffer size we instruct ALSA to use on a quick glance - but chances are it is too large. And maybe, just as a blind guess, by creating a new voice you somehow force the buffer to be flushed and so the sound plays immediately?

--
"Either help out or stop whining" - Evert

David Couzelis
Member #10,079
August 2008
avatar

The issue has been resolved (to my satisfaction, at least). Thank you both! ;D

I spent the last 15 minutes switching my Arch Linux setup from ALSA to PulseAudio and SURPRISE! the most simple Allegro setup and call to "al_play_sample" now works flawlessly.

...Now, for my next step, is to decide if I want to keep PulseAudio (there's still some stuff I'd need to configure if I wanted to stick with it), try OSS, or simply leave ALSA the way it is and ignore the Allegro output issue. But, that's for me to worry about.

Thank you again! :)

Kris Asick
Member #1,424
July 2001

I actually wrote an entire sound handler using Allegro for my current project as the A5 approach to sound is... infuriatingly complicated. :P

I have experienced no delays, but then, my code uses al_play_sample_instance() to do its thing. *shrugs*

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Go to: