android - AudioFlinger no pudo crear una pista. estado:-12
soundpool (9)
Estoy programando para android 2.2 y estoy tratando de usar la clase SoundPool para reproducir varios sonidos simultáneamente pero a lo que parece que el sonido de los tiempos aleatorios dejará de salir de los altavoces.
para cada sonido que se hubiera reproducido, esto se imprime en el logcat:
AudioFlinger could not create track. status: -12
Error creating AudioTrack
Audio track delete
No se lanza ninguna excepción y el programa continúa ejecutándose sin ningún cambio a excepción de la falta de volumen. Me ha costado mucho rastrear qué condiciones causan el error o volver a crearlo después de que ocurre. No puedo encontrar el error en la documentación en ninguna parte y estoy bastante perdido.
¡Cualquier ayuda sería muy apreciada!
Editar: Olvidé mencionar que estoy cargando archivos mp3, no ogg.
Como dije anteriormente, hay un problema con el bucle: cuando establezco repetir en -1 recibo este error, pero con 0 todo está funcionando correctamente. Me he dado cuenta de que algunos sonidos dan este error cuando intento tocarlos uno por uno. Por ejemplo:
mSoundPool.stop(mStreamID);
mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f);
En tal caso, la primera pista se reproduce bien, pero cuando cambio los sonidos, la siguiente pista produce este error. Parece que al usar looping, un buffer está de alguna manera sobrecargado, y mSoundPool.stop no puede liberar recursos inmediatamente.
Solución :
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f);
}, 350);
Y está funcionando, pero la demora es diferente para diferentes dispositivos.
En mi caso, reducir la calidad y, por lo tanto, el tamaño de los archivos MP3 a menos de 100 kb no fue suficiente, ya que algunos archivos de 51 kb funcionaron, mientras que algunos archivos de 41 kb de mayor duración aún no lo hicieron.
Lo que nos ayudó fue reducir la frecuencia de muestreo de 44100 a 22050 o acortar la duración a menos de 5 segundos.
Estaba con este problema. Para resolverlo, ejecuto el método .release () del objeto SoundPool después de terminar de reproducir el sonido.
Aquí está mi código:
SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 50);
final int teste = pool.load(this.ctx,this.soundS,1);
pool.setOnLoadCompleteListener(new OnLoadCompleteListener(){
@Override
public void onLoadComplete(SoundPool sound,int sampleId,int status){
pool.play(teste, 20,20, 1, 0, 1);
new Thread(new Runnable(){
@Override
public void run(){
try {
Thread.sleep(2000);
pool.release();
} catch (InterruptedException e) { e.printStackTrace(); }
}
}).start();
}
});
Tenga en cuenta que en mi caso mis sonidos tenían una longitud de 1-2 segundos como máximo, así que puse el valor de 2000 milisegundos en Thread.sleep (), para liberar solo los recursos después de que el reproductor haya terminado.
Tratar
final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 50);
tg.startTone(ToneGenerator.TONE_PROP_BEEP, 200);
tg.release();
La liberación debe mantener sus recursos.
Tuve un problema similar en el que el rastreador de música dentro de mi juego para Android soltaba notas y recibía el error de Audioflinger (aunque mi estado era -22). Lo hice funcionar sin embargo así que esto podría ayudar a algunas personas.
El problema ocurrió cuando se estaba emitiendo una sola muestra varias veces simultáneamente. Entonces, en mi caso, se trataba de una única muestra que se reproducía en dos o más pistas. Esto parecía ocasionalmente un punto muerto o algo así y una de las dos notas se descartaría. La solución era tener dos copias de la muestra (dos archivos ogg reales, idénticos pero ambos en los activos). Luego, en cada pista, aunque estaba reproduciendo la misma muestra, venía de un archivo diferente. Esto solucionó totalmente el problema para mí.
No estoy seguro de por qué funciona, ya que almaceno las muestras en la memoria, pero incluso cargar el mismo archivo en dos sonidos diferentes no lo solucionó. Solo cuando las muestras salieron de dos archivos diferentes, los errores desaparecieron.
Estoy seguro de que esto no ayudará a todos y no es la solución más bonita, pero podría ayudar a alguien.
Un solo SoundPool tiene una limitación de memoria interna de 1 (un) Mb. Usted podría estar golpeando esto si su sonido es de muy alta calidad. Si tiene muchos sonidos y está llegando a este límite, simplemente cree más conjuntos de sonido y distribuya sus sonidos a través de ellos.
Es posible que ni siquiera sea capaz de alcanzar el límite de la pista dura si se está quedando sin memoria antes de llegar allí.
Ese error no solo aparece cuando se alcanza el límite de transmisión o de ruta, sino también el límite de memoria. Soundpool dejará de reproducir sonidos viejos y / o sin prioridad para reproducir un sonido nuevo.
Veo demasiadas respuestas complicadas. El error -12 significa que no ha liberado las variables. Tuve el mismo problema después de reproducir un archivo de audio OGG 8 veces. Esto funcionó para mí:
SoundPoolPlayer onBeep; //Global variable
if(onBeep!=null){
onBeep.release();
}
onBeep = SoundPoolPlayer.create(getContext(), R.raw.micon);
onBeep.setOnCompletionListener(
new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) { //mp will be null here
loge("ON Beep! END");
startGoogleASR_API_inner();
}
}
);
onBeep.play();
Liberar la variable justo después de .play () estropearía las cosas, y no es posible liberar la variable dentro de onCompletion, así que observe cómo lanzo la variable antes de usarla (y buscando null para evitar excepciones de nullpointer).
¡Funciona como el encanto!
john.k.doe tiene razón. Debes reducir el tamaño de tu archivo mp3. Debe mantener el tamaño por debajo de 100 kb por archivo. Tuve que reducir mi archivo de 200kb a 72kb usando una tasa de bits constante (CBR) de 32 kbps en lugar de los 128kbps habituales. ¡Eso funcionó para mí!
tuve casi el mismo problema con algunos sonidos que estaba intentando cargar y reproducir recientemente.
Incluso lo descompuse para cargar un solo mp3 que estaba causando este error.
Una cosa noté: cuando cargué con un bucle de -1, fallaría con el error de "estado 12", pero cuando lo cargué en un bucle 0 veces, tendría éxito. incluso el intento de cargar 1 vez falló.
la solución final fue abrir el mp3 en un editor de audio y volver a editarlo con una calidad ligeramente inferior para que el archivo sea ahora más pequeño y no parezca que ocupe tantos recursos en el sistema.
finalmente, existe esta discusión que alienta la realización de un lanzamiento en los objetos que está utilizando, porque de hecho hay un límite estricto en los recursos que se pueden usar, y es todo el sistema, por lo que si usa varios de los recursos, otros las aplicaciones no podrán usarlas.
https://groups.google.com/forum/#!topic/android-platform/tyITQ09vV3s/discussion%5B1-25%5D
Para audio, hay un límite estricto de 32 objetos AudioTrack activos por dispositivo (no por aplicación: necesita compartir esos 32 con el resto del sistema), y AudioTrack se usa internamente debajo de SoundPool, ToneGenerator, MediaPlayer, audio nativo basado en OpenSL ES , etc. Pero el límite real de AudioTrack es <32; depende más de factores blandos como la memoria, la carga de la CPU, etc. También tenga en cuenta que el limitador en el mezclador de audio Android actualmente no tiene compresión de rango dinámico, por lo que es posible hacer un clip si tiene una gran cantidad de sonidos activos y todo es ruidoso
Para los reproductores de video, el límite es mucho más bajo debido a la carga intensa que el video pone en el dispositivo.
Utilizaré esto como una oportunidad para recordarles a los desarrolladores de medios: recuerden llamar a release () para objetos multimedia cuando su aplicación esté en pausa. Esto libera los recursos subyacentes que necesitarán otras aplicaciones. No confíe en los objetos de medios que se limpian al finalizar el recolector de elementos no utilizados, ya que eso tiene un tiempo impredecible.