записывать аудио с точными временными метками

Я хочу записать необработанный звук на устройство Android Wear и точно синхронизировать его с данными других датчиков, такими как акселерометр. Для записи необработанного звука я использую AudioRecord, но как определить правильный метка времени для любой части аудиопотока?

Основная проблема заключается в том, что я получаю необработанные аудиокадры из буфера без информации о том, как долго эти кадры находились в буфере, сколько кадров было потеряно и т. д.

Итак, чтобы получить данные кадра, я вызываю AudioRecord.read() в цикле, но как узнать, когда был записан конкретный кадр?

Я вижу три способа определения метки времени, и все они кажутся мне неправильными:

  1. Получите текущее системное время до или после вызова AudioRecord.startRecording() с помощью вызывая SystemClock.elapsedRealtimeNanos(), а затем вычисляя время каждого фрагмента на основе от частоты дискретизации и размера кадра. Но по моим тестам есть значительная задержка, пока собственно запись не начнется. Время также будет рассинхронизировано всякий раз, когда некоторые кадры теряются, например. когда обработка останавливается на мгновение.

  2. Получить текущее системное время до или после AudioRecord.read(). Но это, вероятно, не то время, когда эти данные были записаны, это могло произойти немного раньше. И если данные еще не доступны, read() заблокируется, и отметка времени, полученная ранее, будет совершенно неправильной.

  3. 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()

Какой из них будет наиболее точным способом определения временной метки, соответствующей данным в массиве байтов?

Есть ли другой метод получения необработанных аудиоданных с точными временными метками?


person HugoRune    schedule 17.08.2020    source источник
comment
возможно, вам поможет это репозиторий Google (проверьте класс AudioTimestampPoller)   -  person G. Ciardini    schedule 03.09.2020
comment
Если я интерпретирую AudioTimeStampPoller правильно, он работает над некоторыми более сложными характеристиками поведения getTimestamp(), но я до сих пор не совсем понимаю, как соотнести эту метку времени с кадрами, из которых возвращает текущий вызов read() буфер, а не кадры, которые в данный момент записываются. Поэтому я не совсем понимаю, как оно может быть более точным или даже отличаться от текущего системного времени.   -  person HugoRune    schedule 06.09.2020
comment
мыслить нестандартно - неужели вы просто создаете высокочастотный всплеск или всплеск на динамике, который может быть записан вместе с другим звуком и использован для последующей синхронизации кадров, как PLL?   -  person bitranox    schedule 06.09.2020
comment
это может сработать, но тогда мне нужно будет получить точные временные метки для вывода звука с неизвестной задержкой между постановкой звука в очередь и реальным динамиком, не уверен, что это проще. другой вариант, конечно, ударить по часам, которые создадут коррелированные аудиосигналы и сигналы акселерометра, но я действительно надеялся на более элегантное решение.   -  person HugoRune    schedule 06.09.2020
comment
@HugoRune вам удалось найти приемлемое решение? Сейчас я работаю над похожей идеей и хотел бы знать, нашли ли вы что-то 7 месяцев спустя.   -  person topher217    schedule 24.03.2021


Ответы (1)


Вам нужно создать коррелированный звук и сигнал акселерометра. Вы также можете добавить в микс фонарик, камеру, динамик и т. Д.

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

person bitranox    schedule 06.09.2020