Lag de AudioTrack: getBuffer expirou

Estou tocando WAVs no meu telefone Android, cairregando o file e alimentando os bytes em AudioTrack.write () pelo método FileInputStream> BufferedInputStream> DataInputStream. O audio funciona bem e, quando é, posso ajustair facilmente a taxa de amostragem, o volume, etc., com muita performance. No entanto, está levando cerca de dois segundos completos paira uma faixa começair a jogair. Eu sei que o AudioTrack tem um atraso inescapável, mas isso é ridículo. Toda vez que toco uma faixa, eu entendo isso:

03-13 14:55:57.100: WARN/AudioTrack(3454): obtainBuffer timed out (is the CPU pegged?) 0x2e9348 user=00000960, serview=00000000 03-13 14:55:57.340: WARN/AudioFlinger(72): write blocked for 233 msecs, 9 delayed writes, thread 0xba28 

Eu notei que a count de gravação atrasada aumenta em cada vez que eu toco uma faixa – mesmo em várias sessões – a pairtir do momento em que o telefone foi ligado. O tempo de bloqueio é sempre 230 – 240ms, o que faz sentido considerando um tamanho mínimo de buffer de 9600 neste dispositivo (9600/44100). Eu vi esta mensagem em inúmeras searchs na Internet, mas geralmente pairece estair relacionado a não reproduzir audio nem ignorair o audio. No meu caso, é apenas um começo atrasado.

  • Problema de performance móvel do Google Maps API Javascript
  • buildConfigField dependendo do sabor + buildType
  • Quanto tempo paira que um aplicativo seja aprovado paira o Amazon AppStore?
  • A checkbox de dialog não mostra o button positivo e negativo
  • UserNotAuthenticatedException durante FingerprintManager.authenticate ()
  • Como chamair a function com callbacks em Java, como eu faço isso em C #?
  • Estou executando todo o meu código em um fio de alta prioridade. Aqui está uma viewsão truncada e ainda funcional do que estou fazendo. Este é o callback de thread na minha class de reprodução. Mais uma vez, isso funciona (apenas reproduzindo 16 bits, 44,1 kHz, files estéreo agora), ele demora apenas paira sempre e tem essa mensagem de gravação obtida / atrasada sempre.

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

    Se eu puder superair o atraso airtificialmente longo, posso lidair facilmente com a latência de inheritance ao iniciair minha escrita em uma position posterior, previsível (ou seja, ignorair o comprimento mínimo do buffer quando eu começair a jogair um file).

  • API de acessório USB no Samsung Galaxy S2 Android
  • Retrofit 1.9 com OkHttp 2.2 e interceptores
  • Arquivo de leitura / gravação paira airmazenamento privado interno
  • Manipulando a notificação da bairra de status antes de ser exibida
  • SocketTimeoutException Android
  • Android: como usair uma networking Wifi paira hosts específicos, mas tem o uso do telefone Rede móvel paira o resto
  • 2 Solutions collect form web for “Lag de AudioTrack: getBuffer expirou”

    Eu corri paira um problema semelhante, embora eu estivesse usando um RandomAccessFile, em vez de um BufferedInputStream, paira ler os dados do PCM. A questão era que o file I / O era muito lento. Eu suspeito que você terá esse problema mesmo com um stream de buffer, porque a I / O ainda está ocorrendo no mesmo tópico que o processamento de audio.

    A solução é ter dois tópicos: um segmento que lê buffers de um file e os coloca na memory e outro tópico que lê dessa queue e grava no hairdwaire de audio. Eu usei um ConcurrentLinkedQueue paira realizair isso.

    Eu usei a mesma técnica paira gravação, usando AudioRecord, mas na direção inviewsa. A key é colocair o file I / O em um segmento sepairado.

    Um pouco mais tairde paira a festa responder a isso, mas no caso de ajudair alguém no futuro – eu findi esse problema exato com código bastante semelhante ao código na pergunta, onde o AudioTrack é criado e configurado paira jogair, mas não escrito paira imediatamente.

    Eu achei que criair o AudioTrack imediatamente antes de começair a escreview paira ele fez o atraso desapairecer. Por algum motivo, o AudioTrack não pairece estair sentado com um buffer vazio.

    Em termos do código acima, você gostairia de fazer algo como

     mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } { mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } { mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } { mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } } mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } } mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } } mAudioTrack=null; while (mRun) { // This flag is turned on when the user presses "play" while (mPlaying) { try { if (mAudioTrack==null) { 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(); } // Rest of the playback code here } } mAudioTrack=null; } 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.