Estoy reproduciendo WAV en mi teléfono Android cargando el archivo y alimentando los bytes en AudioTrack.write() a través del método FileInputStream> BufferedInputStream> DataInputStream. El audio funciona bien y, cuando lo hace, puedo ajustar fácilmente la frecuencia de muestreo, el volumen, etc. sobre la marcha con un buen rendimiento. Sin embargo, tomará unos dos segundos completos para que una pista comience a reproducirse. Sé que AudioTrack tiene un retraso ineludible, pero esto es ridículo. Cada vez que juego una pista, me sale esto:Retraso de audio: obtener el tiempo de espera agotado
03-13 14:55:57.100: WARN/AudioTrack(3454): obtainBuffer timed out (is the CPU pegged?) 0x2e9348 user=00000960, server=00000000
03-13 14:55:57.340: WARN/AudioFlinger(72): write blocked for 233 msecs, 9 delayed writes, thread 0xba28
me he dado cuenta que el recuento de escritura demorada se incrementa en uno cada vez que juegan una pista - incluso a través de múltiples sesiones - desde el momento en que el teléfono tiene encendido. El tiempo de bloqueo siempre es de 230 a 240 ms, lo cual tiene sentido considerando un tamaño mínimo de buffer de 9600 en este dispositivo (9600/44100). He visto este mensaje en innumerables búsquedas en Internet, pero por lo general parece estar relacionado con la falta de reproducción del audio o la omisión del audio. En mi caso, es solo un comienzo retrasado.
Estoy ejecutando todo mi código con un hilo de alta prioridad. Aquí hay una versión truncada pero funcional de lo que estoy haciendo. Esta es la devolución de llamada del hilo en mi clase de reproducción. De nuevo, esto funciona (solo reproduce archivos estéreo de 16 bits, 44.1kHz en este momento), solo toma una eternidad comenzar y tiene ese mensaje getBuffer/demora de escritura cada vez.
public void run() {
// Load file
FileInputStream mFileInputStream;
try {
// mFile is instance of custom file class -- this is correct,
// so don't sweat this line
mFileInputStream = new FileInputStream(mFile.path());
} catch (FileNotFoundException e) {
// log
}
BufferedInputStream mBufferedInputStream = new BufferedInputStream(mFileInputStream, mBufferLength);
DataInputStream mDataInputStream = new DataInputStream(mBufferedInputStream);
// Skip header
try {
if (mDataInputStream.available() > 44) {
mDataInputStream.skipBytes(44);
}
} catch (IOException e) {
// log
}
// Initialize device
mAudioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
ConfigManager.SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
ConfigManager.AUDIO_BUFFER_LENGTH,
AudioTrack.MODE_STREAM
);
mAudioTrack.play();
// Initialize buffer
byte[] mByteArray = new byte[mBufferLength];
int mBytesToWrite = 0;
int mBytesWritten = 0;
// Loop to keep thread running
while (mRun) {
// This flag is turned on when the user presses "play"
while (mPlaying) {
try {
// Check if data is available
if (mDataInputStream.available() > 0) {
// Read data from file and write to audio device
mBytesToWrite = mDataInputStream.read(mByteArray, 0, mBufferLength);
mBytesWritten += mAudioTrack.write(mByteArray, 0, mBytesToWrite);
}
}
catch (IOException e){
// log
}
}
}
}
Si puedo conseguir más allá del artificialmente largo intervalo, puedo tratar fácilmente con la latencia hereda iniciando mi escritura en una posición más tarde, predecible (es decir, pasar de largo la longitud del búfer mínimo cuando empieza a reproducir un archivo)
Tengo un problema similar en el momento. ¿Encontraste alguna solución? – sunside
todavía no, lamentablemente. :/ – BTR