如何在静态模式下使用 AudioTrack

How to use AudioTrack in static mode

我想在 Android 上玩浮点数组。我想先走(我认为是)简单的方法,所以我想我会使用 AudioTrack。我选择使用静态模式是因为音频流不是连续的。在文档中它说:

In static buffer mode, copies the data to the buffer starting at offset 0, and the write mode is ignored. Note that the actual playback of this data might occur after this function returns.

所以最初我的实现看起来像:

// 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, 0, sound.length, AudioTrack.WRITE_NON_BLOCKING);
    audioTrack.play()

这就导致了第一个问题,一个声音只能播放一次。我 found 我需要在 play() 之后调用 stop()reloadStaticData()。但这会导致根本无法播放第一个声音。以及以下任何声音播放错误(意味着声音错误)。

我试过将stop()reloadStaticData()放在write()之后和play()之前,然后播放第一个声音但接下来的声音是错误的(它们是第一个声音的截断版本而不是不同的声音)。

根据这些经验,在我看来 write() 并没有真正写入缓冲区的开头。一般来说如何使用 AudioTrack 我完全不清楚。 stop() 好像停止播放了。但是我必须在 play() 之后调用它来重置播放头位置。

原来我的 phone 扬声器无法播放声音...这是我的解决方案

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, 0, buffer.length, AudioTrack.WRITE_BLOCKING);
        audioTrack.play();
    }