Комментарии 21
Э-э-э, пардонь-те, но всё-таки спрошу: в вашем подходе вы какую задержку измеряете:
выводы звука на динамик?
ввода звука с микрофона?
расстояние от профессиональной камеры до мобильника?
или задержку передачи звука по некоторому каналу связи?
Проясню свои вопросы:
вывод звука на динамик даёт задержку примерно 10-30 мсек. Это обычные звуковые устройства для компьютера и обычный вывод без ухищрений, и сомнительно, что для мобильного устройства эта задержка будет сильно меньше. На всякий случай: задержка меряется так: берём двухлучевой осциллограф и один щуп подключаем к условному контакту gpio (что найдётся на компьютере), другой на контакт динамика и на экране смотрим задержку. Она НЕ маленькая и она ПЛАВАЕТ.
Ввод звука с микрофона - это всегда боль и это задержка обычно больше, чем на вывод. Легко может быть 30+ мсек. Измеряется на акустической петле: вывод звука и тут-же ввод (задержка вывода понятна (см. выше), всё что осталось - задержка ввода);
расстояние от ... ну тут всё просто: скорость звука в воздухе около 3 мсек на 1 метр. Отодвинули камеру на 70 см, получили задержку в 2 миллисекунды. Приблизили на 1 метр - задержка уменьшилась на 3 мсек;
задержка передачи: а вот здесь уже начинаются интересности: для систем голосовой связи с маленькими задержками используют либо синхронные линии с выделенными таймслотами (канал E1 и это стоит денег), либо используют специальные протоколы и маршрутизаторы (и всё это в пределах одной сети/здания). Если использовать обычные протоколы IP-телефонии, то там звуковой пакет набивается на 22 - 40 мсек (и задержка явно больше).
И самое плохое во всём этом, что задержка плавает: если ваш мобильник слегка чем-то занялся, то вы тут же получите скачок задержки (от 5 до 50 мсек, в зависимости от настроек ввода/вывода звука, как открываются устройства): звук выдаётся синхронно, и если его никто не готов брать (или выдавать), то тут же вставляется (или выводится) пустой буфер. И если вы хотите управлять задержкой, то это нужно обязательно отслеживать.
Другая проблема: частота оцифровки звука на разных устройствах не совпадает: ваша профессиональная камера/микрофон записывают звук на реальной частоте условно 48028 Гц, а на выходе работает звуковуха на частоте 47980 Гц (естественно, каждое из устройств считает, что оно работает на 48 кГц) и тогда звук начинает постепенно отставать. И через 1 час вы уже получите задержку в около 3,5 секунды (естественно, если ничего не будете предпринимать). С частотой оцифровки вы вряд ли что-то сможете сделать: она банально плывёт от температуры.
В общем, Ваша цель приблизиться к единицам миллисекунд очень амбициозна. Или вы используете спец-средства и спец-алгоритмы: тогда может разовьёте тему: это очень интересно почитать.
-
Ух, какой-то депрессивный пост получился.
Попробую закончить на позитиве: человеческое ухо задержки в акустике до 30 мсек мозгом компенсирует, вы их не обнаружите, поэтому может не нужно гоняться за 1 мсек?
В любом случае, если вы получили точность 16,6 мсек - это очень хороший результат.
Прим.: извиняюсь, за некоторую эмоциональность, у нас передача звука и задержки - это основная работа и больная мозоль. А у Вас очень хороший результат.
Прим: в основном говорю за звук, т.к. мы занимаемся только звуком; про видео - возможно тоже есть тонкости.
Автор только в начале пути, вы к нему слишком строги) Первое и главное - источник света и звука должен быть аппаратным, только так можно гарантировать отсутствие любых задержек. Для кодирования звука - DTMF или ЛЧМ, для видео - несколько светодиодиков бы хватило. Для анализа тоже можно обойтись самыми обычными резонансными фильтрами и без всякого FFT (правда математика там конечно сложнее).
Большое спасибо, что потратили время на такой объемный комментарий! Это, действительно, ценно для меня, - получить ответ от специалиста в этой области.
В задаче не стояло измерять задержку часами. Она измеряется несколько секунд, достаточно получить одну-две метки и будет понятен результат.
Вы, собственно, всё правильно рассказали, что я не смогла точно сформулировать о причинах задержек в онлайн версии, поэтому она и не работает пока (может и не заработает из-за всех перечиленный Вами трудностей). В другой версии - оффлайн, при записи видео определяется всё с той точностью, насколько возможно, меньше половины длины фрейма тут получить нереально. Телефон в этой версии не будет "отвлекать" процессор от записи видео, иначе бы у всех смартфонов криво работала запись видео. Эта версия приложения работает, протестировано ни один раз.
И опять же согласна, что исходя из исследований, люди способны воспринимать ошибки аудиовизуальной синхронизации (когда звук отстает от визуальной составляющей) в следующих диапазонах: перцептивное окно - около 100-200 миллисекунд. Все, что короче 100 мс, обычно воспринимается как синхронное. Вот, читала статью об этом: https://www.kom.tu-darmstadt.de/papers/Stei96_228.pdf Но тут было важно определить какую цифру ввести в оборудование при синхронизации трансляций.
Точность 1мс не амбициозна, а давно достигнута, не в такой комбинации телефон-телефон, конечно, а телефон-проф. оборудование-компьютер. И я смотрела видео про это в Центре прямых трансляций компании NEP Connect как раз используют этот подход с телефоном и метками. В демке они с точностью до 1 мс показывают результаты измерений: https://youtu.be/RfkSs-87LOM?si=-roGiDRrxkIbkApf Буквально отодвинули микрофон и задержка выросла на 2 мс, как Вы и говорите.
Еще раз спасибо!!!
Посмотрел на указанное Вами видео (про точность 1 мс), и стало понятнее про задачу (и про звук). И если Вы хотите сделать что-то подобное, могу добавить пару идей / проблем, вдруг будет полезно.
вывод звука с телефона: скорее всего при выводе звука используется счётчик выведенных сэмплов (на компьютере такая штука есть, она лёгкая и информативная, полагаю в мобильнике всё также): у звуковухи можно запросить номер сэмпла, который она вот прямо сейчас выводит. Далее определяется задержка между временем когда программа условно затолкала 100'000-ый сэмпл в звуковой драйвер/устройство и временем когда она его стала выводить. Задержка известна - ок. Хотя она и плавает, при определённых ухищрениях её можно держать в рамках и в самой программе звук генерировать раньше/позже, чтобы звук попадал на физический динамик в точно нужный момент. В общем, немного ухищрений, но это довольно легко;
а вот с вводом звука могут быть проблемы. Такого лёгкого счётчика как на вывод, может и не быть (мы не нашли :(, ). И тут есть варианты: - либо высасывать звук на максимальной скорости маленькими пакетиками. Тут рекомендуется изучить матчасть про мобильник, но на компьютере это работает плохо: даже если вы запрашиваете звук по 3 мсек, сама звуковуха может накопить с десяток пакетиков и выплюнуть их вам почти-единовременно (даже с использованием DirectSound) и вот уже окно в 30 мс. Либо ставить специальную звуковую карту, которая или даёт очень маленькую задержку на ввод, или ставит временные метки на звук (что со стандартным мобильным устройством это может быть проблематично :(, ). Например, у нас собственная звуковая карта (разработали свою); полагаю, у hitomi примерно так же: либо своё устройство, либо профессиональное + допиливание в аппаратуре и драйверах;
про видео: точность в 1 мс очень возможно они получают через старт показа изображения. По видео создаётся ощущение, что статичный кадр с qr-кодом стартует с некоторой сдвижкой (и ещё периодически изображение пропадает на короткое время). В принципе, если ловить сдвижку, когда кадр выводится наполовину, то можно получить отсечку времени точнее 1/5 - 1/6 кадра. Во всяком случае на ipad-е, когда программа выводит меняющиеся картинки, может вывестись в одном кадре верхнюю часть от старой картинки и нижнюю часть от новой картинки. Ловим момент совмещения старое/новое (возможно даже их пропорции) и получаем доли кадра в задержке. Также учитываем, что кадр выводится намного быстрее, чем потом показывается - и это отрабатывается выбором устройств: моделей iphone/ipad мало, они очень похожи, можно провести калибровку по времянке;
Если резюмировать:
В статье Вы указали, что достигли точности в полкадра. И тут главный вопрос, как синхронизировались видео и звук "в реале" (в эфире, в пространстве между мобильниками). Если эти полкадра уже с учётом задержки ввода звука (сомнения, да?), то тогда всё отлично.
В ином случае возможно потребуется плотно изучить вопрос ввода звука, это может сильно осложнить ваше решение.
Немного дополнений:
то, что на вашей программе задержка стоит ровно, не значит, что она правильная. Она может фиксировано быть завышена/занижена. Перезапускаете приложение - и числа могут быть другими. Если делаете много-много запусков/перезагрузок и задержка повторяется (даже через оффлайн обработку), то тогда есть простой путь - любым способом замеряем реальное положение дел и в программу вносим константу. Возможно, эту константу придётся позамерять для разных телефонов.
у звуковухи можно запросить номер сэмпла, который она вот прямо сейчас выводит
А не подскажите, как именно? Просто лично я не смог найти ответ на это вопрос ни у WASAPI, ни у ASIO.
В wave api есть функция waveOutGetPosition - получаем текущую позицию.
Примечание в тематику статьи:
Более того, для ввода тоже есть функция - waveInGetPosition.
Другое дело, что вычисленное значение задержки на ввод может сильно плавать (как говорится, бай дизайн) и ценность сего может быть сомнительной (то самое отсутствие "лёгкого" счётчика).
А так-то функции есть - пользуйтесь.
Так это позиция относительно чего? Мне её как привязать к конкретному семплу в ранее заполненном буфере? А без этого толку от этой функции - ноль, я и сам могу её прекрасно считать через текущее время и частоту дискретизации.
Честно говоря, не понял Ваше затруднение. Итак, по предложениям:
Позиция относительно нуля байтов (мы считаем в байтах). Условно:
вы открываете устройство на вывод, включаете play, данных не даёте. Запрашиваете позицию, получаете 0. Отлично;
начинаете кормить звуковуху данными. Запрашиваете позицию, получаете 0. Это потому, что звуковуха сразу один-десять-сто сэмплов выводить не будет, она будет копить данные;
через некоторое время позиция начинает прирастать. Это означает, что звуковуха поднакопила данных, прогнала их через ресемплер/эквалайзер/эффекты/громкость/чтотоещё и наконец решила это выплюнуть наружу.
Вот с момента прирастания позиции (см. п 1) вы можете её перевести в номер сэмпла в том порядке, как кормили звуковуху (в простейшем случае позицию в байтах разделить на размер отсчёта и количество каналов). Если у вас долгое воспроизведение (4-8-15+ часов), то лучше озаботиться пересчётом позиции, т.к. счётчик может переполниться (и тогда он заворачивается). Технически, можете поискать этот текущий сэмпл в буферах (и учтите на вывод всё идёт пережёванное и конвертированное).
Самое полезное предложение. ЕСЛИ расчёта через текущее время и частоту дискретизации Вам достаточно, то лучше этим и пользоваться. Однозначно лучше!
-
На всякий случай укажу, почему п.3 может не подойти:
воспроизведение начинается не сразу;
эквалайзеры/эффекты могут дать задержку;
если данных вдруг не будет, то звуковуха вставит пустой блок;
частота таймера/часов не соответствуют частоте в звуковой карте (возникает ощущение, что туда кварц вообще не завозят).
-
На всякий случай распишу типовую задачу, где эту позицию можно использовать. Вы пишете простенький шутер, в котором есть какие-то враги, которые топают и стреляют вокруг. И сам вы тоже при нажатии на кнопку стреляете. Поиграв 10-30 минут вы вдруг отмечаете, что звук выстрела слегка отстаёт от нажатия кнопки. Не на секунды конечно, но уже ощутимо. Посмотрев на использование звуковых буферов, вы видите, что их используется подозрительно большое количество. Они не утекают, память не растёт, но всё равно много. Вы решаете уменьшить количество буферов, оставляете два-три. Поиграв 1-2-3+ минуты вы начинаете слышать надоедливое потрескивание. Чтобы убрать потрескивание, Вы решаете два-три буфера довести до десяти-двадцати. Однако ничего не меняется, потрескивание остаётся и даже не становится реже. Вы понимаете, что сейчас есть два крайних варианта: либо большая задержка, либо звук начинает потрескивать. Но хочется третий вариант: маленькая задержка и без треска. За третьим вариантом Вы идёте на stackoverflow/habr/др и там вам советуют следить за позицией.
Итак, если Ваша задача совсем не похожа на приведённый выше шутер, то лучше следовать пункту 3. Ну а если пункт 3 не подходит, то ...
Добро пожаловать!
При проведении прямых трансляций звук часто опережает изображение
Где такое происходит? Да ещё и часто?
Везде), Вы этого не видите, как зритель, потому что за этим стоит работа целой команды.
Какой команды, где? Когда в сеть вещают цифровую телепередачу, отправляется поток, в котором есть специальные данные, помогающие синхронизовать видео со звуком. Откуда берется рассинхрон? А если, как Вы пишете, никто этого не видит, то с чем боретесь?
Этот поток надо сначала сделать. Я не прямо большой специалист, но сталкивался с прямым вещанием, а там все сложно: видео идёт одним путем (скажем, через видеомикшер с пультом у режиссёра), аудио отдельно другим (через аудиомикшер тоже с пультом у режиссёра), потом после раздельной обработки и микширования они должны слепиться вместе, и вот тут-то практически всегда оказывается что звук скажем спешит, а видео опаздывает. Чтобы с этим бороться, в микшерах есть настройки задержки, их можно выставить, но на какое конкретно значение? Чтобы знать значение, его нужно сначала корректно измерить.
То, что Вы описываете, больше похоже на кривые руки, а не проблемы передачи данных. Синхронность видео и звука надо обеспечивать до того, как передавать их в сеть.
Чтобы знать значение, его нужно сначала корректно измерить.
Можно захватить кусок видео со звуком с выхода, вставить в любую видеомонтажку и там увидеть, какая разбежка видео и звука.
Синхронность видео и звука надо обеспечивать до того, как передавать их в сеть.
В какую сеть? Ещё нет никакой сети, есть раздельные аудиоканалы с микрофонов, и видеоканалы с камер, видео надо смикшировать (всякие там картинки в картинке), аудио надо смикшировать, потом это все объединить, и уже потом что-то можно передавать в сеть. А вы видимо думаете, что булки сразу на деревьях должны расти, так вот, это не так.
В профессиональных применениях сигналы синхронизуют с помощью опорного сигнала genlock.
Я опять же не большой специалист, так, мимокрокодил, но ЕМНИП генлок - это про синхронизацию нескольких видео, а не видео и аудио.
А звук в камере синхронизуется к видео. Поэтому, если видео между несколькими камерами генлокировано, то и звук между ними синхронный.
Сложнее, если надо сторонний звук подмешать. Но если это делается правильным устройством - например, эмбеддером, то звук также будет синхронен с видео.
Но вообще, конечно, проблема синхронизации и вправду не всегда легко решается.
В профессиональных трансляциях несколько камер, между ними идёт переключение и микширование, чтобы показывать видео с разных ракурсов, звук они не записывают вообще. Звук приходит отдельно с одного или нескольких микрофонов. Это все нужно синхронизировать, так как звук как правило оцифровывается и обрабатывается быстрее, поэтому задержка у него меньше и видео как правило всегда запаздывает.
Я узнал вас по аве x) я помню видосы про то, как делать резюме
Синхронизация звука и видео. Взгляд дилетанта