# 🎵 Теория: физика звуковой волны, ICS-43434 и камертон

## 1. Звук как механическая волна

Звук — продольная волна давления в упругой среде (чаще всего в воздухе). Источник колебаний
(камертон, голосовые связки, динамик) попеременно сжимает и разрежает молекулы воздуха рядом с
собой; область сжатия/разрежения передаётся соседним молекулам и бежит дальше со скоростью звука
(~343 м/с в воздухе при 20°C) — сами молекулы при этом почти не перемещаются, они лишь
колеблются вокруг положения равновесия и передают импульс дальше, как костяшки домино.

Волна полностью описывается несколькими величинами:

| Величина | Единица | Что определяет на слух |
| :--- | :--- | :--- |
| **Частота** $f$ | Гц (колебаний/сек) | Высоту звука (низкий/высокий) |
| **Период** $T = 1/f$ | с | Время одного полного колебания |
| **Длина волны** $\lambda = v/f$ | м | Расстояние между соседними сжатиями в воздухе |
| **Амплитуда** | Па (давление) | Громкость |

Уравнение простой гармонической волны звукового давления: $p(t) = A\sin(2\pi f t + \varphi)$, где
$A$ — амплитуда, $\varphi$ — фаза (сдвиг во времени). Именно такой сигнал — почти идеально —
даёт камертон: он сконструирован так, чтобы после удара звучать одной строго определённой
частотой, а не смесью многих (в отличие от голоса или большинства музыкальных инструментов).

Человеческое ухо слышит примерно 20 Гц — 20000 Гц (диапазон сужается с возрастом, в основном
сверху). Камертоны для настройки музыкальных инструментов обычно делают на 440 Гц (нота Ля
первой октавы, международный эталон высоты звука с 1955 года) или, для медицинских
неврологических камертонов, на более низкие частоты (128 Гц и т.д.).

## 2. Как ICS-43434 превращает волну в числа

ICS-43434 — MEMS-микрофон (Micro-Electro-Mechanical System): на кремниевом кристалле вытравлена
микроскопическая мембрана, которая прогибается под звуковым давлением. В отличие от
классического электретного микрофона (мембрана + отдельный аналоговый усилитель + отдельный АЦП
где-то на плате), у ICS-43434 усилитель и 24-битный АЦП находятся прямо на том же кристалле —
наружу выходит уже готовый цифровой поток по протоколу **I2S**, без промежуточного аналогового
сигнала, который мог бы наловить помех по дороге.

Формат данных и протокол I2S — тот же, что разобран в компоненте [INMP441](../INMP441/THEORY.md#3-протокол-i2s-три-провода-одна-идея):
три линии (SCK/такт, WS/выбор слота, SD/данные), 24 значащих бита в 32-битном слове с
MSB-выравниванием. Конфигурация в этом компоненте — [`Ics43434::begin()`](src/Ics43434.cpp#L5-L39).
Микрофон электрически и протокольно почти идентичен INMP441 — это не совпадение, а стандарт
де-факто для недорогих I2S MEMS-микрофонов; отличаются в основном паспортные характеристики.

## 3. Паспортные параметры (⚠️ по общедоступным источникам, не сверено с оригинальным PDF)

| Параметр | Значение | Что означает |
| :--- | :--- | :--- |
| SNR | ~65 дБА | Отношение сигнал/шум — выше, чем у более дешёвых микрофонов вроде INMP441 (~61 дБА), меньше собственного шума |
| Чувствительность | −26 дБFS @ 94 дБ SPL, 1 кГц | Заводской эталон: при звуковом давлении 94 дБ SPL цифровой сигнал достигает −26 дБ от максимума шкалы |
| Диапазон частот | ~60 Гц — 20 кГц | Шире, чем у INMP441 (60 Гц — 15 кГц) — лучше передаёт высокие обертоны |
| Питание | ~1.6–3.6 В | Совместимо с 3.3В логикой ESP32 |

Эти цифры взяты из широко цитируемых источников по чипу и **не проверены по оригинальному
даташиту** в рамках подготовки этого компонента — если точность критична (например, для
серьёзного научного проекта), сверьте по PDF на сайте производителя.

## 4. Частота дискретизации и теорема Найквиста

АЦП не записывает непрерывную кривую, а берёт мгновенные "снимки" давления через равные
промежутки времени — **частота дискретизации** (`sample_rate` в
[Ics43434.h:30](include/Ics43434.h#L30), по умолчанию 44100 Гц — стандартная частота CD-качества
и большинства звуковых карт, выбрана здесь, чтобы даже высокие обертоны и точный анализ pYIN
работали без потерь).

**Теорема Котельникова-Найквиста**: чтобы правильно восстановить волну частотой $f$, нужно делать
не менее $2f$ снимков в секунду. При 44100 Гц корректно различимы частоты вплоть до **22050 Гц**
(частота Найквиста) — выше всего слышимого диапазона человека, поэтому камертоны, голос и музыка
оцифровываются без потери информации. Если в сигнале есть частоты выше половины частоты
дискретизации, они не исчезают, а искажённо "отражаются" обратно в слышимый диапазон —
**алиасинг** (aliasing), классическая ошибка любой цифровой измерительной системы.

## 5. Преобразование Фурье: из чего состоит сложный звук

Любой периодический сигнал можно представить суммой простых синусоид разных частот, амплитуд и
фаз — это теорема Фурье. **Преобразование Фурье** (в цифровой технике — БПФ, быстрое
преобразование Фурье) вычисляет эти составляющие численно, превращая график "давление от
времени" (осциллограмму) в график "энергия от частоты" (**спектр**).

- **Камертон** после удара звучит практически одной синусоидой — на спектре один острый, узкий
  пик. Это не случайность, а инженерная цель конструкции камертона: масса и упругость вилки
  подобраны так, чтобы подавить все моды колебаний, кроме основной.
- **Голос** — наложение нескольких резонансов голосового тракта (форманты) — несколько пиков.
- **Хлопок/удар** — очень короткий во времени сигнал даёт широкий, размазанный по частотам
  спектр: чем короче импульс во времени, тем шире его спектр — фундаментальное свойство
  преобразования Фурье (неопределённость время-частота, родственная принципу неопределённости
  Гейзенберга в физике волн вообще).

Инструмент [`tools/02_spectrum_fft.py`](tools/02_spectrum_fft.py) считает БПФ через
`numpy.fft.rfft` и рисует спектр и спектрограмму (спектр, меняющийся во времени, — третье
измерение через цвет).

## 6. Биения: что происходит, когда звучат два источника почти в унисон

Если рядом одновременно звучат два источника с близкими, но не равными частотами $f_1$ и $f_2$
(например, два слегка расстроенных камертона), их волны в воздухе складываются — принцип
суперпозиции. Математически:

$$\sin(2\pi f_1 t) + \sin(2\pi f_2 t) = 2\cos\!\left(2\pi\frac{f_1-f_2}{2}t\right)\sin\!\left(2\pi\frac{f_1+f_2}{2}t\right)$$

Результат — сигнал на средней частоте $\bar f = (f_1+f_2)/2$ (несущей, которую слышно как
"высоту звука"), амплитуда которого медленно пульсирует с частотой **биений**:

$$f_{\text{биений}} = |f_1 - f_2|$$

Это именно то периодическое "у-у-у-у" нарастания-затухания громкости, которое слышно, когда два
почти одинаковых тона звучат вместе. Настройщики музыкальных инструментов используют это
явление: чем меньше слышно биений между струной и эталонным камертоном, тем точнее настроен
инструмент — при полном унисоне ($f_1 = f_2$) биения пропадают совсем.

Инструмент [`tools/03_tuning_fork.py`](tools/03_tuning_fork.py) в режиме `beats` записывает
реальный звук двух одновременно звучащих источников и строит огибающую сигнала (через
преобразование Гильберта) — на ней видны именно эти периодические провалы громкости, а частоту
$f_1, f_2$ показывают два пика в спектре записи.

### Комбинационные тона Тартини

Если разность частот становится большой (десятки Гц), биения перестают восприниматься как
плавная пульсация громкости одного тона и превращаются в отдельный, самостоятельно слышимый
низкий тон — эффект открыл в 1714 году итальянский скрипач и теоретик музыки Джузеппе Тартини,
отсюда название "тон Тартини" (комбинационный тон). Физиологически это уже не свойство самой
волны в воздухе, а нелинейность обработки сигнала во внутреннем ухе.

## 7. Мел-шкала: почему ухо — не БПФ

БПФ даёт **линейную** шкалу частот: расстояние между 100 Гц и 200 Гц на графике равно расстоянию
между 10100 Гц и 10200 Гц. Человеческое ухо воспринимает высоту звука совсем не так: разница
между 100 Гц и 200 Гц звучит для нас как "заметный скачок вверх на октаву", а разница между
10000 Гц и 10100 Гц почти неразличима на слух. Это связано с устройством улитки внутреннего уха
(cochlea) — разные её участки резонируют на разные частоты, и это разбиение неравномерно:
плотнее в низких частотах, реже в высоких.

**Мел-шкала** (от англ. *melody*) — эмпирическая психоакустическая шкала, приближающая это
неравномерное восприятие. Стандартная формула перевода из герц в мелы:

$$m = 2595 \cdot \log_{10}\!\left(1 + \frac{f}{700}\right)$$

Инструмент [`tools/04_mel_hearing.py`](tools/04_mel_hearing.py) строит бок о бок два
спектрограммных представления одной записи — линейное (как считает БПФ) и мел-шкалу (как
приближённо слышит ухо, через `librosa.feature.melspectrogram`), чтобы физически увидеть эту
разницу: на мел-шкале низкочастотная часть голоса растягивается на графике, а высокочастотная
сжимается — потому что именно там ухо различает мельчайшие детали.

## 8. Почему нет абсолютных дБ SPL

В акустике громкость измеряют в **дБ SPL** (Sound Pressure Level) — абсолютной шкале
относительно порога слышимости (20 мкПа). Заводская чувствительность ICS-43434 (раздел 3)
связывает конкретное звуковое давление (94 дБ SPL, тон 1 кГц) с конкретным цифровым уровнем
(−26 дБFS) — но только для эталонного откалиброванного экземпляра на заводе.

Этот компонент **не выполняет калибровку** — ни один физический экземпляр не проверялся
эталонным источником звука. Поэтому во всём коде и во всех графиках используется только
**относительная шкала**:
- **LSB** — "сырое число" АЦП, 16-битное значение от −32768 до 32767 после
  [`Ics43434::toSample16()`](include/Ics43434.h#L59-L61).
- **дБFS** (dB Full Scale) — логарифмическая шкала относительно максимума этой 16-битной шкалы,
  используется в [`main.cpp`](src/main.cpp#L79-L96) и в [`tools/01_noise_meter.py`](tools/01_noise_meter.py) —
  показывает, насколько сигнал близок к клиппингу, а не абсолютную громкость в паскалях.

Если нужен настоящий дБ SPL — требуется калибровка конкретного экземпляра эталонным источником
известной громкости (например, калибратором 94 дБ SPL/1 кГц).

## 9. Почему чтение блокирующее, но не теряет данные: DMA

`i2s_channel_read()` в [`Ics43434::read()`](src/Ics43434.cpp#L41-L52) не "слушает" линию SD
напрямую в момент вызова — ESP32 непрерывно копирует поступающие биты в буфер памяти через
**DMA** (Direct Memory Access) в фоне, независимо от того, чем занят процессор. `read()` лишь
забирает уже накопленные готовые сэмплы из буфера (и ждёт новых до `timeout_ms`, если тот пуст).
Поэтому даже недолгая задержка в `loop()` (например, на `Serial.print()`) не теряет звук — он
подождёт в DMA-буфере, пока тот не переполнится.
