¿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.
- Problemas de AsyncTasks múltiples en Android Spinner
- ¿Debo hacer el trabajo en un hilo separado si mi aplicación Android no tiene interfaz de usuario?
- Cómo guardar un archivo con un hilo de fondo en Android
- Android: Sincronización con el subproceso de procesador de OpenGL
- Detener el hilo mediante la declaración de devolución
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.
- Espere hasta que se haya agregado fragmento a la interfaz de usuario
- ¿Cómo gestiona la memoria Android?
- Registrar un receptor de difusión de un servicio en un nuevo hilo
- Asynch hilo que detiene el hilo principal de interfaz de usuario
- Seguridad de subprocesos al realizar iteraciones a través de un ArrayList utilizando foreach
- SQLite database, multithreading, bloqueos y sincronización de cuentas en android
- ¿Cómo descargar múltiples archivos simultáneamente usando intentservice en Android?
- ¿Cómo puedo pasar objetos ejecutables a un manejador?
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.
- ¿Cómo subir un video a YouTube en Android?
- ¿Conoces alguna herramienta de instrumentación dinámica para Android con soporte para múltiples dispositivos (idealmente en Python o Jython)?