Квантование, разрядность и шум квантования
Второй шаг оцифровки: как непрерывную амплитуду укладывают в конечное число уровней и какой ценой.
Квантование — округление амплитуды каждого отсчёта до ближайшего уровня из конечного набора; число уровней задаёт разрядность (число бит).
Дискретизация решила вопрос времени: мы берём значения в отдельные моменты. Но само значение всё ещё вещественное число с бесконечной точностью. Хранить его целиком нельзя — нужно округлить до одного из конечного набора уровней. Это и есть квантование, второй и последний шаг оцифровки.
Разрядность и уровни
b бит дают 2**b уровней. 8 бит — 256 уровней, 16 бит (аудио-CD) — 65536, 24 бита (студия) — больше 16 миллионов. Чем больше уровней, тем точнее округление и тише шум, но тем больше данных.
| Биты | Уровней | Где применяют |
| 8 | 256 | старые игры, телефония (mu-law) |
| 12 | 4096 | многие АЦП микроконтроллеров, ЭКГ |
| 16 | 65536 | аудио-CD, бытовой звук |
| 24 | 16.7 млн | студийная запись |
Квантуем сигнал
Округлим синусоиду до 3 бит (8 уровней) в диапазоне -1..1 и посмотрим на разницу с оригиналом — это и есть ошибка квантования.
import math
def quantize(v, bits, vmax=1.0):
levels = 2 ** bits
step = 2 * vmax / levels
q = round(v / step) * step
return max(-vmax, min(vmax, q))
sig = [math.sin(2 * math.pi * n / 16) for n in range(8)]
q3 = [round(quantize(v, 3), 3) for v in sig]
err = [round(s - q, 3) for s, q in zip(sig, q3)]
print("Оригинал:", [round(v, 3) for v in sig])
print("3 бита :", q3)
print("Ошибка :", err)
Вывод:
Оригинал: [0.0, 0.383, 0.707, 0.924, 1.0, 0.924, 0.707, 0.383] 3 бита : [0.0, 0.5, 0.75, 1.0, 1.0, 1.0, 0.75, 0.5] Ошибка : [0.0, -0.117, -0.043, -0.076, 0.0, -0.076, -0.043, -0.117]
Каждое значение «прыгнуло» на ближайший из 8 уровней; разница между оригиналом и округлённым — ошибка, и она ведёт себя как шум, наложенный на сигнал.
Шум квантования и правило 6 дБ на бит
Ошибки округления образуют шум квантования. Его величина — порядка половины шага квантования. Чем больше бит, тем меньше шаг и тем тише шум. Качество измеряют отношением сигнал/шум (SNR). Для идеального квантователя действует знаменитое правило: каждый дополнительный бит даёт примерно 6 дБ SNR (точнее, SNR ≈ 6.02*b + 1.76 дБ).
def snr_db(bits):
return round(6.02 * bits + 1.76, 1)
for b in [8, 12, 16, 24]:
print(f"{b:>2} бит -> SNR ~ {snr_db(b)} дБ")
Вывод:
8 бит -> SNR ~ 49.9 дБ 12 бит -> SNR ~ 74.0 дБ 16 бит -> SNR ~ 98.1 дБ 24 бит -> SNR ~ 146.2 дБ
16 бит дают около 98 дБ — этого хватает, чтобы шум квантования был тише любого реального фона. Поэтому аудио-CD звучит «чисто».
Как работает под капотом
Шум квантования при достаточно сложном сигнале можно считать равномерно распределённым в диапазоне [-step/2, step/2]. Его мощность равна step**2 / 12 — отсюда и берётся формула SNR. На тихих и простых сигналах шум становится коррелированным с сигналом и слышен как искажение; чтобы его «размешать» в обычный шум, добавляют крошечный случайный сигнал — дизеринг (dither). Это контринтуитивно: специально добавленный шум улучшает субъективное качество, разрушая закономерность ошибок округления.
Частые ошибки
- Путать разрядность и частоту дискретизации.
fsотвечает за частоты (ось времени), биты — за точность амплитуды (ось значений). Это независимые параметры. - Гнаться за 24 битами на бытовой задаче. Лишние биты раздувают данные; если фон громче шага квантования, прирост не слышен.
- Игнорировать клиппинг. Если сигнал выходит за диапазон
vmax, он «обрезается» по верху — это уже не шум, а грубое искажение, которое не лечится битами.
Итог
- Квантование округляет амплитуду до одного из
2**bуровней;b— разрядность. - Ошибки округления образуют шум квантования величиной около половины шага.
- Правило: каждый бит добавляет ~6 дБ к SNR; 16 бит дают ~98 дБ.
- Разрядность и
fsнезависимы: одна про амплитуду, другая про частоты.