I have an Android game in which I need to play short sounds. SoundPool crashes on dual-core phones , Mediaplayer has up to 200 ms + delay, OpenSL requires SDK 9+ (I support 1.5). So AudioTrack
This is what I tried. I create such AudioTrack objects.
protected AudioTrack createAudioTrack() {
final int trackSize = 17408;
return new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT, trackSize, AudioTrack.MODE_STATIC);
}
Then I create a runnable for everyone in the game sound (about 8).
private static class SoundRunnable implements Runnable {
private final AudioTrack sound;
private final byte[] rawAudio;
public SoundRunnable(final AudioTrack sound, final byte[] rawAudio){
this.sound = sound;
this.rawAudio = rawAudio;
sound.write(rawAudio, 0, rawAudio.length);
}
@Override
public void run() {
playSound();
}
private synchronized void playSound() {
switch (sound.getPlayState()) {
case AudioTrack.PLAYSTATE_PAUSED:
sound.stop();
sound.reloadStaticData();
sound.play();
break;
case AudioTrack.PLAYSTATE_PLAYING:
sound.stop();
sound.reloadStaticData();
sound.play();
break;
case AudioTrack.PLAYSTATE_STOPPED:
sound.reloadStaticData();
sound.play();
break;
default:
break;
}
}
public synchronized void release() {
sound.release();
}
}
Then, when I need to play the sound, I send it to ThreadPool.
private void playSound(final int soundToPlay) {
final SoundRunnable soundRunnable = mediaPlayers.get(soundToPlay);
if(soundRunnable != null){
threadPool.execute(soundRunnable);
}
}
The main problem I am facing is that the sounds are played twice the first time runnable is run. After that, every once in a while I can still get a double sound, but it works very well.
AudioTrack runnables. , , . , , , getBuffer, . (, AudioTracks).
AudioTrack, .