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