Временная область, окна и фреймы

Ключевая идея анализа звука: работать не со всей записью, а с короткими кадрами.

Фрейм (окно) — короткий отрезок сигнала (обычно 20–40 мс), внутри которого звук считается почти неизменным и анализируется отдельно.

Речь и музыка постоянно меняются: за секунду произносится несколько звуков. Анализировать всю запись одним куском бессмысленно — характеристики «размажутся». Поэтому сигнал режут на короткие окна и анализируют каждое отдельно. Это фундамент спектрограммы и почти всех признаков.

Почему именно 20–40 мс

Окно выбирают так, чтобы внутри него звук был квазистационарным — почти не менялся. Для речи это 20–40 мс: за такой срок артикуляция не успевает измениться, но окно достаточно длинное, чтобы оценить частоты. Слишком короткое окно плохо различает частоты, слишком длинное — смазывает быстрые изменения. Это фундаментальный компромисс время/частота.

Перекрытие и hop

Окна берут с перекрытием: следующее начинается не там, где кончилось предыдущее, а раньше. Шаг между началами окон называют hop (обычно 10 мс). Перекрытие нужно, чтобы не потерять события на стыках и получить плавную картину во времени.

сигнал: ====================================
окно 1: [------]
окно 2:     [------]
окно 3:         [------]
окно 4:             [------]
            ^hop^
        перекрытие окон

Режем сигнал на кадры кодом

Реализуем нарезку на окна с перекрытием — это ровно то, что делает первый шаг любой спектрограммы.

signal = list(range(20))   # 20 «отсчётов» для наглядности
frame_size = 8
hop = 4

frames = []
start = 0
while start + frame_size <= len(signal):
    frames.append(signal[start:start + frame_size])
    start += hop

print("Число кадров:", len(frames))
for i, fr in enumerate(frames):
    print("кадр", i, ":", fr)

Вывод:

Число кадров: 4
кадр 0 : [0, 1, 2, 3, 4, 5, 6, 7]
кадр 1 : [4, 5, 6, 7, 8, 9, 10, 11]
кадр 2 : [8, 9, 10, 11, 12, 13, 14, 15]
кадр 3 : [12, 13, 14, 15, 16, 17, 18, 19]

Видно перекрытие: отсчёты 4–7 попадают и в кадр 0, и в кадр 1. Так из одного длинного сигнала получается последовательность кадров, которую дальше анализируют по частотам.

Оконная функция

Если просто «вырезать» кадр, на его краях возникают резкие обрывы, которые портят спектр (добавляют ложные частоты). Чтобы этого избежать, кадр умножают на оконную функцию (Хэмминга, Ханна) — плавную кривую, которая мягко сводит края к нулю. Это стандартный шаг перед преобразованием Фурье.

Компромисс время/частота легко прочувствовать на аналогии с фотографией движения. Короткая выдержка ловит точный момент (хорошее разрешение во времени), но по одному кадру не понять скорость объекта. Длинная выдержка показывает смазанный след — видно скорость и направление (частоту), но точный момент потерян. С окнами звука то же самое: короткое окно точно скажет когда что-то произошло, но плохо различит близкие частоты; длинное окно тонко разделит частоты, но размажет момент во времени. Выбрать одновременно идеальную точность и там, и там физически невозможно — это фундаментальный предел, а не недоработка инженеров.

Полезно понимать, зачем вообще нужно перекрытие, на бытовом примере. Если резать запись на стыкующиеся, но не перекрывающиеся куски, короткий звук вроде щелчка согласной может попасть ровно на границу двух окон и «размазаться» — в обоих кадрах он будет лишь наполовину, и ни один не покажет его как цельное событие. Перекрытие с шагом hop в 10 мс гарантирует, что любой момент попадёт в центр хотя бы одного окна. Это как нарезать ленту с запасом внахлёст, чтобы на склейках ничего не выпало.

Зачем нужна оконная функция, проще всего объяснить через «честность» спектра. Когда мы грубо вырезаем кадр, на его краях сигнал обрывается резкой ступенькой, а Фурье воспринимает любой резкий скачок как присутствие множества высоких частот, которых в реальном звуке нет. Получаются призрачные «хвосты» в спектре — артефакт нарезки, а не свойство звука. Оконная функция Ханна или Хэмминга плавно гасит сигнал к краям окна до нуля, и спектр перестаёт «врать» о несуществующих частотах. Поэтому почти любой расчёт спектрограммы по умолчанию применяет окно ещё до Фурье.

Как работает под капотом

Когда вы увидите параметры n_fft=400, hop_length=160 в коде librosa или torchaudio, это и есть размер окна и шаг в отсчётах. При 16 кГц 400 отсчётов = 25 мс окно, 160 = 10 мс hop. Эти три числа — окно, hop, оконная функция — полностью задают, как запись превращается в последовательность кадров, а значит, и в спектрограмму.

Частые ошибки

  • Анализировать всю запись одним куском. Характеристики усреднятся и потеряют смысл.
  • Брать окна без перекрытия. События на стыках теряются, картина «дёргается».
  • Забыть оконную функцию. Резкие края кадра дают ложные частоты в спектре.

Итоги

  • Звук режут на короткие окна (20–40 мс), внутри которых он почти стационарен.
  • Окна берут с перекрытием; шаг между ними — hop (≈10 мс).
  • Перед спектром кадр умножают на оконную функцию, чтобы убрать обрывы краёв.
  • Окно, hop и оконная функция полностью задают нарезку записи на кадры.
Проверьте себя
1. Почему звук анализируют по коротким окнам, а не целиком?
AТак быстрее загружать файл
BВнутри короткого окна (20–40 мс) звук почти не меняется, и его можно корректно анализировать
CОкна экономят память диска
DЭто требование PCM
2. Что такое hop при нарезке на кадры?
AРазмер окна
BШаг между началами соседних окон
CЧастота сэмплирования
DЧисло каналов
3. Зачем кадр умножают на оконную функцию (Хэмминга/Ханна)?
AЧтобы сделать звук громче
BЧтобы плавно свести края кадра к нулю и убрать ложные частоты в спектре
CЧтобы изменить язык речи
DЭто не нужно