Published tables and closed forms, free of any instance so a test can assert the SHIPPED constant rather than a copy of it.
More...
|
| EqTimeConstants | eq_time_constants (TapeCurve curve, double speed_ips) noexcept |
| | The published time-constant table, selected by (curve, speed).
|
| double | eq_corner_hz (double tau_s) noexcept |
| | Corner frequency of a time constant, in Hz. f = 1 / (2π·t).
|
| double | eq_record_response_db (const EqTimeConstants &tc, double hz) noexcept |
| | The analog record (pre-emphasis) prototype H(s) = (1 + s·t₁)/(1 + s·t₂), in dB, normalized to 0 dB at kEqReferenceHz.
|
| double | eq_playback_response_db (const EqTimeConstants &tc, double hz) noexcept |
| | The playback (de-emphasis) network is the exact reciprocal of the record network, so its response is the negation.
|
| HeadGapGeometry | head_gap_geometry (double speed_ips) noexcept |
| | Gap widths by speed class.
|
| double | speed_m_per_s (double speed_ips) noexcept |
| | Tape speed in metres per second.
|
| double | gap_loss_magnitude (double hz, double gap_m, double speed_ips) noexcept |
| | Westmijze's reproduce gap loss: |sin(π·g/λ) / (π·g/λ)|, λ = v/f.
|
| double | gap_loss_db (double hz, double gap_m, double speed_ips) noexcept |
| double | gap_null_hz (double gap_m, double speed_ips) noexcept |
| | First extinction null, where λ = g: f = v / g.
|
| double | age_print_through_db (double age01) noexcept |
| double | age_bias_drift (double age01) noexcept |
| double | first_order_shelf_db (double corner_hz, double gain_linear, double hz, double sample_rate) noexcept |
| | Magnitude, in dB, of the REALIZED chardelay::FirstOrderShelf — the TPT one-pole shelf this module uses for both the bias shelf and the crosstalk tilt.
|
| ArchetypePreset | archetype_preset (TapeArchetype archetype) noexcept |
| | Baked defaults per §5 of the source spec.
|
| double | snap_speed_ips (TapeArchetype archetype, double requested_ips) noexcept |
| | Nearest legal speed for an archetype.
|
|
| constexpr std::array< double, 5 > | kSpeedsIps = {1.875, 3.75, 7.5, 15.0, 30.0} |
| | The halving speed ladder, in inches per second.
|
| constexpr double | kMetresPerInch = 0.0254 |
| | Inches to metres. Exact by definition of the international inch.
|
| constexpr double | kEqReferenceHz = 1000.0 |
| | The frequency every EQ curve in this module is normalized to be unity at.
|
| constexpr std::array< double, 3 > | kAgeAxis = {0.0, 0.5, 1.0} |
| | The reused kAgeAxis table drives spacing, hiss, chew and degrade, and kTapeAxis drives wow/flutter depth — all reused verbatim.
|
| constexpr std::array< double, 3 > | kAgePrintThroughDb = {-80.0, -55.0, -38.0} |
| | Storage print grows with age.
|
| constexpr std::array< double, 3 > | kAgeBiasDriftUnits = {0.0, 0.15, 0.4} |
| | An aging bias supply drifts toward OVER-bias — the documented failure direction, since oscillator components drift high more often than low.
|
Published tables and closed forms, free of any instance so a test can assert the SHIPPED constant rather than a copy of it.
Baked defaults per §5 of the source spec.
ampex_350_440 legal speeds {15, 7.5} [design parameter — the documented two-speed Ampex 350 configuration; 440-class descendants add 30 ips and are offered as a superset by selecting the Studer row instead]. studer_a800 {30, 15, 7.5} and its ≥40 dB crosstalk figure are PUBLISHED. cassette_deck is fixed at 1.875 ips by the cassette standard.
Crosstalk: −40 dB for the A800 is published (100 Hz–12 kHz). −38 dB for the Ampex class [dp, range −45 .. −30 dB] and −30 dB for cassette [dp, range −35 .. −22 dB] are honest design choices positioned against that one verified figure — no comparable published number surfaced for either. Cassette's narrower track pitch making crosstalk worse than open-reel is the documented direction; the magnitude is ours.
Starting age01: 0.2 for the Ampex class [dp, range 0.1–0.35 — "a machine
with some hours on it"], 0.05 for the Studer [dp, 0.0–0.15 — well-maintained flagship], 0.3 for cassette [dp, 0.2–0.5 — consumer-grade wear expectation].
| double pulp::signal::tape::first_order_shelf_db |
( |
double | corner_hz, |
|
|
double | gain_linear, |
|
|
double | hz, |
|
|
double | sample_rate ) |
|
inlinenoexcept |
Magnitude, in dB, of the REALIZED chardelay::FirstOrderShelf — the TPT one-pole shelf this module uses for both the bias shelf and the crosstalk tilt.
Stated in closed form rather than measured by rendering because two callers need it: the crosstalk stage normalizes its tilt at kEqReferenceHz using it, and the suite asserts the bias shelf against it. Deriving it from the analog prototype instead would leave a bilinear-warping error inside a tolerance, which is exactly the kind of slop that hides a real coefficient bug. From the TPT recurrence y = g·x + (1−g)·s, s' = 2g·x + (1−2g)·s: H_lp(z) = g(1 + z⁻¹) / (1 − (1−2g)z⁻¹), and the shelf is G + (1−G)·H_lp.
| double pulp::signal::tape::gap_loss_magnitude |
( |
double | hz, |
|
|
double | gap_m, |
|
|
double | speed_ips ) |
|
inlinenoexcept |
Westmijze's reproduce gap loss: |sin(π·g/λ) / (π·g/λ)|, λ = v/f.
Note this is exactly the gap term of the reused Wallace model, evaluated at THIS module's speed-class gap rather than at the delay tier's fixed 3 µm — the argument k·g/2 there is (2πf/v)·g/2 = π·g/λ here. Same published formula, a different head.
Gap widths by speed class.
Published typical RANGES; the specific value inside each range is a design parameter.
Studio 15/30 ips reproduce 3.5 µm [design parameter, range 2–5 µm — the documented professional reproduce-gap range], record 10 µm [dp, 8–13 µm]. Consumer reel 7.5/3.75 ips reproduce 5 µm [dp, 3–7 µm], record 12 µm [dp, 8–15 µm]. Cassette 1.875 ips reproduce 0.8 µm [dp, 0.5–1.2 µm — the documented sub-micron cassette reproduce-gap range], record 3 µm [dp, 2–5 µm]. Record gaps run wider than reproduce gaps throughout, which is convention rather than accident: the recording side has the lower resolution requirement.
| std::array<double, 3> pulp::signal::tape::kAgeAxis = {0.0, 0.5, 1.0} |
|
inlineconstexpr |
The reused kAgeAxis table drives spacing, hiss, chew and degrade, and kTapeAxis drives wow/flutter depth — all reused verbatim.
These two columns are new phenomena a feedback-loop delay has no way to model: print-through needs storage time, and bias drift is a maintenance state rather than a per-repeat one. [all design parameters]