LA-2A плагин: review модели и предложения по улучшению
Контекст: анализ DSP-формул плагина-эмулятора LA-2A. Цель документа — указать на расхождения с прототипом (Teletronix/UA LA-2A) и предложить замены, верифицированные по открытым источникам. Среда разработчика: JUCE 8 / Visual Studio 2022.
Каждый пункт помечен:
Verified — подтверждено документацией или измерениями (источник в конце).
Design choice — обоснованное архитектурное решение, не из единственного источника.
Estimate — типовой порядок, требует подгонки под референс.
Текущая модель (как есть)
Код:
12AX7: Ip = K·E₁^1.5·tanh(Vpk/Va), fixed-point relaxation 0.3,
cathode bypass 50µF (Vk fixed), gain ~34×
12BH7: cathode follower, та же модель, μ=17, relaxation 0.08, выход /15
OT: tanh saturation + LPF 30 kHz, DC-block
SC: анод 12AX7 → high-shelf emphasis 3 kHz (0/+2/+4/+6/+8/+10 dB)
→ full-wave rect → RMS 5ms → ratio 0.5/1.0
Opto: EL √envelope; CdS R = 10M·exp(-light·12); attack 12/8 ms, release 80/60 ms
FB: LDR + 1 MΩ делитель на входе 12AX7
PR: drive 0–8×
Критические расхождения
1.
Release time: нет long tail — главная потеря характера LA-2A
Источник: мануал Universal Audio LA-2A, цитата:
"Cells are selected which provide minimum attack time, and a release time which requires about 60 ms for 50% release, and then a gradual release over a period of 1 to 15 secs to the point of complete release."
Текущая модель
release 80/60 ms воспроизводит только быструю (50%) фазу и теряет медленный тепловой хвост CdS-фоторезистора, который и есть характерный «дыхательный» отклик LA-2A.
Замена — multi-τ release с тремя постоянными времени:
Код:
dR_fast/dt = (R_target - R_fast) / τ_fast τ_fast ≈ 10 ms
dR_med/dt = (R_target - R_med) / τ_med τ_med ≈ 150 ms
dR_slow/dt = (R_target - R_slow) / τ_slow τ_slow ≈ 2.5 s
R_effective = α·R_fast + β·R_med + γ·R_slow, α+β+γ = 1
(стартовые веса: 0.5 / 0.3 / 0.2; ❓ калибровать)
Опционально (полировка): state-dependent τ_slow — растёт с историей GR, до ~5–10 с (объясняет, почему UA пишет «1 to 15 secs» — диапазон зависит от программы). Это даёт именно тот эффект, что LA-2A «одинаково хорошо» работает на разных источниках.
В JUCE 8 — три каскадных
juce::dsp::FirstOrderTPTFilter или ручной one-pole в state-объекте T4B-ячейки.
2.
R37 Emphasis — фильтр работает в другую сторону
Источник: мануал UA LA-2A (стр. 9) и UA support article:
"The (R37) Emphasis... controls a shelf filter circuit in the compressor's sidechain input... Rotating the Emphasis control counter-clockwise increases filtering of the sidechain signal. The Emphasis filter gradually reduces the lower frequency content of the sidechain signal."
Контекст: R37 нужен был для компенсации FM pre-emphasis (+17 dB на 15 кГц), которой облучали LA-2A в broadcast-применении.
Текущая модель: high-shelf BOOST на 3 кГц с шагами 0/+2/+4/+6/+8/+10 dB.
Реальная схема: low-shelf CUT, режущий низа до –10 dB. Pivot frequency, насколько удаётся восстановить из обсуждений (mixanalog, GroupDIY) — около 1 кГц.
Спектральный наклон у обеих реализаций похож (sidechain становится чувствительнее к ВЧ), но:
- У low-shelf cut общий уровень sidechain падает → надо корректировать gain detector;
- Форма около pivot отличается → характер de-essing-эффекта не идентичен.
Замена:
Код:
sc_filtered = LowShelf(input, fc ≈ 1 kHz, gain = 0...-10 dB)
JUCE:
juce::dsp::IIR::Coefficients<float>::makeLowShelf(...).

Точные значения шагов аттенюации (0/-2/-4/-6/-8/-10 dB) — гипотеза, исходно соответствующая реальной кривой R37. Проверять по AB-сравнению с UAD/Waves CLA-2A.
3.
CdS — экспонента вместо power-law
Источник: стандартная физика фоторезисторов (CdS, Silonex/Clairex CL-505L, используемые в T4B):
R = K · E^(-γ), where γ ≈ 0.7…1.2
Текущая модель: R = 10M · exp(-light · 12) — экспонента откалибрована в одной точке. На сильной компрессии экспонента схлопывает R быстрее реального → компрессия становится жёстче, ratio растёт быстрее, чем у прототипа.
Замена:
Код:
R_inst = R_dark · max(L, L_eps)^(-γ)
R_dark ≈ 10 MΩ ✅ типично для CdS
γ ≈ 0.75 ❓ калибровать под T4B (диапазон 0.7–0.9)
L_eps малое для избежания /0
В коде на C++ —
std::pow(L, -gamma) либо аппроксимация через
exp(-gamma·log(L)) с быстрым log.
4.
EL panel — √ не учитывает порог зажигания
Источник: обсуждение T4B на GroupDIY (Joe-electro, Kenetek):
EL-панель в T4B запитана от sidechain до ~90 VAC peak, зажигается выше определённого напряжения, светимость растёт нелинейно.
Текущая модель: L = √(envelope) — даёт свечение при любом ненулевом сигнале.
Замена — threshold + power-law:
Код:
L = K_el · max(0, |V| - V_th)^n
V_th ≈ 60 V (в скейле sidechain) ❓ калибровать
n ≈ 2.5 ❓ типично 2–3 для EL
Эффект: при тихих сигналах ниже порога компрессия не включается вовсе — это соответствует ощущению LA-2A как «leveling amplifier», а не классического компрессора.
Важные расхождения (вторая очередь)
5.
Sidechain пропускает 6AQ5 driver tube
Источник: мануал UA LA-2A (стр. 11, Side-Chain Circuit) + обзор Gemtracks:
"The side-chain is comprised of a voltage amplifier, a pre-emphasis filter, and a driver stage which provides the voltage necessary to drive the electro-luminescent panel." "Two more tubes (12AX7 and 6AQ5) are in the sidechain and serve there as drivers for the electroluminescent foil."
Текущая модель: только
анод 12AX7 → emphasis, дальше детектор. Драйверная ступень на 6AQ5 (пентод) пропущена, а её нелинейность вносит свою окраску в sidechain.
Замена: добавить упрощённую модель 6AQ5 driver между фильтром и детектором. Минимально — мягкий нелинейный gain stage (asymmetric soft clip с порогом, имитирующий клиппинг пентода в sidechain). Полноценная Koren-модель пентода (требует параметров KG2, KP, EX) — over-engineering, можно ограничиться waveshaper-ом.
6.
12BH7 нельзя моделировать той же формулой, что 12AX7
Источник: опубликованные SPICE-модели (R. McLean DIY Audio thread, Leach form):
- 12AX7 Koren: μ=100, EX=1.4, KG1=1060, KP=600, KVB=300

- 12BH7A Leach: μ=16.64, perveance K=22.34E-6, exponent 1.5

Обратите внимание: для 12BH7 в открытом доступе
нет Koren-модели в той же форме, что для 12AX7 — есть Leach (старая 1.5-power) и 3F4 (расширенная). Использовать "ту же модель с μ=17" неправильно — у 12BH7 совсем другие KG1 и форма передаточной.
Варианты:
- Минимум: оставить Child-Langmuir 1.5 для 12BH7, но с perveance-коэффициентом, соответствующим Leach-модели (≈22.34E-6, у 12AX7 коэффициент существенно меньше — там «остренькая» лампа).
- Лучше: снять параметры Koren из datasheet 12BH7 (RCA / GE) через CurveCaptor (есть в open source) или через ручной фит в Excel/MATLAB. Это разовая работа на час.
- Идеально: 12BH7 в LA-2A работает катодным повторителем — там точная форма передаточной не критична, важен корректный output impedance и небольшая нелинейность. Можно ограничиться вариантом 1 + правильное вычисление Vk через корректный Rk.
7.
Fixed-point relaxation 0.08 → Newton-Raphson
Проблема: relaxation 0.08 для 12BH7 — симптом плохой сходимости из-за сильной локальной ОС в катодном повторителе. Это означает 30+ итераций на сэмпл для приличной точности → ненужная нагрузка на CPU.
Замена: Newton-Raphson по неявной системе:
Код:
// Для 12BH7 cathode follower (ищем Vk):
// g(Vk) = Vk - Rk * Ip(Vin - Vk, Vsupply - Vk)
// g'(Vk) = 1 - Rk * (dIp/dVgk * (-1) + dIp/dVp * (-1))
// = 1 + Rk * (dIp/dVgk + dIp/dVp)
float Vk = Vk_prev; // warm start с прошлого сэмпла
for (int i = 0; i < MAX_ITER; ++i) {
float Ip = computeIp(Vin - Vk, Vsupply - Vk);
float g = Vk - Rk * Ip;
if (std::abs(g) < EPS) break;
float dIp_dVgk = ...; // analytical derivative
float dIp_dVp = ...;
float gp = 1.0f + Rk * (dIp_dVgk + dIp_dVp);
Vk -= g / gp;
}
Сходимость: 2–4 итерации до 1e-6 residual вместо 30+.
Safeguard: при отсутствии сходимости за 6 шагов → fallback на bisection в
[Vk_min, Vk_max].
В JUCE — стандартные
<cmath> функции; для оптимизации можно
juce::FastMathApproximations для exp/log, но обычно std-версии достаточно (это всё ещё ~5% одного ядра).
8.
Output transformer — tanh + LPF 30 kHz слишком прозрачен
Источник: реальный OT в LA-2A — UTC A-24 (или HA-133, Stancor WF-34, Sowter 1010 как замены), step-down. Frequency response типового 30 Hz – 20 kHz ±1 dB, с лёгким HF resonance из-за leakage L и winding C.
Что упускает текущая модель:
- HF resonance (≈18–22 kHz, Q≈1) — характерный «открытый» верх.
- LF magnetic saturation — magnetizing current ∝ 1/f, на низких частотах сердечник насыщается быстрее → 3-я гармоника на басу. Это половина того, что делает LA-2A «жирным».
- Асимметричная нелинейность — даёт 2-ю гармонику. Чистый tanh симметричен, рождает только odd-order harmonics.
Замена:
Код:
1. HF секция: biquad LCR (juce::dsp::IIR), резонанс ~20 kHz Q≈1
2. LF saturation: high-shelf boost +6 dB ниже 100 Hz перед нелинейностью,
high-shelf cut после неё (имитация 1/f magnetizing)
3. Asymmetric softclip: y = softclip(x + 0.04·|x|)
или y = (x + 0.5·x²·ε)/(1+|x|)
Полноценная Jiles-Atherton модель сердечника overkill для VST.
Минор / nice-to-have
9.
Gain staging — убрать /15
выход 12BH7 /15 смешивает три разных вещи:
- Gain катодного повторителя (≈ μ/(μ+1) ≈ 0.94)
- Step-down ratio output transformer
- Внутреннюю нормировку к audio float
Разделить на явные блоки в коде:
Код:
[12AX7 stage] → Av_voltage ≈ 34
[coupling cap] → HPF ~3 Hz
[12BH7 follower] → Av ≈ 0.94
[OT step-down] → ×0.25 (1:4 ratio, ❓ зависит от модели OT)
[output trim] → калибровочная константа k_norm
Подставлять
k_norm так, чтобы при PR=0 plugin был bypass-friendly (unity gain).
10.
Sidechain detector — вместо RMS 5ms схемная топология
Реальный sidechain LA-2A после rectifier — конденсатор, заряжающийся через низкое сопротивление и разряжающийся через высокое. Это даёт fast attack / slow discharge без явного envelope follower:
Код:
sc_after_rect → cap_charge (Rc=низкое, Rd=высокое, C=1µF)
RMS 5ms — абстракция, дающая похожий, но не идентичный результат. Особенно отличие заметно на транзиентах.
11.
Compression ratio 0.5/1.0
Источник: обсуждения на Gearspace + UA Webzine:
- Compress mode: 3:1 to 4:1, soft knee, program-dependent
- Limit mode: ∞:1 (UA spec) / реально ~10:1 при насыщении CdS
Текущие коэффициенты
0.5/1.0 могут соответствовать этим ratio через нелинейность gain reduction — это надо проверить static input/output curve plugin'а в режиме compress vs limit. Если кривые не совпадают с измерениями реального LA-2A — пересмотреть mapping.
Приоритизация для итеративного релиза
| Приоритет | Что | Эффект | Сложность |
|---|
| P0 | Multi-τ release с τ_slow ≈ 2.5 s | Без этого это не LA-2A | Низкая (3 one-pole) |
| P0 | CdS power-law вместо exp | Корректная форма GR | Низкая (1 строка) |
| P0 | R37 emphasis: low-shelf cut вместо high-shelf boost | Соответствие схеме | Низкая (biquad) |
| P1 | EL panel threshold + V^n | Тихие сигналы не давят compression | Низкая |
| P1 | OT с LF saturation + HF resonance | Жирный low-end, открытый top | Средняя |
| P1 | Newton solver для 12BH7 | CPU экономия 5–10× | Средняя |
| P2 | 6AQ5 sidechain driver | Дополнительная окраска | Низкая (waveshaper) |
| P2 | 12BH7 — отдельные параметры | Корректность модели | Средняя (нужен фит) |
| P3 | Cap-discharge sidechain detector | Естественные транзиенты | Низкая |
| P3 | Asymmetric OT softclip | 2-я гармоника | Низкая |
| P3 | Явный gain staging (убрать /15) | Maintainability | Низкая |
Верификация изменений
Минимальный test suite, чтобы убедиться, что изменения
приближают к прототипу:
- Static GR curve — sine 1 kHz @ +6 dBu вход, sweep amplitude, замерять output. Сравнивать с измерениями реального LA-2A или UAD-эмуляции (есть много обзоров).
- Release impulse response — короткий burst → выкл. → измерить кривую восстановления GR. Должна быть характерная двухступенчатая (быстрая до 50%, медленная до полного восстановления).
- THD spectrum на +4 dBu и +18 dBu — наличие 2-й и 3-й гармоник в правильной пропорции.
- Frequency response sidechain для разных позиций R37 — проверить, что это shelf cut на низах, не boost на верхах.
Источники
Disclaimer
Все значения, помеченные

, — типовые для соответствующих компонентов и должны быть откалиброваны под референсное звучание (UAD, Waves CLA-2A или, идеально, измерения реального юнита). Документ не претендует на bit-exact эмуляцию — это roadmap, который приведёт модель ближе к прототипу по слышимым характеристикам.