Перезапуск AudioTrack даже после его остановки
Я создал простое приложение, которое генерирует прямоугольную волну данной частоты и воспроизводит ее с помощью AudioTrack в режиме STREAM (STREAM_MUSIC). Кажется, что все работает нормально, и звук звучит нормально, но когда поток закончен, я получаю сообщения в журнале:
W/AudioTrack (7579): getBuffer() трек 0x14c228 отключен, перезапущен...
Даже после вызова функции stop() я все еще получаю их.
Я считаю, что правильно настроил размер буфера AudioTrack на основе минимального размера, необходимого AudioTrack (в моем случае 6x1024). Я питаю его меньшими буферами в 1024 шортах.
Хорошо ли, что я получаю это, и должен ли я оставить его таким?
Ответы
Ответ 1
Хорошо, я думаю, проблема решена. Ошибка возникает, когда буфер не полностью заполнен данными во времени (переполнение буфера). Я понятия не имею, что такое тайм-аут, но если вы испытываете это, убедитесь, что:
-
Вы не вызываете метод воспроизведения до тех пор, пока у вас не будет данных в буфере.
-
Вы можете генерировать данные достаточно быстро, чтобы побить таймаут.
-
После того, как вы закончите подачу буфера данными, прежде чем вы вызовете метод stop(), убедитесь, что "последний" буфер был полностью заполнен данными до истечения времени ожидания.
Я имел дело с последней проблемой, всегда ожидая немного (до таймаута), затем отправляя 1 буфер, полный нулей, и, наконец, вызывающий функцию stop().
Имейте в виду, что вы всегда должны отправлять буфер в более мелкие куски, даже если у вас есть большой кусок. Мне все еще немного надоедает, что я не уверен на 100%, если это правильный путь, но ошибки ушли, поэтому я думаю, что смогу жить с этим:)
Ответ 2
Я обнаружил, что даже когда буфер технически достаточно длинный и заполнен байтами, если они не были должным образом отформатированы (звуковые шорты, преобразованные в байтовый массив), он все равно выведет вам эту ошибку.
Ответ 3
Я получал это предупреждение, когда я создал экземпляр Audiotrack под названием audioTrack.play()
, и между вызовом play()
и audioTrack.write()
была небольшая задержка. Если я позвонил play()
прямо перед write()
, предупреждение исчезло.
Ответ 4
Я решил этим
if (mAudioTrack.getPlayState()!=AudioTrack.PLAYSTATE_PLAYING)
mAudioTrack.play();
mAudioTrack.write(b, 0, sz * 2);
mAudioTrack.stop();
mAudioTrack.flush();