Автоматический DSP-премастеринг для аудиокассет на C++

от автора

От ностальгии к алгоритмам

Помните мою прошлую статью, где мы гоняли один и тот же современный альбом на четырёх типах лент через трёхголовочную Kenwood KX-1100G? Тот эксперимент показал: аналоговый звук жив, но характер цифрового мастера и точность калибровки деки часто влияют на результат сильнее, чем разница между Type I и Type IV.

За кадром осталась другая проблема. Современный стриминговый релиз — это −8…−10 LUFS integrated, True Peak на 0 dBFS и выше, плотный верх, широкий стереобас и brickwall-лимитирование. Записать такой файл на ленту «как есть» — получить грязный верх, нестабильный уровень, клиппинг на записи и бас, который «гуляет» между каналами из‑за crosstalk.

После десятка вечеров с ручной подгонкой gain, bias и лимитеров под каждый трек я устал повторять одну и ту же работу. Так появился CassetteMaster — десктопное приложение на C++20 / JUCE 8, которое автоматически готовит цифровой звук к записи на физическую кассету.

Это не «ленточный эффект с шипением» и не винтажный дисторшн. Задача программы — сохранить digital fidelity: убрать только то, что физически конфликтует с магнитной лентой.

В чём физический конфликт цифры и ленты

Компакт-кассета работает в жёстких физических пределах ушедшей эпохи:

  • MOL/SOL — ограниченный выходной уровень на высоких частотах;

  • Self-erasure — избыточные ВЧ «стирают» соседние участки дорожки;

  • Crosstalk ~30–40 dB между каналами;

  • Head gap + 4.76 cm/s — естественный спад ВЧ к 14–16 kHz;

  • Wow/flutter, bias, azimuth — механические ограничения транспорта.

Современный мастеринг создаётся под стриминг и смартфоны. Магнитная лента — нет.

Параметр цифрового мастера

Ограничение ленты (Type I / II)

Что происходит при прямой записи

Громкость −8…−10 LUFS

Насыщение магнитного слоя (MOL)

Глухой, грязный дисторшн

Яркий, пережатый верх

Self-erasure

Лента «стирает» сама себя на ВЧ

Широкий стереобас

Crosstalk

Фазовые проблемы, «гуляющий» бас

True Peak ≥ 0 dBFS

Ограничение по пикам

Жёсткий аналоговый клиппинг

Наша задача: не сделать lo-fi-плагин, а наоборот — сохранить цифровую точность, сняв исключительно то, что сломает запись на конкретной ленте и деке.

Интерфейс: три шага от FLAC до WAV

Workflow простой:

  1. Add music — drag & drop файла или папки (WAV, FLAC, AIFF, OGG).

  2. Prepare — офлайн-анализ и автоматический мастеринг в фоновом потоке.

  3. Export — 32-bit float WAV, опционально с калибровочными тонами в начале.

Тип ленты (Type I / II / IV) и длина кассеты (C60/C90/C120) задаются до обработки. Дека в текущем UI зафиксирована на Kenwood KX-1100G — той самой, с которой мы проводили эксперимент.

Кнопки Before / After включают A/B-предпрослушивание фрагмента (~45 s). Waveform показывает LUFS, True Peak и маркеры обработки: limiter, HF reduction, de-esser, clip warning.

Архитектура: офлайн-процессор, а не realtime-эффект

CassetteMaster — легковесный офлайн-процессор. Вся тяжёлая работа идёт в worker thread, UI не блокируется. Ядро — статическая библиотека cassette_core, общая для GUI-приложения, опционального CassetteBurner и VST3/AU-плагина.

Поток при нажатии Prepare

  1. AudioFileLoader загружает файл в AudioBuffer<float>.

  2. EssentiaAnalyzer::extractFeatures строит структуру AudioFeatures.

  3. CassetteProfile::forRecording(KenwoodKX1100G, tapeType) задаёт потолки LUFS/TP/HF.

  4. AdaptiveMasteringProcessor::process вызывает планировщик, опционально ODG loop, затем CassetteAutoMaster::processTrack.

  5. ProcessingDiagnostics рисует маркеры на waveform и пишет лог.

  6. UI обновляет панель «After» и статус Ready to export.

Шаг 1. Офлайн-анализ

Когда вы перетаскиваете FLAC в окно, движок вычисляет карту параметров — не для красоты метров, а для принятия решений планировщиком.

Loudness и пики: integrated LUFS (EBU R128-подобный LoudnessMeter), True Peak с oversampling (TruePeakMeter), crest factor, loudness range.

Спектр: доли энергии LF/MF/HF, stereo correlation, LF stereo correlation, ширина стереобазы.

Психоакустика (PsychoacousticMetrics, 24 полосы Bark):

  • roughness — «грубость» верха (модуляция 20–300 Hz);

  • sharpness (DIN 45692);

  • hfAboveMaskingDb — энергия ВЧ выше порога маскирования;

  • streamingRingingIndex — «звонкость» стримингового мастера;

  • hfTamerStrength — рекомендуемая глубина HF prep (0…1).

Essentia подключается опционально (CASSETTE_BUILD_ESSENTIA); без неё работает встроенный fallback по BS.1770.

Шаг 2. Умный планировщик

Приложение не обрабатывает все треки одинаково. Класс CassetteMasteringPlanner — сердце автоматизации.

Сначала вычисляется Tape Threat Score (0…1): взвешенная сумма превышений LUFS/TP над потолком профиля, roughness, sharpness, HF above masking, ringing index, низкой LF correlation, высокого HF energy ratio, клиппинга.

Для Kenwood KX-1100G score умножается на (1 − autoPrepRelief), где autoPrepRelief = 0.18 — планировщик менее агрессивен, чем для «голых» профилей IEC.

Шаг 3. Цепочка DSP

Реализация — CassetteAutoMaster::processTrack. Сигнал проходит через кастомный граф обработки:

Инфра-HPF (~25 Hz)

Отрезаем суб-низкие частоты, которые дека всё равно не запишет, но которые бесполезно насыщают магнитный слой. В режиме hot/clean отключён — на peaky материале после HPF limiter давал заметное проседание LUFS.

Side LF mono

Переводим сигнал в Mid/Side. В канале Side отрезаем всё ниже ~120 Hz. Бас становится монофоническим — меньше crosstalk на кассетной головке.

Adaptive HF Tamer

Динамический эквалайзер в полосе 4.5–14 kHz. Если наступает критический пик энергии на ВЧ, который вызовет self-erasure, tamer мягко «присаживает» эту частоту. На спокойном материале прозрачен.

Roughness De-Esser

Борется со специфическим «звоном» цифровых лимитеров — без глобального low-pass.

True Peak Limiter + Post-chain loudness trim

Integrated LUFS и True Peak — два разных ограничения. На кассете важны оба.

Для hot/clean, когда горячие и LUFS, и TP, берётся менее агрессивный из двух gain — чтобы limiter не «съедал» лишние LU.

После limiter/HF chain измеряется LUFS. Если источник был «горячим», но выход ниже cap — makeup (до +4.5 dB). Если выше cap — лёгкий cut. Для тихих источников boost не применяется.

Итеративный цикл до 4 проходов с re-limit только на full prep path.

Физика → DSP

Физическое явление

Ответ CassetteMaster

Насыщение ленты (Jiles–Atherton)

Gain staging к maxIntegratedLUFS, soft clip только Type I / lo-fi

Self-erasure / HF bias

Adaptive HF Tamer, Side HF cut

Crosstalk

Side LF mono (HPF Side < 120–150 Hz)

Head gap + 4.76 cm/s

Side HF cut по профилю

Inter-sample peaks

True Peak meter + limiter

Профили ленты и Kenwood KX-1100G

Профили заданы в CassetteProfile. Для Kenwood — applyKenwoodKX1100GTuning: без эмуляции Dolby HX-Pro, расширенный HF headroom, повышенный biasReductionOnHf на Type II.

Kenwood +

max LUFS

TP ceiling

Type I

−11.0

−0.8 dBFS

Type II

−11.5

−0.5 dBFS

Type IV

−11.0

−0.2 dBFS

Mixtape: папка → Side A / Side B

Перетащите папку с альбомом — программа сканирует аудио, сортирует имена natural sort, считает длительность с gap 2 s между треками.

Если материал не помещается на C60/C90/C120 — greedy packing на несколько кассет:

Каждый трек проходит per-track mastering, затем сводится на timeline стороны.

Тест на живом материале: Charli XCX

Для регрессии DSP — fixture прямо в CI: 90-секундный фрагмент Charli XCX — SS26 Rock Music.

Before

After

Integrated LUFS

−9.86

−10.80

True Peak

+0.15 dBFS

−0.80 dBTP

Plan

KX-1100G hot/clean

Планировщик корректно выбрал hot/clean — только level + limiter, без HF prep. Результат укладывается в cap Kenwood Type I (−11 LUFS), TP строго на ceiling.

Почему это важно: в ранних версиях тот же трек «перегашивался» до ~−14 LUFS — limiter и infra-HPF работали в связке и съедали 3–4 dB энергии без необходимости. Новая архитектура устранила перегас, сохранив безопасные пики.

Заключение

CassetteMaster — специализированный tape-oriented mastering, а не универсальный loudness maximizer. Программа сочетает:

  • объективный и психоакустический анализ стриминговых мастеров;

  • автоматический выбор глубины обработки — от «только level + TP» до полного HF/LF prep;

  • профили ленты и деки с физически мотивированными потолками LUFS/TP/HF;

  • прозрачный DSP с post-chain loudness trim и защитой от двойного перегаса;

  • mixtape workflow для альбомов и папок;

  • verifiable quality через автотесты и fixture реального pop-трека.

Спасибо за чтение!

Денис Попков

KMP разработчик в «Black Bricks»

Если вы нашли неточности/ошибки в статье или просто хотите дополнить её своим мнением — то прошу в комментарии! Или можете написать мне в Telegram. Также подписывайтесь на мой ТГ-канал. Там пишу про свои будни, кассеты и винил :>

ссылка на оригинал статьи https://habr.com/ru/articles/1046213/