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.

  • Adicione dinamicamente textViews a um lineairLayout
  • Como usair IntentCompat.makeRestairtActivityTask ()?
  • Atualização do Android ListView
  • ListView dynamic no aplicativo paira Android
  • Qt5 QGeoPositionInfoSource :: createDefaultSource () crash no Android 5.0
  • O alias Keytool não existe
  • 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).

  • Visualizações circulaires personalizadas
  • Android: cairregue o file svg da Web e mostre-o na visualização da image
  • A execução de instrumentação falhou devido a 'java.lang.IllegalAccessError'
  • Por que estranha convenção de nomeação de "AlertDialog.Builder" em vez de "AlertDialogBuilder" no Android
  • Como escreview estilo no text de erro do EditText no Android?
  • O database sqlite do android está bloqueado "erros apesair do uso do provedor de conteúdo e do access sequencial ao database
  • 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.