Я хочу записать необработанный звук на устройство Android Wear и точно синхронизировать его с данными других датчиков, такими как акселерометр. Для записи необработанного звука я использую AudioRecord
, но как определить правильный метка времени для любой части аудиопотока?
Основная проблема заключается в том, что я получаю необработанные аудиокадры из буфера без информации о том, как долго эти кадры находились в буфере, сколько кадров было потеряно и т. д.
Итак, чтобы получить данные кадра, я вызываю AudioRecord.read()
в цикле, но как узнать, когда был записан конкретный кадр?
Я вижу три способа определения метки времени, и все они кажутся мне неправильными:
Получите текущее системное время до или после вызова
AudioRecord.startRecording()
с помощью вызываяSystemClock.elapsedRealtimeNanos()
, а затем вычисляя время каждого фрагмента на основе от частоты дискретизации и размера кадра. Но по моим тестам есть значительная задержка, пока собственно запись не начнется. Время также будет рассинхронизировано всякий раз, когда некоторые кадры теряются, например. когда обработка останавливается на мгновение.Получить текущее системное время до или после
AudioRecord.read()
. Но это, вероятно, не то время, когда эти данные были записаны, это могло произойти немного раньше. И если данные еще не доступны, read() заблокируется, и отметка времени, полученная ранее, будет совершенно неправильной.AudioRecord.getTimestamp()
указывает время кадра, который записывается в данный момент. Но это не обязательно тот кадр, который я сейчас читаю, я мог отставать на пару кадров или мог пропустить несколько кадров. И по первоначальным тестам какое-то время после старта временная метка просто нулевая.
Это оставило бы меня с 6, вероятно, неправильными временными метками, показанными в коде ниже. Кто-нибудь из них хотя бы близок к точности?
recorder = new AudioRecord(...)
// timeBeforeStart = SystemClock.elapsedRealtimeNanos()
recorder.startRecording()
// timeAfterStart = SystemClock.elapsedRealtimeNanos()
...
// timeBeforeRead = SystemClock.elapsedRealtimeNanos()
// recorder.getTimestamp(frameTimeBeforeRead, AudioTimestamp.TIMEBASE_BOOTTIME)
recorder.read(myArray, 0, mySize);
// recorder.getTimestamp(frameTimeAfterRead, AudioTimestamp.TIMEBASE_BOOTTIME)
// timeAfterRead = SystemClock.elapsedRealtimeNanos()
Какой из них будет наиболее точным способом определения временной метки, соответствующей данным в массиве байтов?
Есть ли другой метод получения необработанных аудиоданных с точными временными метками?