AudioTrack.write()。 Android文档说
但是,在我的代码中,write()方法似乎要等到整个缓冲区播放完毕,直到扬声器发出声音。因此,例如,事后不能再调用stop()方法或填充更多数据。
音轨通过以下方式初始化:
int mBufferSize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_8BIT);
AudioTrack mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
mBufferSize, AudioTrack.MODE_STREAM);
int duration = 44100*5;
short[] mBuffer = new short[duration];
在onCreate中:
for (int i = 0; i < wavelength; i++) {
waveform[i] = Math.sin(((double) i)/wavelength * 2 * Math.PI - Math.PI);
}
mAudioTrack.play();
单击按钮时,这称为:
private void playSound(double frequency, int duration) {
int idx = 0;
for (int i = 0; i < duration-1; i++) {
idx = idx + (int) Math.ceil(frequency);
if (idx > wavelength-1)
idx = idx % wavelength;
mBuffer[i] = (short) (waveform[idx] * Short.MAX_VALUE);
}
long startTime = System.currentTimeMillis();
ret = mAudioTrack.write(mBuffer, 0, mBuffer.length);
long runtime = System.currentTimeMillis() - startTime;
debugText.setText(Long.toString(runtime));
}
时间戳显示,write()调用恰好花费了5秒钟,这就是音频剪辑的长度,而且我不相信传输时间会完全相同。我想生成更多要播放的数据(也许以其他频率播放),同时仍在播放先前的数据。我知道有些开发人员使用多个线程(而且我没有线程处理经验,所以我不知道该怎么做),但是文档表明也可以通过这种方式...
最佳答案
调用AudioTrack.write(...)
会阻止,直到将所有提供的数据复制到AudioTrack的流缓冲区中为止。 AudioTrack缓冲区的大小(上面的mBufferSize
)设置为AudioTrack.getMinBufferSize(...)
,因此显然很小,可以肯定只需要一秒钟的音频。
您想要排队的5秒钟音频数据显然无法容纳如此小的缓冲区。因此,AudioTrack.write(...)
必须重复填充该缓冲区,因为缓冲区正在被播放耗尽。在返回之前,它必须使音频数据的最后一部分入队。并且在它可以执行之前,它必须至少等待,直到播放了除音频数据的最后mBufferSize
以外的所有内容。
如果您增加mBufferSize
的数量,您应该开始看到AudioTrack.write
call 阻塞的时间减少了。
关于android - 播放整个缓冲区后,Android AudioTrack.write()返回,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39741926/