Содержание статьи +
- Кратко
- Почему это важно
- Проблема: микрофон, который не умолкает
- Как детектор речевой активности принимает решение
- Две ошибки, которые может совершить любой VAD
- Прерывистая передача: действие по решению
- Как это делает Opus – и одна ловушка
- Частая ошибка: включить DTX не для того звонка
- У VAD есть вторая карьера: он не только про экономию трафика
- Где здесь Фора Софт
- Главное
- Что почитать дальше
Кратко
Детектор речевой активности, по-английски VAD, – это небольшой модуль голосовой системы, который много раз в секунду решает, слышит ли микрофон речь или только фоновый шум. Прерывистая передача, по-английски DTX, – это то, что система делает с этим решением: когда никто не говорит, она перестаёт отправлять полные аудиопакеты и шлёт вместо них крошечный «описатель тишины», сокращая трафик неактивного микрофона примерно на 90 процентов. Чтобы тишина не звучала как обрыв связи, приёмник проигрывает тихий подобранный шум – комфортный шум. Эта статья объясняет, как VAD принимает решение, как DTX и комфортный шум превращают это решение в реальную экономию, и разбирает два режима отказа – обрезанные первые слоги и рваная речь, – которые подарит вашим пользователям небрежная настройка.
Почему это важно
Если вы делаете видеоконференции, телемедицину, контакт-центр или онлайн-обучение, большинство участников молчат бо́льшую часть времени – они слушают, а не говорят. Постоянный поток аудиопакетов от каждого молчащего микрофона тратит трафик и ёмкость серверов, а в большом звонке именно это решает, выдержит ли система 500 человек или развалится на 50. Эта статья – для продакт-менеджера, основателя или операционного руководителя, которому нужно понять компромисс достаточно, чтобы принять решение и задать инженеру точный вопрос, а не писать детектор самому. Старший инженер тоже найдёт здесь каждое утверждение со ссылкой на исходный RFC, Рекомендацию ITU-T или реализацию мейнтейнера.
Проблема: микрофон, который не умолкает
Начнём с того, что́ на самом деле идёт по сети во время звонка. Микрофон захватывает звук непрерывно, кодер режет его на маленькие куски – обычно по 20 миллисекунд звука каждый, такой кусок называют фрейм – система оборачивает каждый фрейм в пакет и отправляет. Двадцать миллисекунд на фрейм означают пятьдесят фреймов в секунду, пятьдесят пакетов в секунду, пока открыт звонок.
Вот в чём подвох: в обычном разговоре двоих каждый говорит реально меньше половины времени. На встрече из десяти человек один участник может говорить две минуты из часа. Всё остальное время его микрофон шлёт пакеты, в которых нет ничего, кроме гула его комнаты – вентилятора, кондиционера, тихого шипения офиса. Каждый такой пакет стоит трафика на стороне отправителя, трафика на стороне приёмника и времени обработки на сервере посередине. Умножьте это на каждого молчащего участника в каждом звонке – и потери становятся огромными.
Решение состоит из двух половин, которые всегда идут вместе. Первая половина – это решение: этот фрейм – речь или тишина? За это решение отвечает детектор речевой активности, который дальше мы будем называть VAD – модуль, который слушает каждый фрейм и помечает его «речь» или «не речь». Вторая половина – это действие: раз этот фрейм – тишина, перестать слать полные пакеты. Это действие – прерывистая передача, дальше DTX – буквально передача, которой разрешено останавливаться и возобновляться, а не идти непрерывно. VAD решает; DTX действует на основе решения. Без VAD, который его кормит, полезного DTX не бывает – поэтому эти две вещи почти всегда обсуждают как одну тему.
Как детектор речевой активности принимает решение
У VAD одна задача и жёсткое ограничение. Задача: посмотреть на текущий фрейм и выдать один бит – речь или нет. Ограничение: сделать это сейчас, почти не заглядывая в будущее, потому что живой разговор разваливается, как только круговая задержка превышает примерно 300–400 миллисекунд, так что детектор не может сидеть и ждать ещё звука перед решением.
Простейший VAD просто измеряет громкость. Если энергия фрейма выше порога – это речь, ниже – тишина. Это быстро и крошечно, и это ломается, как только комната шумная: громкий кондиционер берёт порог так же легко, как тихий голос. Поэтому любой серьёзный VAD смотрит не только на сырую громкость. Он смотрит на то, как энергия распределена по частотам, потому что у речи и у ровного шума разная форма. У голоса есть структура – он концентрирует энергию в полосах, где живёт человеческая речь, и эта структура меняется от мгновения к мгновению, пока говорящий формирует разные звуки. Вентилятор или кондиционер по сравнению с этим плоский и неизменный. Одна полезная мера этого – спектральная плоскостность: одно число, высокое, когда энергия размазана ровно по всем частотам, как у шума, и низкое, когда энергия собрана в нескольких полосах, как у голоса.
Три поколения VAD используют эту же идею со всё большей изощрённостью.
Классический телеком-VAD, стандартизованный в Рекомендации ITU-T G.729 Annex B (1996), был сделан для телефонной сети. Он сочетает четыре признака – полнополосную энергию, низкополосную энергию, меру формы спектра и частоту переходов через ноль – в решение «речь / не речь» и непрерывно отслеживает фоновый шум, чтобы порог подстраивался по мере того, как комната становится громче или тише (ITU-T G.729 Annex B, 1996). Это эталон, с которым сверялись более поздние конструкции.
WebRTC VAD, который встроен в Chrome, Edge и большинство нативных голосовых приложений, – тот, с которым инженеры реально работают. Он делит каждый фрейм на шесть частотных полос, считает энергию в каждой и подаёт их в небольшую статистическую модель – смесь гауссиан (Gaussian mixture model), метод, который держит один грубый шаблон «энергии речи» и один «энергии шума» и спрашивает, на что текущий фрейм больше похож. Он принимает фреймы по 10, 20 или 30 миллисекунд и даёт одну ручку настройки – «агрессивность» от 0 до 3, где 0 охотно сообщает о речи, а 3 – наиболее склонен счесть что-либо шумом. Повышение агрессивности отвергает больше шума, но рискует обрезать тихие края настоящих слов (WebRTC common_audio/vad, исходники libwebrtc).
Нейросетевой VAD, современный выбор по точности, заменяет рукописные правила небольшой сетью, обученной на тысячах часов речи и шума. Широко используемый открытый пример – Silero VAD – компактная модель (около 309 тысяч параметров, примерно 1–2 мегабайта на диске в версии 5, 2024 год), которая обрабатывает звук кусками по 512 отсчётов (32 миллисекунды при частоте дискретизации 16 kHz) и несёт немного контекста из предыдущего куска, чтобы читать течение речи, а не судить каждый кусок в отрыве. На обычном CPU она работает намного быстрее реального времени – её разработчики сообщают порядка 1 миллисекунды на кусок – и держится на множестве языков и типов шума там, где детекторы по энергии спотыкаются (заметки к релизу Silero VAD v5, 2024). Цена – файл модели, который нужно поставлять, и чуть больше вычислений, чем у шестиполосного подхода.
Вывод для неинженера: все три отвечают на один и тот же вопрос «да/нет». Чем новее конструкция, тем лучше она отличает тихий голос от громкой комнаты – и чем она лучше, тем меньше обрезает слова ваших пользователей.
Две ошибки, которые может совершить любой VAD
VAD – это классификатор, и, как у любого классификатора, у него ровно два способа ошибиться. Назвать их – самое полезное в этой статье, потому что любая жалоба на DTX, которую вы получите, сводится к одной из них.
Ложноотрицательная ошибка – это назвать настоящую речь «тишиной». Система перестаёт передавать посреди слова, и слушатель слышит, как первый слог фразы проглатывается – «…брый день, коллеги» вместо «Добрый день, коллеги». Это жалоба на обрезанную речь, и её пользователи ненавидят больше всего, потому что потеря слов рушит понимание.
Ложноположительная ошибка – это назвать шум «речью». Система продолжает слать полные пакеты во время тишины, так что вы просто теряете часть экономии, которую должен был дать DTX. Неприятно для облачного счёта, незаметно для пользователя.
Эти две ошибки напрямую обмениваются друг на друга, и ручка агрессивности – это рычаг. Сделайте VAD агрессивнее – он отвергнет больше шума (меньше ложноположительных, больше экономии), но начнёт обрезать тихие окончания слов (больше ложноотрицательных). Сделайте мягче – речь в безопасности, но экономия тает. Нет настройки, устраняющей обе; любая реальная система выбирает точку на этой линии. Инженерный приём, который выкупает бо́льшую часть проблемы обрезанной речи, – hangover (хвост удержания): после того как VAD перестал детектировать речь, система продолжает передавать ещё короткий хвост – несколько лишних фреймов – на случай, если говорящий лишь делает паузу между словами, а не закончил. Классический VAD G.729 Annex B использует именно такой шумозависимый hangover, чтобы защитить задний край речи (ITU-T G.729 Annex B, 1996). Он стоит немного трафика на удержание линии и экономит вам бо́льшую часть тикетов об обрезанных словах.
Прерывистая передача: действие по решению
Как только VAD говорит «этот отрезок – тишина», DTX решает, что́ реально положить на провод. Наивный ответ – не слать ничего – имеет проблему, которую телефонная индустрия выучила десятилетия назад: полная цифровая тишина звучит как поломка. Когда тихий гул комнаты, бывший мгновение назад, вдруг падает до мёртвого, абсолютного ничего, слушатели решают, что звонок оборвался, и начинают говорить «Алло? Вы там?». Решение – не уходить в полную тишину на проводе, а слать крошечный пакет, который, по сути, говорит: «проигрывай тихий шип под комнату, пока я не скажу иначе». Этот крошечный пакет называется описателем вставки тишины, по-английски SID (silence insertion descriptor), а подобранный шип, который приёмник проигрывает из него, – комфортный шум, генерируемый генератором комфортного шума (CNG).
Структура этого SID-пакета стандартизована. IETF RFC 3389 (сентябрь 2002) определяет RTP-нагрузку, несущую параметры комфортного шума: один байт уровня шума (насколько громким должен быть шип, в dBov – уровне относительно максимума системы) плюс необязательные байты, описывающие спектральную форму шума (его «цвет» – басовитый гул против яркого шипа) в виде коэффициентов отражения (RFC 3389, §3). Приёмник подаёт эти параметры в свой генератор комфортного шума и синтезирует подходящий шип локально. Обратите внимание, чего в пакете нет: никакого реального звука. RFC 3389 написан специально для старых кодеков без встроенной обработки тишины – G.711, G.722, G.726 – и смоделирован по схеме комфортного шума из Приложения II Рекомендации ITU-T G.711 (февраль 2000), которая, в свою очередь, заимствовала VAD и DTX из G.729 Annex B (RFC 3389, §2). Нагрузка несёт фиксированный тип RTP-нагрузки 13 на тактовой частоте 8 kHz (RFC 3389, §4).
Вот арифметика, которая делает всё это стоящим. Обычный голосовой пакет в звонке WebRTC несёт 20 миллисекунд кодированного звука – для речи в Opus порядка 40–80 байт полезной нагрузки, отправляемых 50 раз в секунду. Пакет SID / комфортного шума несёт лишь байт уровня и несколько спектральных байт – горстку байт – и шлётся гораздо реже, потому что шип комнаты почти не меняется от мгновения к мгновению.
Активная речь: 20 мс на фрейм → 50 пакетов/сек, ~40–80 байт нагрузки каждый
Тишина (DTX): описатель ~2–3 байта, шлётся лишь раз в несколько сотен мс
Итог: нагрузка неактивного микрофона падает примерно на 90%Разобранный пример. Допустим, один участник во время речи несёт 60 байт нагрузки Opus каждые 20 мс – это 60 × 50 = 3000 байт в секунду нагрузки. Тот же микрофон, неактивный под DTX, шлёт один 3-байтовый описатель каждые 400 мс – это 3 × 2,5 = 7,5 байт в секунду. Это сокращение нагрузки примерно на 99,75 процента на неактивном потоке – экономия драматична именно потому, что большинство микрофонов в звонке неактивны бо́льшую часть времени. (Когда вы добавите обратно фиксированные заголовки RTP, UDP и IP, полная экономия на поток меньше, чем экономия нагрузки, но всё равно велика – поэтому эмпирическое правило для целых звонков звучит как «десятки процентов», а не «девяносто девять процентов».)
Как это делает Opus – и одна ловушка
Opus, кодек, который несёт почти весь звук WebRTC, имеет встроенные VAD, DTX и комфортный шум – поэтому современный стек редко использует отдельную машинерию RFC 3389. Собственный VAD Opus живёт в речевой половине кодека (часть под названием SILK) и судит каждый фрейм по энергии полос и спектральной плоскостности – по тому же семейству признаков, что описано выше. Когда DTX включён и VAD сообщает тишину, Opus кодирует фрейм лишь примерно раз в 400 миллисекунд вместо каждых 20 – а декодер заполняет пробелы своим встроенным трактом маскировки потерь и комфортного шума (реализация Opus; инженерные заметки getstream.io по WebRTC, 2024).
Три точных факта из спецификации важны всем, кто это настраивает:
Во-первых, DTX выключен по умолчанию. Формат RTP-нагрузки Opus определяет параметр сессии usedtx, и «если значение не указано, по умолчанию 0» – то есть непрерывная передача (RFC 7587, §6.1, июнь 2015). DTX нужно запросить явно.
Во-вторых, когда Opus сбрасывает тихие фреймы, он должен сбрасывать только целые фреймы, такого размера, чтобы последовательные временные метки RTP отличались на кратное 120, – тогда приёмник может понять, что пробел – это намеренный DTX, а не потерянные пакеты, и может использовать целые фреймы для маскировки (RFC 7587, §3.1.3). Приёмник отличает DTX от потери пакетов, читая пробел во временных метках на фоне порядковых номеров (RFC 7587, §3.1.3).
В-третьих – и это ловушка – не сочетайте Opus со старой нагрузкой комфортного шума RFC 3389. Opus генерирует свой комфортный шум внутри; навесить сверху RFC 3389 избыточно и явно не рекомендуется стандартом: «Использование Comfort Noise по RFC 3389 с Opus не рекомендуется» (RFC 7587, §3.1.3). Тракт RFC 3389 – для кодеков, лишённых собственной обработки тишины, а не для Opus.
Вторая ловушка, которую стоит назвать: DTX в Opus включается в речевом режиме, а не в чисто музыкальном. Если загнать кодек в музыкальный режим или настроить так, что тракт тишины никогда не активируется, вы заплатите полную цену за неактивные микрофоны даже с usedtx=1. Подбирайте режим кодека под контент – голос для встречи, не музыку.
Частая ошибка: включить DTX не для того звонка
DTX – почти бесплатные деньги для разговора, где сама суть в том, что люди говорят по очереди и большинство микрофонов неактивны. Это неправильный выбор по умолчанию для трансляции непрерывного звука – музыкального выступления, диджей-сета по WebRTC, аудиоинсталляции, радионяни, чья вся цель – передавать тихую комнату. В этих случаях «тишина», которую детектирует VAD, и есть сигнал, нужный слушателю, и DTX срежет мягкие пассажи, заменив их синтетическим шипом. Стандарт говорит то же: непрерывная передача рекомендуется, если ограничения сети не суровы, потому что DTX несёт чуть более низкое качество звука, чем отправка каждого фрейма (RFC 7587, §3.1.3). Правило: DTX включён для разговора, выключен для прослушивания звука, который должен быть тихим.
Есть и взаимодействие настроек, о котором стоит предупредить инженеров. DTX стоит ниже шумоподавления и регулировки усиления в тракте захвата. Если шумоподавитель агрессивен, VAD видит более чистый сигнал и лучше решает про тишину; если регулировка усиления накачивает почти тихую комнату, VAD может принять усиленный шип за речь и держать поток живым. Части не независимы – их настраивают вместе.
У VAD есть вторая карьера: он не только про экономию трафика
Стоит знать, что то же решение «речь / тишина» переиспользуется по всему современному голосовому продукту, часто заметнее, чем работа по трафику.
Конвейер транскрипции или распознавания речи использует VAD, чтобы найти, где начинаются и кончаются высказывания, и нарезать звук на куски размером с предложение для подачи в распознаватель – это «эндпоинтинг», который решает, когда голосовой ассистент считает, что вы закончили фразу. Система записи использует VAD, чтобы пропускать мёртвый эфир, давая более короткий файл и более чистую расшифровку. Шумовой гейт в интерфейсе конференции использует VAD, чтобы зажигать индикатор «вы говорите» и заглушать поток участника, пока он реально не заговорит. Голосовой агент использует VAD для смены реплик – решая, что человек остановился и агент может начать. Популярность Silero VAD во многом идёт от этих применений, а не от DTX. Так что, когда инженер говорит «нам нужен хороший VAD», он может иметь в виду точность транскрипции или отзывчивость агента, а вовсе не трафик – стоит уточнить, какая задача на столе.
Где здесь Фора Софт
Фора Софт встраивает звук реального времени в видеоконференции, телемедицину, онлайн-обучение и live-shopping с 2005 года. В этих системах настройка VAD и DTX – рутинное, но значимое решение: телемедицинский звонок хочет мягкий VAD с щедрым hangover, чтобы тихая реплика врача никогда не обрезалась, а вебинар на 500 человек хочет агрессивный DTX на каждом микрофоне аудитории, чтобы медиасервер не захлёбывался неактивными пакетами. Мы подбираем этот баланс под каждый продукт, следим за метриками обрезанной речи и частоты пакетов вместе и держим DTX выключенным там, где контент – непрерывный звук, а не разговор. Тот же сигнал «речь / тишина» затем питает функции транскрипции и «активного спикера», которые пользователи реально видят.
Главное
- VAD решает «речь или тишина» на фрейм; DTX действует на это, останавливая полную передачу во время тишины.
- Во время тишины система шлёт крошечный описатель, а не ничего, чтобы приёмник проиграл подобранный комфортный шум.
- Две ошибки VAD: обрезать настоящую речь (пользователи ненавидят) и пропустить тишину (просто теряете экономию).
- Hangover – передача короткого хвоста после остановки речи – выкупает бо́льшую часть жалоб на обрезанные слова.
- У Opus DTX встроен (usedtx=1, по умолчанию выключен), сбрасывает целые фреймы и не рекомендует комфортный шум RFC 3389.
- Выключайте DTX для потоков непрерывного звука вроде музыки – он срежет тихие пассажи, нужные пользователям.