Skip to content
C. Цифровой тракт и DSP. 15-20

Фаза C (занятия 15–28): Цифровой тракт и DSP студийного уровня

Стадия Такмана: активная работа, пик сложности модуля. Роль наставника по SSDL: фасилитатор — не даёт готовых решений, даёт вопросы, даташиты и границы поиска; worked examples остаются только на входе в каждую новую тему, дальше — самостоятельная сборка.

Дисциплина работы с парком плат: новое сначала на «расходном» BlackPill F411, отлаженное переносим на H743 (настольный процессор) и U585 (бортовой блок). Так цена ошибки новичка не равна цене флагманской платы.

    flowchart LR
    P["Пьезо LDT0-028K"] --> FE["Аналоговый фронтенд<br/>(фаза B)"]
    FE --> ADC["ES8311 АЦП<br/>24 бит / 48 кГц"]
    ADC -- "SAI/I2S + DMA<br/>double buffer" --> DSP["STM32H743<br/>HPF 30 Гц → notch-EQ →<br/>компрессор/лимитер → IR-свёртка"]
    DSP -- "SAI + DMA" --> DAC["ES8311 ЦАП"]
    DAC --> AMP["NS4150B / линейный выход<br/>→ пульт, комбо"]
    I2C["I2C: конфигурация кодека"] -.-> ADC
    BLE["ESP32-C6: BLE-пресеты"] -. UART .-> DSP
    SRV["STM32G031: футсвитч,<br/>индикация, заряд LiPo"] -.-> DSP
  

Занятие 15. Архитектура тракта и роли плат

Цель занятия: обучающийся рисует и защищает блок-схему тракта с обоснованием роли каждой платы парка.

Разминка-вспоминание

(Интервальный возврат к фазе B через занятие): 1) f среза вашего фронтенда? 2) Зачем эшелон защиты у входа кодека? 3) Что даёт charge amp против буфера?

Разбор (worked example)

Сравнительная таблица плат: ядро, частота, FPU (одинарная/двойная точность), SRAM, периферия SAI, потребление. Вывод проговаривается: H743 (M7, 480 МГц, FPU-DP, 1 МБ RAM) — длинная IR и весь тракт с запасом; U585 (M33, 160 МГц, 786 КБ) — автономный бортовой блок с облегчённым трактом; F411 — полигон; G031 — сервис; ESP32-C6 — только управление, не аудио (одноядерный RISC-V без аппаратного FPU, BLE-джиттер).

Практика

Нарисуйте блок-схему

Свой вариант тракта (Mermaid или на бумаге) с указанием шин и разрядности.

Защитите распределение ролей

3 вопроса наставника вида «а почему DSP не на ESP32, он же с Wi-Fi?» — ответ с опорой на таблицу характеристик.

Бюджет латентности

Разбейте 10 мс на слагаемые: АЦП-группа задержки кодека + буфер N отсчётов + обработка + буфер на выход + ЦАП. Посчитайте буфер: 128 отсчётов @ 48 кГц = 2,67 мс на половину double buffer.

Типичные ошибки

  1. «Мегагерцы решают» — игнорируют FPU и SRAM. 2) Забывают, что в бюджет латентности буфер входит дважды (вход и выход). 3) Хотят стримить аудио по BLE «для удобства» — считаем джиттер и ставим BLE только на команды.

Мини-проверка выхода

Блок-схема утверждена; таблица бюджета латентности заполнена.


Занятие 16. I2C и регистры ES8311

Цель занятия: обучающийся читает и пишет регистры кодека по I2C и получает осмысленный ответ чипа.

Разминка-вспоминание

(Интервальный возврат к занятию 4–5): 1) Логические уровни «1» и «0» в вольтах при питании 3,3 В? 2) Зачем подтягивающие резисторы? (На I2C они обязательны — SDA/SCL с открытым стоком!) 3) Таблица истинности И — где она «живёт» в адресации устройства?

Разбор (worked example)

CubeMX на F411: включаем I2C1 (100 кГц), подтяжки 4,7 кОм на 3,3 В. Разобранный код: HAL_I2C_IsDeviceReady → скан шины → чтение регистра ID ES8311 → расшифровка по даташиту. Далее минимальная конфигурация кодека под 48 кГц/24 бит slave: последовательность записей регистров с комментарием у каждой строки «что включает и почему в этом порядке».

Практика

Подключите модуль кодека

Питание 3,3 В, SDA/SCL с подтяжками, земли объединены. До подачи питания — проверка наставником.

Скан шины и чтение ID

Добейтесь ACK по адресу кодека, прочитайте и расшифруйте ID-регистры.

Конфигурация

Прошейте последовательность инициализации; прочитайте регистры обратно и сверьте (write-verify — привычка на всю жизнь).

Типичные ошибки

  1. Нет подтяжек — шина молчит, «плата сломана». 2) Перепутан 7-битный адрес и адрес со сдвигом под HAL («1). 3) Пишут регистры до подачи MCLK, а даташит требует тактирование — читаем раздел Power-up sequence.

Мини-проверка выхода

Лог: скан шины, ID, конфигурация записана и верифицирована; ученик объясняет назначение 5 ключевых регистров.


Занятие 17. SAI/I2S: тактирование 48 кГц без джиттера

Цель занятия: обучающийся настраивает SAI (24 бит / 48 кГц, MCU master) и подтверждает частоты осциллографом.

Разминка-вспоминание

  1. Формат I2C-транзакции (старт-адрес-ACK-данные)? 2) Сколько бит в кадре при 24 бит стерео-слотах? 3) Что такое джиттер и почему он слышен?

Разбор (worked example)

Clock tree в CubeMX: от кристалла HSE через PLL получаем частоту, кратную 256×Fs (12,288 МГц MCLK для 48 кГц); показываем, почему «почти 48 кГц» от неточного PLL — это расстройка высоты тона и артефакты. Роли: MCU — master (BCLK, LRCK, MCLK), кодек — slave. Осциллограммой сверяем: LRCK = 48 кГц, BCLK = 48к × 2 × 32 = 3,072 МГц.

Практика

Настройте clock tree

Добейтесь целых 12,288 МГц на MCLK (подбор множителей PLL с наставником-фасилитатором: он спрашивает, не считает за вас).

Проверьте прибором

Осциллограф/логический анализатор на MCLK, BCLK, LRCK — частоты в протокол.

Ошибочный эксперимент

Намеренно задайте Fs = 44,1 кГц при конфигурации кодека на 48 кГц — послушайте и опишите артефакт. (Управляемая ошибка закрепляет понимание лучше запрета.)

Мини-проверка выхода

Протокол частот; устно: полный путь тактов от кварца до LRCK.


Занятие 18. DMA circular + double buffer (дебаг-кейс «заикание»)

Цель занятия: обучающийся объясняет механику двойной буферизации и чинит намеренно сломанный тракт.

Разминка-вспоминание

  1. Частота BCLK при 48 кГц/32-бит слотах? 2) Сколько мс в 128 отсчётах при 48 кГц? 3) Почему обработка «в прерывании сколько успеем» — плохо?

Разбор (worked example)

Схема: DMA в circular-режиме гонит SAI↔RAM непрерывно; колбэки HalfCplt/Cplt лишь поднимают флаг «половина X готова»; обработка — в основном цикле в свободную половину. Тайм-диаграмма на доске: что случится, если обработка длится дольше 2,67 мс (наезд на «живую» половину = треск).

Практика (кейс)

Получите эталон

Наставник даёт рабочий passthrough-проект для F411 и демонстрирует чистый звук.

Кейс

В код внесена одна из поломок: обработка в ISR с задержкой / перепутаны половины буфера / размер DMA в словах вместо байт. Диагностика по протоколу: симптом → гипотезы (мин. 2) → проверка (тумблер GPIO + осциллограф как профилировщик!) → исправление.

Обобщение

Запишите в «карту граблей DMA» найденный класс ошибки и её сигнатуру на слух/осциллографе.

Типичные ошибки

  1. Правка кода «наугад» без гипотезы — протокол требует сформулировать её письменно. 2) printf в реальном времени как «отладка» — сам ломает тайминг (обсуждаем GPIO-трассировку). 3) Кэш M7 (позже, на H743): забытая инвалидация кэша над DMA-буфером — данные «старые»; помечаем как грабли будущего занятия 21.

Мини-проверка выхода

Кейс закрыт по протоколу; число подсказок — в журнал SSDL.


Занятие 19. Сквозной passthrough на F411

Цель занятия: обучающийся самостоятельно собирает тракт «фронтенд → кодек → МК → кодек → выход» без обработки и измеряет задержку.

Разминка-вспоминание

  1. Роли HalfCplt/Cplt? 2) Слагаемые бюджета латентности? 3) Последовательность включения кодека?

Практика (самостоятельная сборка, наставник — фасилитатор)

Соберите всё вместе

Фронтенд фазы B → вход кодека (через вторую пару защитных диодов!) → SAI → буфер → SAI → выход кодека → NS4150B/наушники.

Сыграйте

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

Измерьте латентность

Способ: щелчок по датчику, двухканальный осциллограф (вход фронтенда / выход кодека) — дельта фронтов. Либо loopback-запись в Audacity. Значение в протокол.

ТБ: наушники надеваем только после проверки уровня на динамике — необработанный пьезо-пик в наушниках болезненен. В тракте пока нет лимитера — играть mezzo-piano.

Мини-проверка выхода

Чистый passthrough; измеренная задержка соотнесена с расчётной таблицей занятия 15.


Занятие 20. Биквады: параметрический EQ, вырезание резонанса плёнки

Цель занятия: обучающийся находит резонанс датчика по спектру и вырезает его notch-биквадом на CMSIS-DSP.

Разминка-вспоминание

(Интервальный возврат к занятию 10): 1) Что такое АЧХ и точка −3 дБ? 2) Как вы измеряли АЧХ фронтенда? 3) Латентность вашего passthrough?

Разбор (worked example)

Полностью разобранный код: arm_biquad_casd_df1_inst_f32, расчёт коэффициентов notch по Audio EQ Cookbook (формулы b0..a2 через f0, Q); конвертация int24→float32→int24; инициализация состояния; вызов arm_biquad_cascade_df1_f32 на половину буфера. Каждая строка прокомментирована.

Практика

Найдите резонанс

Спектр «сухого» пьезо в REW при игре гамм: характерный горб плёнки/крепления (обычно единицы кГц). Зафиксируйте f0 и ширину.

Вырежьте

Рассчитайте коэффициенты notch (f0, Q≈2…5), вставьте в тракт, сравните спектры до/после.

Добавьте HPF 30 Гц

Второй биквад каскада — против инфранизкого «пьезо-гула» и тряски датчика. Послушайте, что ушло.

Типичные ошибки

  1. Коэффициенты посчитаны для другой Fs — фильтр «уехал». 2) Состояние биквада объявлено локально в колбэке — сбрасывается каждый блок, щелчки. 3) Каскад «на всякий случай» из 8 фильтров — фаза и CPU; правило: каждый фильтр обоснован спектром.

Мини-проверка выхода

Спектры до/после с вырезанным резонансом; ученик выводит формулу пересчёта f0 → коэффициенты при смене Fs.


Занятие 21. Перенос на H743: кэш, память, профилирование

Цель занятия: обучающийся переносит тракт на боевую плату и измеряет загрузку ЦП.

Разминка-вспоминание

  1. Грабли кэша M7 над DMA (анонс занятия 18 — вспоминаем!) 2) Зачем float32 в тракте? 3) Ваша f0 резонанса?

Разбор (worked example)

Отличия H743: D-cache и когерентность с DMA (инвалидация/чистка или MPU-регион non-cacheable под аудиобуферы), размещение буферов по доменам памяти, флаги компилятора (-O2, FPU hard). Профилирование GPIO-тумблером: скважность на осциллографе = загрузка ЦП на блок.

Практика

Портируйте проект

CubeMX под H743, перенос DSP-кода. Ожидаемая ловушка кэша — найдите и решите её сами (наставник молчит первые 30 минут).

Профилируйте

Время обработки блока 128 отсчётов; загрузка ЦП в %. Запишите как базовую линию перед IR.

Мини-проверка выхода

Тракт работает на H743; таблица «этап → мкс/блок» заполнена.


Занятие 22. Динамика: компрессор и лимитер

Цель занятия: обучающийся реализует лимитер, убирающий клиппинг фортиссимо, и настраивает его на слух и по прибору.

Разминка-вспоминание

  1. Пик пиццикато в вольтах на входе — и что с ним делает аналоговая защита? 2) А что «пролезает» дальше в цифру? 3) Загрузка ЦП вашего тракта?

Разбор (worked example)

Детектор огибающей (пиковый, с attack/release как экспоненциальными сглаживаниями), передаточная кривая лимитера (порог, колено), почему release слышен «дыханием». Код разобран построчно; параметры вынесены в структуру пресета (задел под BLE занятия 27).

Практика

Встройте лимитер

После EQ. Порог — из измерений пиков занятия 19.

Настройте на инструменте

Пиццикато-фортиссимо: добейтесь отсутствия клиппинга без слышимой «накачки» на легато. Запишите пары до/после.

Осциллограф-контроль

Огибающая выхода при ударе: пик прижат, форма без ступенек.

Мини-проверка выхода

Фортиссимо без клиппинга; ученик объясняет влияние attack/release на слышимый результат.


Занятие 23. Снятие импульсной характеристики (IR)

Цель занятия: обучающийся получает IR-профиль «пьезо → студийный микрофон» для своей виолончели.

Разминка-вспоминание

  1. Что такое свёртка на пальцах («каждому отсчёту — своё эхо»)? 2) Зачем мы записывали референсы на занятии 1? 3) Порог вашего лимитера?

Разбор (worked example)

Метод: синхронная запись двух каналов (пьезо-тракт / конденсаторный микрофон или лучший доступный референс) одного исполнения; деконволюция в REW либо свип-сигнал через деку. Честно проговариваем ограничение: IR линейна, она переносит тембр/АЧХ, но не нелинейности — поэтому в тракте она после EQ и до лимитера.

Практика

Запишите пару

Дуал-запись гамм и фрагмента пьесы через USB-интерфейс/карту.

Постройте IR

Деконволюция; обрежьте хвост (окно), нормализуйте; экспорт в float32-массив (скрипт даётся готовым, читаем вместе).

Быстрая проверка на ПК

Свёртка оффлайн в Audacity/скрипте: послушайте «пьезо × IR» против референса — до всякого железа.

Мини-проверка выхода

IR-файл получен; оффлайн-свёртка звучит ближе к референсу (фиксируем субъективную оценку — она станет гипотезой для слепого теста фазы D).


Занятие 24. Свёртка на МК: FIR и путь к FFT (рубеж)

Цель занятия: обучающийся применяет короткую IR в реальном времени и измеряет цену в ЦП и латентности.

Разминка-вспоминание

Кумулятивный квиз фаз B–C середины (8 вопросов: от f среза до attack лимитера).

Разбор (worked example)

arm_fir_f32 с ядром N: цена ~N умножений-накоплений на отсчёт → таблица «N → % ЦП на H743». Вывод посчитан учеником, а не объявлен: прямой FIR на 512–2048 отводов — можно; тысячи и десятки тысяч — только партиционированная FFT-свёртка (overlap-add/overlap-save, uniform partitioned convolution), идея показывается на схеме без полного вывода математики.

Практика

FIR 512

Обрежьте IR до 512 отводов, включите в тракт. Профилируйте.

Раздвигайте, пока не упрётесь

1024 → 2048 → … : найдите практический потолок прямого FIR на H743 при вашем блоке. Таблица «N → мкс/блок → влезает?».

Рубежная демонстрация

EQ + лимитер + FIR-IR, живая игра; сквозная латентность измерена и записана.

Мини-проверка выхода

Рубеж: цепь работает, латентность записана; ученик формулирует, зачем нужна FFT-свёртка (сам, из своей таблицы).


Занятие 25. FFT-свёртка и бюджет < 10 мс

Цель занятия: обучающийся укладывает тракт с длинной IR в сквозную латентность < 10 мс, подтверждённую измерением.

Разминка-вспоминание

  1. Цена FIR N=2048 на отсчёт? 2) Слагаемые латентности? 3) Что даёт партиционирование IR?

Разбор (worked example)

Разобранная реализация uniform partitioned convolution на CMSIS arm_rfft_fast_f32: разбиение IR на партиции по размеру блока, спектры партиций считаются один раз, на лету — одна FFT + комплексные умножения-суммирования + одна IFFT на блок. Латентность метода = один блок (в отличие от «наивной» FFT всей IR).

Практика

Включите партиционированную свёртку

Готовый каркас с «дырками» (completion problems — промежуточный формат между worked example и самостоятельной работой): ученик дописывает ключевые места.

Подберите размер блока

64/128/256: таблица «блок → латентность → загрузка ЦП» → выбор рабочей точки.

Подтвердите бюджет

Двухканальный замер: вход фронтенда → выход кодека < 10 мс. Скриншот осциллограммы — в артефакты защиты.

Мини-проверка выхода

Латентность < 10 мс с длинной IR подтверждена прибором; выбор размера блока обоснован таблицей.


Занятие 26. Бортовой блок на U585 и LiPo-питание

Цель занятия: обучающийся собирает автономный облегчённый тракт на инструменте.

Разминка-вспоминание

  1. Чем U585 отличается от H743 (три пункта)? 2) Потолок прямого FIR — как он сместится на 160 МГц M33? 3) Ваш выбранный размер блока?

Разбор (worked example)

Порт тракта: EQ + лимитер + короткая IR (или партиционированная с меньшим числом партиций — считаем бюджет SRAM 786 КБ и ЦП заново для M33). Питание: LiPo 1S → TP4056 (заряд) → малошумящий LDO 3,3 В; развязка аналогового питания фронтенда RC/LC-фильтром от цифрового.

ТБ LiPo (инструктаж под подпись): заряжаем только через плату защиты/TP4056 и только под присмотром; не прокалываем, не гнём, не замыкаем; вздутый аккумулятор не используем и не заряжаем — сдаём наставнику; храним в несгораемом пакете; пайка непосредственно к выводам банки запрещена — только к плате защиты.

Практика

Порт и профилирование

Перенесите облегчённый тракт на U585, измерьте ЦП и латентность заново.

Автономность

Соберите питание, измерьте ток потребления, посчитайте часы работы от вашей ёмкости.

На инструменте

Закрепите блок и датчик (мастика/акриловый скотч — только неразрушающий крепёж на концертном инструменте!), сыграйте автономно.

Мини-проверка выхода

Автономная работа подтверждена; расчёт времени работы сходится с измеренным током ±20%.


Занятие 27. BLE-пресеты через ESP32-C6

Цель занятия: обучающийся переключает DSP-пресеты с телефона без разрыва звука.

Разминка-вспоминание

  1. Почему аудио не по BLE? 2) Где в коде живут параметры пресета (занятие 22)? 3) Ток покоя вашего блока?

Разбор (worked example)

Протокол UART между ESP32-C6 (BLE GATT-характеристика «пресет») и STM32: кадр [маркер|команда|параметры|CRC]; на стороне DSP — применение параметров на границе блока с кросс-фейдом (иначе щелчок). Показываем и обсуждаем угрозу: несанкционированное подключение — ставим pairing с кодом.

Практика

Поднимите мост

ESP32-C6 (готовый пример GATT) ↔ UART ↔ STM32; телефонное приложение-терминал BLE.

Пресеты

3 пресета: «репетиция» (лёгкий EQ), «концерт» (полный тракт), «пиццикато» (быстрый лимитер). Переключение — без щелчков.

Мини-проверка выхода

Пресеты переключаются со слышимой разницей и без артефактов; ученик объясняет, почему смена параметров привязана к границе блока.


Занятие 28. Рубеж фазы C: полный тракт на виолончели

Цель занятия: обучающийся демонстрирует полный тракт вживую и закрывает рубрику прошивки.

Разминка-вспоминание

Кумулятивный квиз фаз B–C (12 вопросов, включая по одному «старому» из фазы A — интервальное закрепление).

Формат рубежа

Живая демонстрация

Игра через настольный H743-процессор и через бортовой U585-блок; переключение пресетов с телефона.

Технический допрос

Наставник-«жюри» открывает любой файл прошивки и любую точку схемы: «объясните эту строку/этот номинал». Рубрика код-ревью из _index.md.

Сверка целей

Цель 5 закрывается только при: латентность < 10 мс (протокол), код-ревью ≥ 5/6, живой звук стабилен ≥ 10 минут игры.

Мини-проверка выхода

Протокол рубежа; список «хвостов» на фазу D (что дошлифовать до испытаний).