Обнаружение окончания воспроизведения в AudioTrack не работает

Это код, который я использую:

void playSound(){
    final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
            AudioTrack.MODE_STATIC);
    // audioTrack.setNotificationMarkerPosition(generatedSnd.length/2);
    audioTrack.setNotificationMarkerPosition(1);
    audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() {
        @Override
        public void onPeriodicNotification(AudioTrack track) {
            // nothing to do
        }

        @Override
        public void onMarkerReached(AudioTrack track) {
            // Log.d(LOG_TAG, "Audio track end of file reached...");
            // messageHandler.sendMessage(messageHandler.obtainMessage(PLAYBACK_END_REACHED));
            Log.d("MY LOG", "Audio track end of file reached...");
            bitPatternValTextView.setText("End of play");
        }
    });
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
    audioTrack.play();
}  

Функция playSound() определена внутри

открытый класс InSituActivity расширяет ActionBarActivity{...}

Мое предположение заключалось в том, что когда воспроизведение AudioTrack достигает N-го аудиосэмпла (каждый N является коротким или 2 байта), тогда audioTrack.setNotificationMarkerPosition(N); вызовет onMarkerReached(AudioTrack track). Однако, как показано в моем примере кода, я пробовал как generatedSnd.length/2 (generatedSnd[] — это массив байтов, который содержит аудиосэмплы, которые я хочу воспроизвести), так и использование небольших постоянных значений, таких как 1, 10 или 20, и onMarkerReached() не кажется чтобы получить вызов в любой из этих ситуаций. Что здесь не так и как это исправить? Я хочу иметь возможность воспроизводить другой звук, когда текущий AudioTrack заканчивает воспроизведение. Сама функция playSound() будет вызываться в потоке (отдельно от потока пользовательского интерфейса).

Вот откуда я взял код:
Как сказать, когда закончилось воспроизведение объекта AudioTrack?

Другие ссылки:
AudioTrack: как определить конец звука?
Путаница по поводу жизни потока и AudioTrack в android java< /а>


person user13267    schedule 22.12.2014    source источник
comment
Вы должны использовать длину файла в количестве кадров с setNotificationMarkerPosition вместо 1. Кстати, это должно быть большое число.   -  person Karioki    schedule 22.12.2014
comment
1 - это просто тестовый номер, если бы он работал, я должен был увидеть какое-то уведомление в логарифме.   -  person user13267    schedule 22.12.2014
comment
Если вы используете отдельный поток, попробуйте MODE_STREAM и подавайте AudioTrack в цикле до конца данных.   -  person pskink    schedule 22.12.2014
comment
хорошо, это работает, но почему это не работает для статики?   -  person user13267    schedule 22.12.2014
comment
что вы подразумеваете под звуковой дорожкой канала? У меня есть все звуковые образцы, которые мне нужно сгенерировать в массиве generateSnd, я думаю, что было бы лучше воспроизводить все как статическое   -  person user13267    schedule 22.12.2014
comment
кстати, я изменил на MODE_STREAM до того, как вы отредактировали свой комментарий, поэтому в настоящее время в моем коде единственная разница в том, что я изменил MODE_STATIC на MODE_STREAM   -  person user13267    schedule 22.12.2014
comment
Я не знаю, почему это не работает для вас: мой слушатель вызывается в статическом режиме, вообще никаких проблем   -  person pskink    schedule 22.12.2014
comment
не могли бы вы поделиться этим разделом вашего кода, пожалуйста?   -  person user13267    schedule 22.12.2014
comment
убедитесь, что pastebin.com/yz2qjneH   -  person pskink    schedule 22.12.2014
comment
не может ли использование setPlaybackPositionUpdateListener() быть причиной разницы?   -  person user13267    schedule 22.12.2014
comment
что вы имеете в виду: не мог использовать?   -  person pskink    schedule 22.12.2014
comment
может ли быть так, что неиспользование setPlaybackPositionUpdateListener() вызывает проблему в моем коде?   -  person user13267    schedule 22.12.2014
comment
??? вы используете его: audioTrack.setPlaybackPositionUpdateListener (новый ...   -  person pskink    schedule 22.12.2014
comment
ага не заметил извините   -  person user13267    schedule 22.12.2014
comment
извините, пожалуйста, я еще не очень хорошо знаком с андроидом   -  person user13267    schedule 22.12.2014


Ответы (1)


может быть, слишком поздно для ответа, но это сработало для меня. Я также не получал обратного вызова onMarkerReached(). Я просто увеличил размер статического потока на большое число. Может не работать для MODE_STREAM или для разных размеров буфера. Работает для всех размеров буфера, которые мне нужны, что составляет несколько десятков секунд максимум для моих вариантов использования. Попробуйте изменить эту строку в своем коде и посмотрите, что произойдет:

int magic_number = 1000; // try with different values. Maybe make it 10% of generatedSnd.length?
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
        sampleRate, AudioFormat.CHANNEL_OUT_MONO,
        AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
        AudioTrack.MODE_STATIC + magic_number);
person rroh    schedule 17.03.2017