Как правильно поставить AudioTrack на паузу и продолжить плавное воспроизведение?

Я использую Android AudioTrack для воспроизведения ранее записанного файла PCM. Если я не ставлю паузу во время игры, все в порядке; но если я сделаю паузу и продолжу, большая часть звука (около 1 секунды) будет пропущена. Вот мой код:

// Player thread
audioTrack = new AudioTrack(
                    AudioManager.STREAM_MUSIC,
                    RECORDER_SAMPLERATE,
                    AudioFormat.CHANNEL_OUT_MONO,
                    RECORDER_AUDIO_ENCODING,
                    bufferSize,
                    AudioTrack.MODE_STREAM);

audioTrack.play();

FileInputStream is = null;
try {
    is = new FileInputStream(filePath);
} catch (FileNotFoundException e){
    e.printStackTrace();
    return;
}

byte[] buffer = new byte[bufferSize];
int offset = 0;

while (true) {
    if(paused) { continue;}

    int cnt = 0;
    try {
       cnt = is.read(buffer, 0, bufferSize);
    } catch (IOException e){
       e.printStackTrace();
    }
    if(cnt < 0) break;
    audioTrack.write(buffer, 0, cnt);
    audioTrack.play();
}
audioTrack.release();

А вот код для приостановки и возобновления игры:

public void pause(){
    this.paused = true;
    audioTrack.pause();
}

public void resume(){
    this.paused = false;
}

Что не так? Как правильно делать pause?


person NeoWang    schedule 13.09.2019    source источник
comment
Вы вызываете audioTrack.play(); в основном потоке (класс Activity / Fragment) без какой-либо службы?   -  person Deˣ    schedule 13.09.2019
comment
Я бы посоветовал обернуть код воспроизведения звуковой дорожки в служебный класс в фоновом потоке. затем вы можете добиться функциональности воспроизведения / паузы с помощью широковещательных приемников.   -  person Deˣ    schedule 13.09.2019
comment
Нет, первая часть кода вынесена в отдельный поток.   -  person NeoWang    schedule 13.09.2019


Ответы (1)


Скорее всего, write возвращает короткий счетчик передач. Согласно документация

... если дорожка останавливается или приостанавливается при входе ... тогда запись может вернуть короткий счетчик передач.

Ваш код не учитывает этот пограничный случай, поэтому вполне вероятно, что весь буфер аудио просто теряется.

Простым решением может быть попытка выполнить второй write сразу после play(), но только в том случае, если первый write возвращает короткий счет. Этот второй write должен учитывать именно те байты, которые не были записаны во время первого write.

person greeble31    schedule 13.09.2019