Разрядность, квантование и формат PCM

Вторая ось оцифровки: насколько точно мы записываем каждый замер.

Разрядность (bit depth) — число бит на один отсчёт; задаёт, на сколько уровней разбита амплитуда и насколько точно она записана.

Дискретизация решает, как часто мы измеряем сигнал. Квантование решает, насколько точно мы записываем каждое измерение. Вместе они полностью описывают оцифровку.

Квантование: непрерывное в целое

Замеренное напряжение — вещественное число, но хранить бесконечно точные числа нельзя. Поэтому диапазон амплитуд делят на конечное число уровней, и каждый замер округляют до ближайшего. Это квантование. Число уровней задаёт разрядность: 8 бит — 256 уровней, 16 бит — 65536 уровней.

РазрядностьУровнейГде
8 бит256старые игры, телефония
16 бит65536CD, стандарт ASR
24 бит16.7 млнстудийная запись

Шум квантования

Округление до уровня вносит маленькую ошибку — шум квантования. Чем больше бит, тем мельче шаг и тише шум. 16 бит дают динамический диапазон около 96 дБ — достаточно, чтобы шум был неслышим. 8 бит уже слышно как «песок» в тихих местах.

непрерывная амплитуда      квантованная (4 уровня)
   /\                          уровень
  /  \      становится      3 |__
 /    \      ---->          2 |  |__
/      \                    1 |     |__
                            0 |________|__

Что такое PCM

PCM (Pulse Code Modulation) — самый базовый способ хранить оцифрованный звук: просто последовательность квантованных отсчётов, число за числом, без сжатия. Файл WAV внутри — это, как правило, PCM плюс маленький заголовок с параметрами (частота, разрядность, каналы). MP3 и другие форматы — это уже сжатие поверх той же идеи.

Квантование своими руками

Промоделируем квантование: возьмём плавный сигнал и «прижмём» его к 4 уровням. Увидим, как появляется ступенчатость.

signal = [0.05, 0.27, 0.51, 0.74, 0.93, 0.66, 0.4, 0.12]
levels = 4  # 2 бита

def quantize(x, levels):
    step = 1.0 / (levels - 1)
    return round(x / step) * step

q = [round(quantize(x, levels), 3) for x in signal]
print("Исходный: ", signal)
print("Квантован:", q)

Вывод:

Исходный:  [0.05, 0.27, 0.51, 0.74, 0.93, 0.66, 0.4, 0.12]
Квантован: [0.0, 0.333, 0.667, 0.667, 1.0, 0.667, 0.333, 0.0]

Видно, как множество разных значений «схлопнулись» в 4 уровня. Разница между исходным и квантованным — это и есть шум квантования.

Чтобы прочувствовать разницу между дискретизацией и квантованием, представьте, что вы срисовываете график на клетчатую бумагу. Частота сэмплирования — это насколько часто стоят вертикальные линии (как часто во времени вы ставите точку). Разрядность — это насколько мелкие горизонтальные клетки (насколько точно вы можете отметить высоту точки). Можно ставить точки часто, но грубо округлять их по высоте — и наоборот. Качество записи страдает, если хромает любая из двух осей, поэтому в спецификациях всегда указывают обе: например, «16 бит / 44.1 кГц».

Полезная интуиция про шум квантования: каждый дополнительный бит примерно удваивает число уровней и даёт около +6 дБ динамического диапазона. Отсюда и магическое «16 бит ≈ 96 дБ» (16 × 6). Это огромный запас: разница между шёпотом и отбойным молотком умещается в него с лихвой, поэтому на музыкальном CD шум квантования человек не слышит. А вот в старых 8-битных играх уровней всего 256, ступеньки крупные, и в тихих местах отчётливо слышен характерный «песок» — это и есть слышимый шум квантования.

Клиппинг коварен тем, что необратим, и это стоит прочувствовать на примере. Представьте, что вы записываете рок-концерт и выставили уровень входа слишком высоко. Громкие пики барабанов выходят за максимум диапазона 32767, и АЦП просто записывает на их месте плоскую «крышу» — вершины волн срезаются в прямые линии. Никакая последующая обработка не вернёт утраченную форму, ведь данных о настоящей высоте пика уже нет. Поэтому звукорежиссёры держат запас в несколько дБ до потолка: лучше записать чуть тише и потом усилить, чем потерять пики навсегда.

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

В 16-битном PCM каждый отсчёт хранится как целое число со знаком от -32768 до 32767. Тишина — около нуля, максимальная громкость — у краёв диапазона. Если сигнал выходит за край (слишком громкий вход), происходит клиппинг: вершины волны срезаются, появляется хрип. Поэтому уровень записи держат с запасом. При подаче в модель такие int-отсчёты обычно нормируют в диапазон [-1, 1] делением на 32768.

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

  • Слишком низкая разрядность. 8 бит для речи дают слышимый шум в тихих фрагментах.
  • Клиппинг при записи. Перегруз входа необратимо срезает пики волны.
  • Забыть нормировку. Подача int16 без деления на 32768 ломает модели, ждущие float [-1, 1].

Итоги

  • Разрядность задаёт число уровней амплитуды; 16 бит — стандарт.
  • Квантование вносит шум; больше бит — тише шум.
  • PCM — несжатая последовательность отсчётов; WAV = PCM + заголовок.
  • Клиппинг и отсутствие нормировки — типичные источники проблем.
Проверьте себя
1. Что задаёт разрядность (bit depth) звука?
AСколько замеров в секунду
BНа сколько уровней разбита амплитуда (точность каждого отсчёта)
CДлину записи
DЧисло каналов
2. Что такое PCM?
AАлгоритм сжатия звука
BНесжатая последовательность квантованных отсчётов
CФормат спектрограммы
DМодель нейросети
3. Почему перед подачей int16-аудио в модель его нормируют делением на 32768?
AЧтобы ускорить запись
BЧтобы привести отсчёты к диапазону float [-1, 1], который ждут модели
CЧтобы увеличить громкость
DЭто не нужно