在静态模式下使用AudioTrack的正确方法是什么?

the*_*osh 5 java audio multithreading android

我有一个Android游戏,我需要播放短音.SoundPool双核手机上崩溃,Mediaplayer200毫秒+延迟,OpenSL需要SDK 9+(我支持1.5).这就离开了AudioTrack.

这就是我尝试过的.我像这样创建AudioTrack对象.

protected AudioTrack createAudioTrack() {
    final int trackSize = 17408;
    return new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT, trackSize, AudioTrack.MODE_STATIC);
}
Run Code Online (Sandbox Code Playgroud)

然后我在游戏声音(约8)中为每个创建一个runnable.

private static class SoundRunnable implements Runnable {

    private final AudioTrack sound;
    private final byte[] rawAudio;

    public SoundRunnable(final AudioTrack sound, final byte[] rawAudio){
        this.sound = sound;
        this.rawAudio = rawAudio;
        sound.write(rawAudio, 0, rawAudio.length);
    }

    @Override
    public void run() {
        playSound();
    }

    private synchronized void playSound() {
        switch (sound.getPlayState()) {
        case AudioTrack.PLAYSTATE_PAUSED:
            sound.stop();
            sound.reloadStaticData();
            sound.play();
        break;
        case AudioTrack.PLAYSTATE_PLAYING:
            sound.stop();
            sound.reloadStaticData();
            sound.play();
        break;
        case AudioTrack.PLAYSTATE_STOPPED:
            sound.reloadStaticData();
            sound.play();
        break;
        default:
            break;
        }
    }   

    public synchronized void release() {
        sound.release();
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,当我需要播放声音时,我将它发送到ThreadPool.

private void playSound(final int soundToPlay) {
    final SoundRunnable soundRunnable = mediaPlayers.get(soundToPlay);
    if(soundRunnable != null){
        threadPool.execute(soundRunnable);
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的主要问题是,第一次执行runnable时声音会播放两次.在那之后每隔一段时间我仍然会得到一个双重声音,但它的效果非常好.

我还尝试在流模式下创建单个AudioTrack并从runnables编写原始音频.这有点成功,但很难知道何时停止播放.我你早点停止声音被缩短,太晚了,你得到一个gainBuffer错误,应用程序锁定.同时播放两个声音也很困难(可能会使用AudioTracks池).

我很想看到AudioTrack的示例代码,它不涉及流式音频.

the*_*osh 1

我在 Google 办公时间问了这个问题。他们说AudioTrack 和SoundPool 有同样的bug。解决这个问题的唯一方法是编写一个本机媒体播放器。不过,这个问题似乎只影响运行 Gingerbread 的双核手机。