Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/CIRCUIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ V1a part:
| V1a | 12AX7 | p1a, g1a, k1a | |
| R1 | 2.7 kΩ | k1a – gnd | |
| C1 | 0.68 µF | k1a – gnd | Full cathode bypass |
| C2 | 100 pF | p1a – k1a | V1a plate–cathode (drawing iss. 4; added D-062, was open item O8) |
| R4 | 100 kΩ | bpA – p1a | Plate load; bpA from supply B7 |

There is no junction between V1a and V1b: p1a is an internal node of B12 (the J1 junction was
Expand Down Expand Up @@ -253,7 +254,7 @@ Regenerate with `python3 reference/spice/spice_tools.py` after any netlist chang
| O5 | NFB tap | 16 Ω output with the speaker load (D-059) | Feedback amount if taken from another tap |
| O6 | Low input | Not modelled | Feature only |
| O7 | OT half-primary orientation | Blue–White (15.36 Ω) on the pA side (V4/V5) | ±0.6 Ω winding asymmetry, about ±40 mV DC per side |
| O8 | C2 100 pF V1a plate–cathode (drawing 2203 STD Preamp iss. 4) | Not in the netlist (found 2026-10-15) | −0.3 dB at 5 kHz, −0.7 … −0.9 dB at 10 kHz into V1b (SPICE study) |
| O8 | C2 100 pF V1a plate–cathode | Resolved: in the netlist since D-062 | −0.3 dB at 5 kHz, −0.7 … −0.9 dB at 10 kHz into V1b (SPICE study) |
| A1 | HT source 505 V / 100 Ω | Assumed | B+ level and sag |
| A2 | OT values | Hammond 1750U replacement datasheet, primary inductance fitted (§3, D-023) | Power, LF/HF response, feedback |
| A3 | Choke 5 H / 115 Ω | Hammond 194F replacement datasheet; L specified at 120 mA DC, the amp runs it at ≈ 27 mA (D-024) | Screen node dynamics, supply DC |
Expand Down
11 changes: 11 additions & 0 deletions docs/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1043,3 +1043,14 @@ at 0 V. Above +20 V, P = Vpk within 0.1 V (DC operating point unchanged).
Consequences: engine diagnostic: HOT DI 0 power-amp failures at 8x and 16x; CRUNCH / DRIVE unchanged (−218 … −224 dB vs
the previous engine), HOT differs by −35 … −37 dB. tests/data EL34 sweeps regenerated; the pentode test asserts the new
below-cathode behaviour. SPICE references with the power amp are re-rendered.

## D-062 C2 100 pF (V1a plate–cathode) added to the netlist (reference model change)
Date: 2026-10-18 · Status: accepted (owner: "add C2 to the netlist")
Context: the drawing (2203 STD Preamp iss. 4) shows C2 100 pF from V1a's plate to its cathode; it was missing from the
transcription (open item O8, found 2026-10-15). SPICE study: −0.3 dB at 5 kHz, −0.7 … −0.9 dB at 10 kHz into V1b.
Decision: `C2 p1a k1a 100p` in the netlist (B12 partition). The engine adds it to V1a's plate–cathode capacitance port
(`cpk1a_` = Cpk + C2 in `Preamp` and `StageV1aV1b`): the same two nodes, so the parallel combination is exact.
Consequences: DC unchanged. Every SPICE reference containing V1a is re-rendered; earlier reports are without C2.
Also found: the standalone blocks' default supply voltages (Preamp, StageV1aV1b, StageV2aV2b, StageV2aV2bToneStack,
PhaseInverter, PowerStage) were still the pre-D-058 values (bpA 389.35, bpX 402.34, ct 488.71, nScr 485.65 V); updated to
CIRCUIT.md §5 (391.92, 405.00, 491.35, 488.88 V) with the block DC fixtures (the full amp sets its supplies itself).
7 changes: 7 additions & 0 deletions docs/PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,13 @@ Notes:
model) and are now rendered once more at RELTOL 1e-7 by `render_spice` (as the M3 cascade), noted in the reports. Plugin
model check: Full 2x HOT −24.2 dB (PASS), unseen −20.8 dB, 94 first-solve failures (2 unrescued) over 28 runs, nearly all in
the extreme validation settings (presets: 0 / 0 / 2); Half 2x HOT −18.9 dB. Presence knob jump −62.9 dB; null test 26 / 26.
- Owner 2026-10-18: add C2 to the netlist (D-062). Plan: `C2 p1a k1a 100p`; the engine folds it into V1a's Cpk port (Cpk + C2,
B1234 and B12: the same nodes, exact); B12 partition; re-verify b12 (DEFAULT, VOL0.2, VOL1.0), b1234, knob jumps b12 / b1234,
M4 acceptance at 768 kHz and 384 kHz exact J4 + HOT, plugin model check (Full 2x), null test, CPU.
- D-062 done. b12 / b1234 first failed on DC (≈ 0.65 %): the standalone blocks' default supplies were pre-D-058; fixed
(engine headers + block DC fixtures). Then: b12 DEFAULT / VOL0.2 / VOL1.0 105 / 106 / 106 PASS, b1234 119 PASS, b3 87 PASS,
b34 94 PASS (0 FAIL each); knob jumps b12 −55.9 dB, b1234 −39.1 … −55.1 dB, b34 −53.1 … −67.6 dB; M4 full acceptance 107
PASS (768 kHz and 384 kHz exact J4); HOT 20 PASS / 1 FAIL (2 rescued first-solves, as after D-061); null test 26 / 26.

## Questions for the owner
_(Claude Code: add questions here and also ask them in the session.)_
Expand Down
2 changes: 1 addition & 1 deletion engine/include/amp2203/PhaseInverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace amp2203 {
/// (g3b−k3, p3b−k3). Presence is smoothed (SPEC §6.2); R_th4 follows the preamp's knobs.
class PhaseInverter {
public:
static constexpr double kSupplyBpX = 402.335999; // CIRCUIT.md §5
static constexpr double kSupplyBpX = 404.998185; // CIRCUIT.md §5
static constexpr int kParamUpdateInterval = 32;
static constexpr int kNodes = 8, kElements = 18, kRootPorts = 4;

Expand Down
2 changes: 1 addition & 1 deletion engine/include/amp2203/PowerStage.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace amp2203 {
/// resistances as one coupled element, the load); root ports (g, s, p) of each pair against ground.
class PowerStage {
public:
static constexpr double kSupplyCt = 488.708422, kSupplyScreen = 485.649287; // CIRCUIT.md §5
static constexpr double kSupplyCt = 491.346637, kSupplyScreen = 488.880467; // CIRCUIT.md §5
/// J5 Thevenin resistances (harness/junctions.py j5a / j5b, provisional; CIRCUIT.md §4).
static constexpr double kRthA = 58067.6, kRthB = 56937.4;
static constexpr int kNodes = 17, kElements = 31, kRootPorts = 6;
Expand Down
9 changes: 5 additions & 4 deletions engine/include/amp2203/Preamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ namespace amp2203 {
/// while one moves, the matrices are recomputed every kParamUpdateInterval samples.
class Preamp {
public:
static constexpr double kSupplyBpA = 389.349603; // CIRCUIT.md §5; B7 sets them in M4
static constexpr double kSupplyBpX = 402.335999;
static constexpr double kSupplyBpA = 391.921506; // CIRCUIT.md §5 (after D-058); B7 sets them in M4
static constexpr double kSupplyBpX = 404.998185;
static constexpr int kParamUpdateInterval = 128; // samples between matrix updates while a knob moves (D-057; was 32)
static constexpr int kNodes = 20, kElements = 38, kRootPorts = 9; // 8 triode ports + the load at y

// Component values, CIRCUIT.md §1 and tubes.lib (SI units).
static constexpr double R1 = 2.7e3, R3 = 68e3, R4 = 100e3, R5 = 470e3, R6 = 10e3, R7 = 100e3;
static constexpr double C1 = 0.68e-6, C3 = 0.022e-6, C4 = 470e-12, C5 = 1e-9, VR1 = 1e6;
static constexpr double C1 = 0.68e-6, C2 = 100e-12, C3 = 0.022e-6, C4 = 470e-12, C5 = 1e-9, VR1 = 1e6;
static constexpr double R9 = 820.0, R10 = 470e3, R11 = 470e3, R12 = 100e3, R13 = 100e3, R15 = 33e3;
static constexpr double C7 = 0.022e-6, C8 = 470e-12, C10 = 470e-12, C11 = 0.022e-6, C12 = 0.022e-6;
static constexpr double VR3 = 220e3, VR4 = 22e3, VR5 = 1e6, VR2 = 1e6;
Expand Down Expand Up @@ -114,7 +114,8 @@ class Preamp {
chowdsp::wdft::ResistorT<double> vr1b_{1.0};
chowdsp::wdft::ResistorT<double> r6_{R6};
chowdsp::wdft::ResistiveVoltageSourceT<double> src7_{R7};
detail::DcCapacitor cgk1a_{Cgk}, cgp1a_{Cgp}, cpk1a_{Cpk}, cgk1b_{Cgk}, cgp1b_{Cgp}, cpk1b_{Cpk};
// cpk1a_: V1a's Cpk in parallel with C2 (100 pF plate–cathode, D-062): one p1a – k1a port
detail::DcCapacitor cgk1a_{Cgk}, cgp1a_{Cgp}, cpk1a_{Cpk + C2}, cgk1b_{Cgk}, cgp1b_{Cgp}, cpk1b_{Cpk};
// B3 elements
detail::DcCapacitor c7_{C7};
chowdsp::wdft::ResistorT<double> r10_{R10};
Expand Down
7 changes: 4 additions & 3 deletions engine/include/amp2203/StageV1aV1b.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ namespace amp2203 {
class StageV1aV1b {
public:
/// Supply node bpA at the F operating point (CIRCUIT.md §5, as the B12 testbench); B7 sets it in M4.
static constexpr double kSupplyBpA = 389.349603;
static constexpr double kSupplyBpA = 391.921506;
static constexpr int kParamUpdateInterval = 32;
static constexpr int kNodes = 8, kElements = 15, kRootPorts = 4;

// Component values, CIRCUIT.md §1 B12 and tubes.lib (SI units).
static constexpr double R1 = 2.7e3, R3 = 68e3, R4 = 100e3, R5 = 470e3, R6 = 10e3, R7 = 100e3;
static constexpr double C1 = 0.68e-6, C3 = 0.022e-6, C4 = 470e-12, C5 = 1e-9, VR1 = 1e6;
static constexpr double C1 = 0.68e-6, C2 = 100e-12, C3 = 0.022e-6, C4 = 470e-12, C5 = 1e-9, VR1 = 1e6;
static constexpr double Cgk = 2.3e-12, Cgp = 2.4e-12, Cpk = 0.9e-12;

StageV1aV1b();
Expand Down Expand Up @@ -90,7 +90,8 @@ class StageV1aV1b {
chowdsp::wdft::ResistorT<double> vr1b_{1.0};
chowdsp::wdft::ResistorT<double> r6_{R6};
chowdsp::wdft::ResistiveVoltageSourceT<double> src7_{R7};
detail::DcCapacitor cgk1a_{Cgk}, cgp1a_{Cgp}, cpk1a_{Cpk}, cgk1b_{Cgk}, cgp1b_{Cgp}, cpk1b_{Cpk};
// cpk1a_: V1a's Cpk in parallel with C2 (100 pF plate–cathode, D-062): one p1a – k1a port
detail::DcCapacitor cgk1a_{Cgk}, cgp1a_{Cgp}, cpk1a_{Cpk + C2}, cgk1b_{Cgk}, cgp1b_{Cgp}, cpk1b_{Cpk};

auto elements() noexcept {
return std::tie(vin_, k1a_, src4_, c3_, r5c4_, c5vr1a_, vr1b_, r6_, src7_, cgk1a_, cgp1a_, cpk1a_, cgk1b_,
Expand Down
2 changes: 1 addition & 1 deletion engine/include/amp2203/StageV2aV2b.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class StageV2aV2b {
/// J2 Thevenin resistance (harness/junctions.py j2, |Z(1 kHz)| of B12 at p1b; DECISIONS D-018).
static constexpr double kRth2 = 89732.8;
/// Supply node bpX at the F operating point (CIRCUIT.md §5, as the B3 testbench); B7 sets it in M4.
static constexpr double kSupplyBpX = 402.335999;
static constexpr double kSupplyBpX = 404.998185;
static constexpr int kNodes = 6, kElements = 13, kRootPorts = 4;

// Component values, CIRCUIT.md §1 B3 and tubes.lib (SI units).
Expand Down
2 changes: 1 addition & 1 deletion engine/include/amp2203/StageV2aV2bToneStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace amp2203 {
class StageV2aV2bToneStack {
public:
static constexpr double kRth2 = 89732.8; // harness/junctions.py j2 (D-018)
static constexpr double kSupplyBpX = 402.335999; // CIRCUIT.md §5; B7 sets it in M4
static constexpr double kSupplyBpX = 404.998185; // CIRCUIT.md §5; B7 sets it in M4
static constexpr int kParamUpdateInterval = 32;
static constexpr int kNodes = 13, kElements = 24, kRootPorts = 4;

Expand Down
Loading
Loading