Энергия, переходы через ноль и основа VAD
Два дешёвых признака, которые до сих пор работают в детекции речи.
ZCR (zero-crossing rate) — частота смены знака сигнала; грубо отражает «высокочастотность» звука и помогает отличать шипящие от гласных.
Не для всего нужны нейросети. Многие практичные признаки считаются прямо во временной области одной формулой. Два классических — краткосрочная энергия и частота переходов через ноль. На них строилась детекция голоса задолго до глубокого обучения, и они до сих пор работают как быстрый предварительный фильтр.
Краткосрочная энергия
Энергия кадра — сумма квадратов его отсчётов. У речи энергия высокая, у тишины — близка к нулю. Это самый простой способ найти, где в записи кто-то говорит, а где пауза.
Переходы через ноль (ZCR)
ZCR считает, сколько раз внутри кадра сигнал сменил знак (перешёл через ноль). Высокочастотные звуки (шипящие «с», «ш») колеблются часто — высокий ZCR. Низкочастотные гласные — низкий ZCR. Интересно, что у тишины с шумом ZCR тоже высокий, но энергия низкая — комбинация двух признаков уже неплохо различает речь, шипящие и тишину.
| Тип | Энергия | ZCR |
| Гласный (а, о) | высокая | низкий |
| Шипящий (с, ш) | средняя | высокий |
| Тишина | низкая | любой |
Считаем оба признака
frame = [0.0, 0.5, -0.3, 0.4, -0.6, 0.2, -0.1, 0.3]
energy = sum(x * x for x in frame)
crossings = 0
for i in range(1, len(frame)):
if (frame[i - 1] < 0) != (frame[i] < 0):
crossings += 1
zcr = crossings / (len(frame) - 1)
print("Энергия:", round(energy, 3))
print("Переходов через ноль:", crossings)
print("ZCR:", round(zcr, 3))Вывод:
Энергия: 1.0 Переходов через ноль: 6 ZCR: 0.857
Высокий ZCR при заметной энергии — похоже на шипящий звук. Так, имея лишь две формулы, мы уже что-то «понимаем» про содержимое кадра.
Простейший VAD по порогу энергии
VAD (Voice Activity Detection) — детекция речи. Простейшая версия: считаем энергию по кадрам и сравниваем с порогом.
frames_energy = [0.01, 0.02, 0.8, 1.2, 0.9, 0.03, 0.01, 0.7]
threshold = 0.1
for i, e in enumerate(frames_energy):
label = "речь" if e > threshold else "тишина"
print("кадр", i, "энергия", e, "->", label)Вывод:
кадр 0 энергия 0.01 -> тишина кадр 1 энергия 0.02 -> тишина кадр 2 энергия 0.8 -> речь кадр 3 энергия 1.2 -> речь кадр 4 энергия 0.9 -> речь кадр 5 энергия 0.03 -> тишина кадр 6 энергия 0.01 -> тишина кадр 7 энергия 0.7 -> речь
Сила связки «энергия + ZCR» в том, что она почти бесплатна по вычислениям и не требует ни нейросети, ни даже преобразования Фурье — только сложения и сравнения знаков. Поэтому такой простой VAD до сих пор живёт там, где важны экономия и скорость: в наушниках с шумоподавлением, в чипах умных колонок, которые должны постоянно «слушать» в режиме ожидания на крошечной батарее. Гонять полноценную нейросеть ради того, чтобы понять «есть звук или тишина», расточительно; дешёвый порог по энергии отсеивает паузы, и тяжёлая модель ASR просыпается только на реальной речи.
Почему именно пара признаков работает лучше каждого по отдельности? Возьмём тихую комнату с лёгким фоновым шипением вентилятора. По одной энергии это похоже на паузу — уровень низкий. Но если порог поставить слишком низко, шипение пролезет как «речь». ZCR здесь спасает иначе: и у шипящих согласных, и у фонового шума переходов через ноль много, поэтому сам по себе высокий ZCR речь не доказывает. А вот сочетание — заметная энергия плюс умеренный ZCR — уже неплохо указывает на гласные, то есть на ядро речи. Один признак легко обмануть, два вместе — гораздо труднее.
Важная честная оговорка: пороговый VAD прост, но хрупок. Стоит появиться громкой музыке, гулу улицы или нескольким говорящим сразу — и фиксированный порог по энергии начинает путать шум с речью и наоборот. Поэтому в шумных условиях его либо делают адаптивным (порог подстраивается под текущий уровень фона), либо заменяют на нейросетевой VAD вроде Silero, который обучен отличать именно человеческий голос, а не просто «громкое от тихого». Классические энергия и ZCR при этом не исчезают — они часто остаются дешёвым первым фильтром перед более умной моделью.
Как работает под капотом
Современные VAD (например, Silero) — это маленькие нейросети, точные даже в шуме. Но их идея та же: по кадрам выдавать «речь / не речь». Энергия и ZCR остаются полезны как лёгкая первая ступень в конвейере — они почти бесплатны по вычислениям и отсекают очевидную тишину до запуска тяжёлых моделей. В разделе про шумоподавление мы вернёмся к VAD подробнее.
Частые ошибки
- Жёсткий фиксированный порог энергии. В шумной записи тишина «громкая» — порог надо адаптировать.
- Использовать только энергию. Тихие шипящие можно принять за тишину; ZCR помогает.
- Считать ZCR панацеей. На сильном шуме ZCR теряет смысл — нужны спектральные признаки.
Итоги
- Краткосрочная энергия отделяет речь от тишины.
- ZCR (частота переходов через ноль) различает высоко- и низкочастотные звуки.
- Комбинация энергии и ZCR — основа классического VAD.
- Современные VAD — нейросети, но с той же идеей «речь/не речь по кадрам».