问题描述
我想在 Android 上播放浮点数组。我想先走(我认为是)简单的方法,所以我想我会使用 AudioTrack。我选择使用静态模式是因为音频流不是连续的。在文档中它说:
在静态缓冲模式下,将数据复制到偏移量0开始的缓冲中,写入模式被忽略。请注意,此数据的实际播放可能会在此函数返回后发生。
所以最初我的实现看起来像:
// constructor ..
audioTrack = new AudioTrack(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build(),new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_FLOAT)
.setSampleRate(sample_rate)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO).build(),sample_rate * 2 * 10,AudioTrack.MODE_STATIC,AudioManager.AUdio_SESSION_ID_GENERATE);
[...]
public ... () { // function
audioTrack.write(sound,sound.length,AudioTrack.WRITE_NON_BLOCKING);
audioTrack.play()
这导致了一个声音只能播放一次的第一个问题。我found 我需要在stop()
之后调用reloadStaticData()
和play()
。但这会导致根本没有播放第一个声音。以及任何以下声音播放错误(意味着声音错误)。
我尝试将 stop()
和 reloadStaticData()
放在 write()
之后和 play()
之前,然后播放第一个声音但接下来的声音是错误的(它们是一个剪辑关闭版本的第一个声音而不是不同的声音)。
根据这些经验,在我看来 write()
实际上并未写入缓冲区的开头。一般来说,我完全不清楚如何使用 AudioTrack
。 stop()
似乎停止播放。但是我必须在 play()
之后调用它来重置播放头位置。
解决方法
原来我的手机扬声器无法播放声音......这是我的解决方案
public void play_sound(float[] sound) {
if (audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
audioTrack.stop();
audioTrack.reloadStaticData();
}
float[] buffer = new float[buffer_size_in_bytes / 4];
for (int i = 0; i < sound.length; i++) {
buffer[i] = sound[i];
}
// Last arg is ignored.
audioTrack.write(buffer,buffer.length,AudioTrack.WRITE_BLOCKING);
audioTrack.play();
}