使用Android AudioTrack的缓冲区

时间:2013-12-11 05:22:27

标签: android audiotrack

我试图想象一下如何使用AudioTrack的缓冲区来有效地传输音乐。我知道您可以使用write方法对音频进行排队,但是一旦音频排队,您如何知道剩余多少以及使用/播放了多少?对不起,如果这是一个基本问题。我理解缓冲区的概念我不知道如何编写缓冲区,特别是使用AudioTrack。

2 个答案:

答案 0 :(得分:16)

AudioTrack.write()返回“写入的字节数”作为int,并指定构造AudioTrack时缓冲区中的字节数。

因此,要跟踪剩余的缓冲区空间,可以保留一个累加器变量,以便知道总共写入了多少字节,并在每次调用AudioTrack.flush()时将此变量设置为零。但是,链接文档指出“通常使用总大小的1/2的块来允许双缓冲”,所以它可能很简单,只需记住你是否写了零,一次或两次,因为调用flush

要知道已播放了多少缓冲区,请使用AudioTrack.getPlaybackHeadPosition()返回已经播放当前缓冲区帧数(即在停止,刷新或重新加载时重置为零)作为带符号的32位整数,但要解释为无符号32位整数。所有这些真正意味着你将它分配给一个int如下。

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

您可以将帧视为与样本等效。即,你可以从用于构造AudioTrack的AudioFormat中找出每个样本使用多少位(以及字节)。

最后,如果有人想知道,你永远无法知道有多少源文件或流通过这个对象来播放(原因之一是它被设计为使用永久的24/7流,没有结束),所以如果你想在一些视频播放网站上进行计算,那么暂停流直到足够的id缓冲以按当前下载速率查看整个视频,你必须将这些信息传递给某些另一种方式。

答案 1 :(得分: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 ");
     }