Содержание статьи +
- Кратко
- Почему это важно
- Проблема: почему комната создаёт эхо
- Главная идея: подавление через вычитание
- Сложная часть: комнату вам никто не выдаёт
- Адаптивный фильтр: угадать, проверить, поправить
- Как измерить успех: ERLE
- Когда вычитания мало: подавитель остатка
- Проблема двойного разговора: режим отказа, который вы реально будете ловить
- Как это делает WebRTC: AEC3 простым языком
- Сравнение, которым можно пользоваться: что меняет сложность
- Где AEC стоит относительно соседей
- Где здесь Фора Софт
- Главное
- Что почитать дальше
Кратко
Акустическое эхо возникает, когда звук из вашего динамика снова попадает в ваш же микрофон и уходит обратно собеседнику, и тот слышит собственный голос с задержкой на круговой путь. Акустическое эхоподавление, по-английски AEC, решает это так: оно берёт сигнал, который устройство собирается воспроизвести, – опорный сигнал, – предсказывает, как комната его исказит, и вычитает это предсказание из микрофона, в идеале оставляя только ваш голос. Предсказание строит адаптивный фильтр, который угадывает, сверяется с реальностью и поправляет себя тысячи раз в секунду, при поддержке детектора двойного разговора, замораживающего фильтр, когда говорят оба, и подавителя остатка, убирающего то, что просочилось. Эта статья объясняет каждую из этих частей простым языком, называет реальный компонент в WebRTC (AEC3) и показывает режимы отказа – двойной разговор, изменение комнаты и задержку Bluetooth, – с которыми вы реально столкнётесь в продакшене.
Почему это важно
Если вы строите платформу для телемедицины, инструмент видеоконференций, контакт-центр, онлайн-класс или любой продукт, где двое говорят через интернет, эхо – тот дефект, который пользователи замечают первым и прощают меньше всего. Замёрзший кадр видео раздражает; услышать собственный голос, отскакивающий назад через полсекунды, делает разговор физически невозможным. Эта статья для менеджера продукта, основателя или операционного руководителя, которому нужно понять эхоподавление достаточно хорошо, чтобы читать баг-репорт, задать инженеру правильный вопрос и выставить клиенту реалистичные ожидания. Опытный инженер тоже найдёт каждое утверждение со ссылкой на соответствующую Рекомендацию ITU-T или исходный код WebRTC. К концу вы сможете объяснить коллеге, почему возникает эхо, как подавитель его убирает и почему оно иногда возвращается ровно на секунду после того, как кто-то подвинул ноутбук.
Проблема: почему комната создаёт эхо
Начнём с физической ситуации, потому что всё решение следует из неё. Вы на звонке. Собеседник – дальняя сторона – говорит. Его голос приходит к вашему устройству как сигнал, устройство воспроизводит его через динамик, и он наполняет вашу комнату. Это нормально и необходимо: вам нужно его слышать.
Вот в чём беда. Ваш микрофон находится в той же комнате, что и динамик. Он не может отличить звук, который должен захватывать – ваш голос, – от звука, который не должен, – голоса дальней стороны, переигрываемого из вашего динамика. Поэтому микрофон ловит и то, и другое, смешивает в один сигнал и отправляет всё обратно. Дальняя сторона теперь слышит копию собственного голоса с задержкой. Эта задержанная копия и есть акустическое эхо.
Невыносимым его делает именно задержка. Если бы эхо возвращалось мгновенно, мозг счёл бы его естественным отражением, какое слышно в любой комнате, и проигнорировал. Но круговой путь по интернету добавляет время. К моменту, когда дальняя сторона слышит своё эхо, оно отстаёт от её исходной речи на заметный промежуток, и мозг уже не может слить эти два звука в один. Чем больше промежуток, тем хуже.
Это не новое наблюдение. Телефонная сеть борется с эхом уже век, и международный стандарт, который его измеряет, – Рекомендация ITU-T G.131 (Talker echo and its control, 11/2003) – прямо показывает зависимость от задержки: количество эха, которое слушатель стерпит, падает с ростом односторонней задержки. G.131 выражает терпимое эхо через «talker echo loudness rating» как функцию средней односторонней задержки, и практический вывод прост – после примерно 25–30 мс односторонней задержки уже нельзя обойтись ручным ослаблением эха; нужно отдельное устройство, которое его удаляет. Это устройство – эхоподавитель.
«Эхо бывает двух видов, и их путают. Линейное эхо (или сетевое) возникает из-за электрических отражений внутри старого телефонного оборудования, в точке, где четырёхпроводная цепь встречается с двухпроводной. Акустическое эхо возникает из-за пути «динамик → микрофон» в комнате. Эта статья – про акустическое эхо, которое доминирует в современных голосовых и видеоприложениях. Стандарт для линейного вида – ITU-T G.168; стандарт для акустического был ITU-T G.167, позже включённый в стандарт hands-free-терминалов ITU-T P.340.»
Главная идея: подавление через вычитание
Чистая идея, лежащая в основе любого эхоподавителя, – что устройство уже знает то единственное, что ему нужно. Оно точно знает, что собирается воспроизвести через динамик, потому что само сгенерировало этот звук. Этот известный сигнал – голос дальней стороны по пути к вашему динамику – называется опорным сигналом, или иногда сигналом дальней стороны (reference signal, far-end signal).
Эхоподавитель – это, в одном предложении, шумоподавляющие наушники для комнаты. Шумоподавляющие наушники слушают внешний мир и проигрывают его противоположность, так что они взаимно гасятся. Эхоподавитель слушает опорный сигнал – звук, который он подаёт на динамик, – предсказывает, какая версия этого звука вернётся в микрофон после блужданий по комнате, и вычитает предсказание из сигнала микрофона. Если предсказание хорошее, остаётся только ваш голос.
Итак, подавитель сидит в точке, где встречаются два сигнала:
- Сигнал микрофона: ваш голос плюс эхо дальней стороны плюс шум комнаты.
- Опорный сигнал: голос дальней стороны ровно в том виде, в каком он подан на динамик.
Задача подавителя – выяснить, как опорный сигнал превращается в эхо, построить копию этого эха и вычесть её. То, что остаётся после вычитания, называется сигналом ошибки – и, что сбивает с толку, именно этот сигнал ошибки и есть полезный выход. Его отправляют дальней стороне. «Ошибка» здесь означает «то, что осталось после удаления предсказуемой части», и в идеале единственное, что мы не смогли предсказать, – это ваш реальный голос.
Сложная часть: комнату вам никто не выдаёт
Если бы подавитель точно знал, как комната превращает опорный сигнал в эхо, задача была бы тривиальной: предсказать, вычесть, готово. Но он не знает. Каждая комната разная, каждый ноутбук разный, и путь меняется в тот момент, когда что-то сдвигается. Поэтому подавителю приходится выучивать комнату по ходу звонка и переучивать её, как только меняются условия.
То, что он выучивает, называется путём эха (echo path) – полное путешествие от опорного сигнала через буфер воспроизведения и цифро-аналоговый преобразователь, наружу через динамик, по воздуху, от стен, стола и кофейной кружки, обратно в микрофон и его аналого-цифровой преобразователь. Инженеры описывают этот путь как импульсную характеристику: если бы вы проиграли через динамик один бесконечно короткий щелчок, импульсная характеристика – это точная картина того щелчка и всех его отражений, приходящих обратно в микрофон в течение следующих десятков миллисекунд.
Типичный путь эха в комнате длинный. Звук распространяется примерно 343 метра в секунду, поэтому отражение от стены в трёх метрах и обратно приходит примерно через 17 мс. При частоте 48 000 отсчётов в секунду – той, что используют WebRTC и большинство голосовых систем, – 17 мс это около 800 отсчётов. Реальные комнаты дают отражения на 100, 200 и даже 400 мс в гулком помещении. Чтобы это смоделировать, подавителю нужен фильтр с сотнями или тысячами «отводов» (taps) – по одному весу на каждый отсчёт задержки, который он хочет учесть.
Пройдём арифметику один раз вслух, потому что она объясняет, почему эхоподавление вычислительно дорого:
длина фильтра (в отсчётах) = длительность пути эха (с) × частота дискретизации (отсчётов/с)
= 0,128 с × 48 000 отсчётов/с
= 6 144 отсчёта (отвода)Путь эха длиной 128 мс на 48 kHz требует примерно 6 000 отводов фильтра, и подавитель должен обновлять эти тысячи чисел непрерывно, для каждого блока звука, в реальном времени. Это и есть инженерный вызов под простой картинкой «предсказать и вычесть».
Адаптивный фильтр: угадать, проверить, поправить
Фильтр, моделирующий путь эха, – адаптивный, то есть он сам подстраивает свои веса. Ему не нужно знать комнату заранее. Он начинает с пустой догадки, играет в предсказание, смотрит, насколько ошибся, чуть-чуть подправляет веса, чтобы ошибиться меньше, и повторяет – тысячи раз в секунду. Этот цикл «угадать – проверить – поправить» и есть бьющееся сердце любого эхоподавителя.
Стандартный рецепт шага коррекции – алгоритм под названием Normalized Least Mean Squares, сокращённо NLMS (нормализованный метод наименьших средних квадратов). Имя описывает, что он делает. «Least mean squares» означает, что он пытается сделать среднюю квадратичную ошибку как можно меньше – большую ошибку он считает гораздо хуже маленькой, поэтому усерднее всего работает над самым громким остатком эха. «Normalized» означает, что он масштабирует каждую коррекцию по текущей громкости опорного сигнала, так что и крик, и шёпот дают поправки разумного размера, а не крик швыряет фильтр из стороны в сторону. NLMS – рабочая лошадка, потому что он устойчив, достаточно дёшев для реального времени и хорош для речи. Обзорная литература по эхоподавлению стабильно называет NLMS основным адаптивным алгоритмом в этой области.
Скорость обучения фильтра задаётся одной ручкой – размером шага (step size). Большой шаг значит, что фильтр учится быстро, но дрожит вокруг правильного ответа; малый шаг – учится медленно, но устаканивается точно. Это центральный компромисс адаптации, и поэтому современные подавители используют переменный размер шага: большой, когда комната только что изменилась и фильтр далёк от истины, малый – когда он сошёлся и нужны лишь тонкие поправки. Момент от «фильтр пуст» до «фильтр совпал с комнатой» называется сходимостью (convergence), и хороший подавитель сходится за доли секунды.
Есть ещё одно уточнение, важное для понимания реальных систем. Считать всё по одному отсчёту во временной области медленно. Реальные подавители переводят блоки звука в частотную область – с помощью быстрого преобразования Фурье, которое раскладывает звук на составляющие его частоты, – потому что фильтрация там намного дешевле. Чтобы держать задержку низкой и всё ещё моделировать длинный путь эха, они разрезают длинный фильтр на несколько коротких кусков, каждый из которых отвечает за свой срез задержки, и обрабатывают их перекрывающимися блоками. Эта структура – партиционированный блочный адаптивный фильтр в частотной области (PBFDAF), а основополагающая конструкция – многозадержечный блочный частотный адаптивный фильтр, описанный Soo и Pang (IEEE Transactions on Acoustics, Speech, and Signal Processing, 1990). Математика вам не нужна; нужно знать, что «блочная обработка в частотной области» – это причина, по которой подавитель может моделировать комнату на 200 мс, не добавляя 200 мс задержки к вашему звонку.
Как измерить успех: ERLE
Откуда вы знаете, что подавитель работает? Измеряете, насколько тише стало эхо. Стандартная метрика – Echo Return Loss Enhancement, сокращённо ERLE, и это просто снижение уровня эха в децибелах, которое подавитель добавляет поверх естественного ослабления, уже даваемого комнатой.
Рабочий пример делает это наглядным. Допустим, голос дальней стороны приходит к вашему микрофону как эхо на уровне, который мы для отсчёта назовём 0 дБ. Подавитель вычитает своё предсказание, и оставшееся эхо измеряется в −40 дБ – то есть в десять тысяч раз слабее по мощности. ERLE – это разница:
ERLE = уровень эха до подавления − уровень эха после подавления
= 0 дБ − (−40 дБ)
= 40 дБХорошо настроенный современный акустический эхоподавитель достигает примерно 35–45 дБ ERLE в устойчивых условиях одиночного разговора. Этого достаточно, чтобы опустить остаток эха ниже уровня обычного шума комнаты, где мозг перестаёт его замечать. Международная методика тестирования производительности эхоподавителей, ITU-T G.168, построена вокруг таких метрик; она написана для линейных эхоподавителей, но её философия измерения – прогнать подавитель заданными сигналами и проверить, что эхо подавлено на целевую величину, – это шаблон, которым пользуется вся отрасль.
Когда вычитания мало: подавитель остатка
Вот неудобная правда: один адаптивный фильтр почти никогда не убирает всё эхо. Реальные динамики немного искажают звук – добавляют нелинейные эффекты, которые ни один линейный фильтр предсказать не может, потому что линейный фильтр умеет моделировать только «эхо – это некая задержанная, масштабированная копия опорного сигнала». Дешёвые динамики ноутбуков, громко работающие динамики телефонов и особенно Bluetooth-динамики вносят искажения, которые фильтр повторить не способен. То, что переживает вычитание, называется остаточным эхом (residual echo).
Поэтому у каждого серьёзного подавителя есть вторая ступень: подавитель остаточного эха, иногда выполненный как нелинейный процессор (NLP). Там, где адаптивный фильтр вычитает, подавитель ослабляет – он приглушает громкость в те моменты и в тех частотных полосах, где он считает, что присутствует остаточное эхо, а вашего голоса нет. Думайте об адаптивном фильтре как о хирурге, удаляющем основную массу опухоли, а о подавителе – как о последующей терапии, зачищающей края. ITU-T G.168 прямо требует ступень нелинейной обработки в соответствующем эхоподавителе именно потому, что одно вычитание оставляет слышимый остаток.
Подавитель – это ещё и место, где подавители могут навредить. Если он ослабляет слишком агрессивно, он срезает начало ваших слов или делает голос «булькающим, как под водой». Настройка подавителя – это баланс между «не пропустить эхо» и «пропустить весь голос ближней стороны», а эти две цели тянут в противоположные стороны.
Проблема двойного разговора: режим отказа, который вы реально будете ловить
Теперь самое важное, что нужно понять про эхоподавление, потому что это симптом, на который инженеры тратят больше всего времени. Всё описанное выше прекрасно работает, когда говорит только один человек за раз. Сложный случай – двойной разговор (double-talk): оба говорят одновременно.
Вспомните, как учится фильтр: он сравнивает своё предсказание с сигналом микрофона и двигает веса в сторону того, что уменьшает ошибку. При одиночном разговоре микрофон содержит только эхо, поэтому «уменьшить ошибку» значит «лучше смоделировать эхо», что ровно правильно. Но при двойном разговоре микрофон содержит эхо плюс ваш голос. Если фильтр продолжает адаптироваться, он примет ваш голос за ошибку предсказания и начнёт корёжить веса, пытаясь подавить вас. Результат испорчен: фильтр расходится, эхо просачивается обратно, и в следующий раз, когда заговорит только дальняя сторона, эхо внезапно станет громким, потому что фильтр обучился на мусоре.
Решение – детектор двойного разговора, сокращённо DTD (double-talk detector). Его единственная задача – заметить, что говорят оба, и сказать фильтру заморозиться: прекратить адаптацию, держать веса неподвижными, переждать двойной разговор на той модели комнаты, что уже есть, и возобновить обучение только тогда, когда ближняя сторона замолчит. Подавитель всё ещё вычитает во время двойного разговора; он просто перестаёт обновлять своё предсказание.
Обнаружить двойной разговор сложнее, чем кажется, и история области – во многом история всё лучших детекторов. Классический метод – алгоритм Гайгеля (Geigel), который просто сравнивает уровень микрофона с недавним уровнем опорного сигнала: если микрофон внезапно громче, чем может объяснить эхо, значит, кто-то рядом говорит. Он дёшев, но груб – исследования показывают, что он пропускает двойной разговор, когда голос ближней стороны не намного громче эха, и его обманывает фоновый шум. Современные детекторы используют нормализованную взаимную корреляцию (normalized cross-correlation) между опорным сигналом и сигналом ошибки, которая гораздо меньше зависит от точной силы пути эха и ловит двойной разговор, который метод Гайгеля пропускает.
«Ловушка, простыми словами. Когда клиент говорит «оно срезает начало моих слов всякий раз, когда собеседник тоже говорит», – это проблема детектора двойного разговора, а не сети. Детектор либо заморозился слишком поздно (эхо просочилось), либо подавитель зажал голос ближней стороны (ваши слова срезало). Это жалоба №1 на эхо в продакшене, и поэтому каждый голосовой продукт надо тестировать с обоими собеседниками, намеренно говорящими наперебой, а не вежливой очередью.»
Как это делает WebRTC: AEC3 простым языком
Большинство браузерных и многие нативные голосовые приложения работают на одном и том же открытом коде – libwebrtc, – и его эхоподавитель называется AEC3 (третье поколение). Если вы заходили в видеозвонок в Chrome, Edge или мобильном приложении на WebRTC, ваш микрофон чистил AEC3. Стоит увидеть, как описанные выше части ложатся на реальную, работающую систему, потому что эти имена повторяются в баг-репорте каждого инженера.
AEC3 живёт внутри Audio Processing Module (APM) – ступени очистки на стороне захвата, которая также содержит шумоподавление и контроль усиления. Весь конвейер мы проходим в Аудиоконвейер WebRTC целиком; здесь приближаемся к блоку эха. Исходный код WebRTC описывает класс верхнего уровня AEC3 как делающий четыре вещи: он принимает 10-миллисекундные кадры разнесённого по полосам звука, опционально применяет анти-гудящий высокочастотный фильтр, запускает низкоуровневое эхоподавление на блоках по 64 отсчёта и частично обрабатывает джиттер тайминга между тем, когда звук воспроизводится, и когда захватывается. Последний пункт важнее, чем кажется.
Сначала идёт оценка задержки. Прежде чем фильтр сможет что-то вычесть, AEC3 должен выровнять опорный сигнал и эхо во времени – должен знать, насколько поздно эхо приходит относительно того, когда был воспроизведён опорный сигнал. Эта задержка не фиксирована: она включает буфер воспроизведения, цифро-аналоговый преобразователь, воздушный путь «динамик → микрофон», аналого-цифровой преобразователь и буфер захвата, и на телефонах может колебаться примерно от 20 до 200 мс. AEC3 непрерывно оценивает эту задержку, кросс-коррелируя опорный и захваченный сигналы – сдвигая один относительно другого, чтобы найти задержку, при которой они лучше всего совпадают, – и передаёт это выравнивание фильтру. Ошибитесь с задержкой – и фильтр пытается подавить эхо относительно неправильного среза опорного сигнала; ничего не работает. Вот почему внезапная смена аудиомаршрута (вставили наушники посреди звонка) может вызвать полсекунды эха, пока оценщик задержки переcхватывается.
Затем линейный адаптивный фильтр моделирует путь эха и вычитает свою оценку – ровно как описано выше, используя блочную обработку в частотной области ради скорости.
Затем подавитель остаточного эха ослабляет то, что фильтр убрать не смог, – нелинейные искажения от дешёвых или громких динамиков, – используя модель того, насколько он уверен в присутствии остаточного эха в каждой частотной полосе в каждый момент.
Всё это время логика, осведомлённая о двойном разговоре, решает, когда безопасно адаптировать фильтр и насколько сильно зажимать подавитель, чтобы речь ближней стороны выжила.
AEC3 также предоставляет крючок под названием статус утечки эха (echo leakage status): если какой-то другой детектор замечает просачивающееся эхо, он может пометить подавитель, чтобы тот среагировал. Архитектура модульна намеренно – контроль задержки, фильтр и подавитель это отдельные части, которые можно настраивать независимо, что вы и будете делать на сложном устройстве.
Сравнение, которым можно пользоваться: что меняет сложность
Не все проблемы эха равны. Таблица ниже резюмирует, почему одни сценарии лёгкие, а другие – кошмар; полезно при оценке того, какие устройства должен поддерживать ваш продукт.
| Ситуация | Путь эха | Сложность для подавителя | Что вы заметите |
|---|---|---|---|
| Гарнитура / наушники (проводные) | Динамик запечатан у уха; пути к микрофону почти нет | Тривиально – гасить почти нечего | Чистый звук; AEC почти нечего делать |
| Ноутбук, умеренная громкость | Короткий стабильный воздушный путь; немного искажений | Легко – фильтр быстро сходится и держится | Хорошо после доли секунды |
| Ноутбук, высокая громкость | Громче эхо, больше искажений динамика | Умеренно – больше остатка для подавителя | Иногда утечка на громких местах |
| Громкая связь в открытой комнате | Длинный гулкий путь; много отражений | Сложно – длинный фильтр, медленная сходимость | Эхо при движении; срез при двойном разговоре |
| Bluetooth-динамик или гарнитура | Длинная переменная задержка петли; искажение кодека | Сложнее всего – оценка задержки всё время плывёт | Прерывистое эхо; детектор борется |
Закономерность ясна: жизнь подавителя тяжелеет по мере того, как путь эха становится длиннее, громче, искажённее и переменнее по задержке. Bluetooth худший сразу по всем осям, и поэтому практический совет в реальных продуктах прям: побуждайте к наушникам, но проектируйте на день, когда пользователь их забудет. Подробно случай Bluetooth и AirPods мы разбираем в Эхоподавление на громкой связи, Bluetooth и AirPods.
Где AEC стоит относительно соседей
Эхоподавление не работает в одиночку. В цепочке захвата WebRTC оно идёт в фиксированном порядке с двумя «соседями», и порядок не случаен. Высокочастотный фильтр сначала выметает низкочастотный гул, чтобы подавитель рассуждал о более чистом сигнале. Затем AEC убирает эхо. Затем шумоподавление поднимает ваш голос из фонового звука – и оно должно идти после AEC, потому что попытка подавить шум, пока эхо ещё присутствует, сбивает оценку шума. Наконец автоматический контроль усиления приводит ваш голос к стабильному уровню.
У каждого соседа есть свой подробный разбор: Автоматический контроль усиления (AGC): стабильный уровень голоса и Шумоподавление: классическое NS, RNNoise, Krisp, NVIDIA RTX Voice. Кодек, который несёт очищенный голос дальше, разбирается в Opus: открытый кодек, съевший WebRTC. Вся цепочка существует, чтобы бороться с тремя врагами живого звонка – эхом, шумом и ненадёжной сетью, – и AEC владеет первым. Когда эхо и потеря пакетов смешиваются, симптомы сливаются; порядок диагностики разобран в Диагностика проблем со звуком в продакшене: ранбук.
Где здесь Фора Софт
Мы встраиваем звук реального времени в видеоконференции, телемедицину, онлайн-обучение и лайв-шопинг с 2005 года, и эхо – первое, что каждый из этих продуктов обязан сделать правильно. Особенно в телемедицине: врач на громкой связи в кабинете и пациент на ноутбуке – это ровно тот сценарий «двойной разговор плюс длинный путь», который ломает наивные настройки, и чистота звука здесь это разница между пригодной консультацией и раздражённым повторным звонком. Наша работа – в основном выбор правильного стека, разумная настройка WebRTC Audio Processing Module под класс устройства, намеренное тестирование при двойном разговоре и Bluetooth и понимание, когда проблема в подавителе, а когда в сети. Мы не переписываем AEC3; мы заставляем его вести себя прилично на тех неидеальных устройствах, что реально есть у ваших пользователей.
Главное
- Акустическое эхо – это звук вашего динамика, снова попавший в микрофон и вернувшийся дальней стороне с задержкой.
- AEC вычитает предсказанное эхо, построенное из опорного сигнала, оставляя только голос ближней стороны.
- Адаптивный фильтр (обычно NLMS) выучивает комнату по циклу «угадать – проверить – поправить» тысячи раз в секунду.
- Детектор двойного разговора должен заморозить фильтр, когда говорят оба, иначе он испортит модель комнаты.
- Подавитель остатка убирает эхо, которое фильтр не смог вычесть; перенастройка срезает ваши слова.
- AEC3 в WebRTC сначала добавляет оценку задержки; плывущая задержка Bluetooth – самый сложный реальный случай.