title: What is the proper way to use AudioTrack in static mode?
body: <p>I have an Android game that I need to play short sounds. <a href="http://developer.android.com/reference/android/media/SoundPool.html" rel="noreferrer">SoundPool</a> crashes on <a href="http://code.google.com/p/android/issues/detail?id=17623" rel="noreferrer">dual core phones</a>, <a href="http://developer.android.com/reference/android/media/MediaPlayer.html" rel="noreferrer">Mediaplayer</a> has up to 200ms+ delays, OpenSL requires SDK 9+ (I support 1.5). So that leaves <a href="http://developer.android.com/reference/android/media/AudioTrack.html" rel="noreferrer">AudioTrack</a>.</p>
  
  <p>This is what I have tried. I create the AudioTrack objects like this. </p>
  
  <pre><code>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);
  }
  </code></pre>
  
  <p>I then create a runnable for each in game sound (about 8).</p>
  
  <pre><code>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();
      }
  
  }
  </code></pre>
  
  <p>Then when I need to play the sound I send it to a ThreadPool.</p>
  
  <pre><code>private void playSound(final int soundToPlay) {
      final SoundRunnable soundRunnable = mediaPlayers.get(soundToPlay);
      if(soundRunnable != null){
          threadPool.execute(soundRunnable);
      }
  }
  </code></pre>
  
  <p>The main issue I have is that sounds play twice the first time I execute the runnable. After that every once in a while I still might get a double sound but it works pretty well.</p>
  
  <p>I have also experimented with creating a single AudioTrack in streaming mode and writing raw audio from the runnables. This was somewhat successfull but was difficult to know when to stop the play back. I you stop to early the sound is cut short, too late and you get an obtainBuffer error and the app locks up. Also playing two sounds at the same time is difficult (could possiblly use a pool of AudioTracks).</p>
  
  <p>I would love to see sample code for AudioTrack that doesn't involve streaming audio.</p>