2011-05-18 12 views
6

Tengo un problema con AudioTrack, esta API de Android me está matando. No tengo experiencia previa con Android o Java, pero soy un codificador con mucha experiencia (asm, C++, etc. en muchas plataformas) y nunca pensé que fuera particularmente tonto, como me hace sentir Android ahora.Android AudioTrack MODE_STATIC problemas de reproducción

¿Qué estoy haciendo mal? Aparentemente nada:

audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minbufsizbytes*64, AudioTrack.MODE_STATIC); 
audioTrack.write(Buffer, 0, numSamples); 
audioTrack.play(); 

realidad de sampleRate = 8000 y minbufsizbytes = 742, los cuales (742 * 64 = 47488) es considerablemente más grande que el búfer que estoy escribiendo (16000 muestras de 16 bits).

El audio suena bien la primera vez. Pero ... ¿cómo lo juego más de una vez? (por ejemplo, en respuesta a un evento, como, por ejemplo, una tecla de piano presionada). Si invoco play() nuevamente, no se producirá ningún sonido nuevo. Así que después de días de frustración, esto es lo que ocurrió:

for (i=0;;i++) { 
    SystemClock.sleep(3000L); // so the problem is NOT "fast, repeated attempts to replay sound", but looks like internal buffer overrun related (please see the Log'ed error below) 
    audioTrack.stop(); 
    audioTrack.reloadStaticData(); 
    audioTrack.setPlaybackHeadPosition(0); 
    audioTrack.play(); 
} 

Así que reproduce el sonido de una segunda o tercera vez .. entonces NO AUDIO !! (!) Y el registro se inunda por este mensaje de error:

05-18 13:03:16.785: ERROR/AudioFlinger(345): TrackBase::getBuffer buffer out of range: 
05-18 13:03:16.785: ERROR/AudioFlinger(345):  start: 0x404fb680, end 0x404fb7f2 , mBuffer 0x40507000 mBufferEnd 0x40512980 
05-18 13:03:16.785: ERROR/AudioFlinger(345):      server 0, serverBase 23744, user 47488, userBase 47488, channels 1 

que luego debe reiniciar el teléfono (emulado o real) de lo contrario el registro de la inundación no se detiene ..

(mal) se comporta en mi Galaxy 2.2 .1, en mi IDEOS 2.1 y en el emulador (varias versiones) ... así que no es un problema de error del teléfono.

Si hago el buffer interno más grande (quinto parámetro en AudioTrack), que jugará más veces antes de que deje de emitir sonidos y comienza a inundar el registro, por lo que creo que es como si un buffer interno era invadieron

PS : ¿sabes si getMinBufferSize devuelve muestras o bytes (incluso para PCM_16BIT), como han informado algunos?

Respuesta

4

¡Aquí hay una muestra de código que se ejecutó varias veces! 'Super' es un AudioTrack

juego public void() {

switch (super.getPlayState()) { 
    case AudioTrack.PLAYSTATE_PAUSED: 
    super.stop(); 
     super.reloadStaticData(); 
     super.play(); 
     break; 
    case AudioTrack.PLAYSTATE_PLAYING: 
    super.stop(); 
     super.reloadStaticData(); 
     super.play(); 
     break; 
    case AudioTrack.PLAYSTATE_STOPPED: 
     super.reloadStaticData(); 
     super.play(); 
     break; 
    } 

}

Cuestiones relacionadas