¿Cuál es la forma correcta de utilizar AudioTrack en modo estático?

Tengo un juego para Android que necesito para reproducir sonidos cortos. SoundPool se bloquea en los teléfonos de doble núcleo , Mediaplayer tiene hasta 200ms + retrasos, OpenSL requiere SDK 9 + (apoyo 1.5). Así que deja AudioTrack .

Esto es lo que he intentado. Creo los objetos AudioTrack como este.

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); } 

A continuación, crear un runnable para cada uno en el sonido del juego (alrededor de 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(); } } 

Entonces cuando necesito jugar el sonido lo envío a un ThreadPool.

 private void playSound(final int soundToPlay) { final SoundRunnable soundRunnable = mediaPlayers.get(soundToPlay); if(soundRunnable != null){ threadPool.execute(soundRunnable); } } 

El principal problema que tengo es que los sonidos juegan dos veces la primera vez que ejecuto el runnable. Después de eso de vez en cuando todavía podría obtener un doble sonido, pero funciona bastante bien.

También he experimentado con la creación de un único AudioTrack en el modo de streaming y la escritura de audio en bruto de los runnables. Esto fue un poco exitoso, pero fue difícil saber cuándo detener la reproducción. Me detengo a temprano el sonido se corta corto, demasiado tarde y se obtiene un error de obtenerBuffer y la aplicación se bloquea. También jugando dos sonidos al mismo tiempo es difícil (podría possiblly utilizar una piscina de AudioTracks).

Me encantaría ver código de ejemplo para AudioTrack que no implica transmisión de audio.

Hice esta pregunta durante las horas de oficina de Google. Dijeron que AudioTrack tiene el mismo error que SoundPool. La única solución a este problema es escribir un reproductor multimedia nativo. Aunque, este problema sólo parece afectar a los teléfonos Dual Core que ejecutan Gingerbread.

  • ContentProvider insert () siempre se ejecuta en el hilo de interfaz de usuario?
  • AIDL vs Messenger
  • Hilos de aplicación vs Hilos de servicio
  • ¿Debería un MediaPlayer ejecutarse en hilos separados?
  • TimerTask vs Thread.sleep vs Handler postDelayed - más preciso para llamar a la función cada N milisegundos?
  • Los animadores sólo se pueden ejecutar en temas Looper Android
  • Android: RunOnUiThread vs AsyncTask
  • java.lang.IllegalStateException: Llamar Ver métodos en otro subproceso que el subproceso de interfaz de usuario
  • Android: la mejor práctica para realizar operaciones asíncronas en getView ()
  • PARTIAL_WAKE_LOCK vs SCREEN_DIM_WAKE_LOCK en el subproceso de descarga
  • Android Runtime Logcat solo obtiene la instancia actual
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.