Many users know that there is an issue with the current audio engine on Android. This writing focuses on the PlaySound() function that often causes frame stutters. I've found some sort of workarounds and I hope some of you find these useful.
Based on my tests the framerate stutter happens exactly when the PlaySound() is called. Once the function is active and just playing back a sound it doesn't cause framerate issues, but when it's called again it often causes a sudden glitch, frame drop. Here are three approaches to try.
1. Loop Silent
Loop a copy/another instance of your sound with 0 volume simultaneously with the "loud" version. The silent version should stay on looping as long as there is a possibility to use the sound. This will take away the severity of the stutter caused by calling the PlaySound() without it being active at all because no instance is playing. If you tapping/triggering rapidly the stutter will be visible but not as bad as without the silent looping. This approach won't remedy the framerate stutter a 100% but your sounds will play properly.
2. Loop Volume Change
If you have something like a rapid-fire plasma/laser/machine gun etc. sound, loop the sound with zero volume and control/fake the sound start and stop with a rapid volume increase and decrease. You have to experiment with this as it can work fairly well with certain kinds of sounds and not well with others. Here you might consider creating longer wave files with many loops in them instead looping a short sample.
This approach has zero negative effect on the frame rate.
3. Loop Pause&Play
This one is a bit finicky, but can work very well for certain sounds in certain situations. It's almost perfect for something like a dialog, or something you want to play only once or a few times. Probably won't work well for fast repeating sounds. For example let's say we have a five second sound we want to play at an important moment when the screen is busy and there are many sprites moving around and we don't want any stutter at the beginning of the sound playback.
Start looping your sound outside the main loop and pause it right away. Unfortunately we don't have certain transport functions for sound like Pause but we can pause with rate which is the playback speed rate/pitch. Playback rate 1 is normal 0 is 0 so the sound stops. After pausing the sound with SetSoundInstanceRate(Sound,0) we have our PlaySound() function called already that is looping but paused. When the sound playback is triggered, we switch rate to 1 - SetSoundInstanceRate(Sound,1) - start a timer and when five seconds past we switch back the playback rate to zero. Probably the best practice in this case is to trim the wav to 5 sec exactly and try to play that duration exactly, since we can't "rewind" to set a start position at zero and start a possible next playback automatically from the beginning.
The drawback of this approach is that the playback start point usually shifts and after many playbacks it might sound glitchy, but has zero negative effect on the frame rate.
Pseudocode for 3rd approach:
LoadSound(1,"MegaLaserFire.wav")
MegaLaserFire=PlaySound(1,100,1)
SetSoundInstanceRate(MegaLaserFire,0) // Pausing the sound
//---Main Loop
Repeat
If GetPointerPressed() // Trigger
timer1#
SetSoundInstanceRate(MegaLaserFire,1) // Playback starts
EndIf
timer2#
If timer2#-timer1# >= 5.0 : SetSoundInstanceRate(MegaLaserFire,0) : EndIf // Pause the sound after 5 sec
// Usually it needs some experimentation but for 5.0 sec something like 4.9 might work better.
Until WhatEver()