2013-12-11 3 views
10

Я пытаюсь понять, как использовать буфер с AudioTrack для эффективного потока музыки. Я знаю, что вы можете записывать в очередь аудио, используя метод write, но как только звук поставлен в очередь, как вы скажете, сколько осталось от того, сколько было использовано/сыграно? Извините, если это рудиментарный вопрос. Я понимаю концепцию буфера, я просто не уверен, как писать, особенно используя AudioTrack.Использование буфера с Android AudioTrack

+0

Почему вы хотите знать: «Сколько осталось, сколько было использовано/сыграно»? –

+0

Чтобы уведомить пользователя о том, что приложение буферизует и выполняет соответствующую логику. –

ответ

14

AudioTrack.write() возвращает «число записанных байтов» как межд, и указать количество байтов в буфере при построении AudioTrack.

Поэтому, чтобы отслеживать, сколько буферного пространства осталось, вы можете сохранить переменную аккумулятора, чтобы вы знали, сколько байтов было записано в общей сложности, и установите эту переменную равной нулю, когда вы вызываете AudioTrack.flush(). Однако связанная документация гласит, что «типично использовать куски 1/2 от общего размера, чтобы разрешить двойную буферизацию», поэтому может быть достаточно просто запомнить, если вы написали нуль один или два раза с момента вызова flush ,

сказать, сколько из буфера игрался, используйте AudioTrack.getPlaybackHeadPosition(), которая возвращает количество кадров, которые были сыграны текущего буфера (т.е. обнулены на остановке, утопленного или пересылкой) как знаковые 32-разрядное целое число, но должно интерпретироваться как unsigned 32-разрядное целое число. Все это на самом деле означает, что вы назначаете его в int следующим образом.

int bufferPlaybackFrame = myAudioTrack.getPlaybackHeadPosition() & 0xFF; 

Вы можете думать о кадрах как эквивалентных образцам. т. е. вы можете работать с AudioFormat, используемым для построения AudioTrack, сколько бит (и, следовательно, байтов) используется для каждого образца.

Наконец, на случай, если кто-то задается вопросом, вы никогда не сможете сказать, сколько исходного файла или потока осталось играть через этот объект (одна из причин заключается в том, что он предназначен для работы с постоянными 24/7 потоками, без конца), поэтому, если вы хотите сделать расчет, как вы видите на некоторых видеоиграх на веб-сайтах, которые приостанавливают поток до тех пор, пока достаточно буферизованного идентификатора, чтобы увидеть все видео с текущей скоростью загрузки, вам придется передать эту информацию в каким-то другим способом.

+1

Спасибо, очень полезный ответ. –

+0

@ А что, если я хочу скачать (один раз) аудиофайлы с сервера, а затем файлы должны играть в офлайн-режиме. ? –

+0

@DevendraSingh, тогда вы бы использовали другой класс и метод вместе (у меня нет интуиции относительно того). Это для доступа к постоянным, бесконечным, 24/7 потокам, которые вы не можете загружать и играть в офлайн-режиме. –

2

* Этот код поможет воспроизводить аудио с буфером *

private void PlayShortAudioFileViaAudioTrack(String filePath) throws IOException 
    { 

    // We keep temporarily filePath globally as we have only two sample sounds now.. 

    if (filePath==null)                  
    return; 

    //Reading the file.. 

    byte[] byteData = null; 
    File file = null; 
    file = new File(filePath); 

    // for ex. path= "/sdcard/samplesound.pcm" or "/sdcard/samplesound.wav" 

    byteData = new byte[(int) file.length()]; 
    FileInputStream in = null; 
    try { 
    in = new FileInputStream(file); 
    in.read(byteData); 
    in.close(); 
    } catch (FileNotFoundException e) { 

    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
    // Set and push to audio track.. 

    int intSize = android.media.AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
    AudioFormat.ENCODING_PCM_8BIT); 
    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
    AudioFormat.ENCODING_PCM_8BIT, intSize, AudioTrack.MODE_STREAM); 
    if (at!=null) { 
    at.play(); 

    // Write the byte array to the track 

at.write(byteData, 0, byteData.length); 
    at.stop(); 
    at.release(); 
    } 
    else 
    Log.d("TCAudio", "audio track is not initialised "); 
    } 
+0

Извините, я должен был быть более конкретным. У меня нет доступа ко всему файлу, потому что я его передаю, поэтому я не могу загрузить весь файл в буфер перед воспроизведением. –

Смежные вопросы