Physics-based speaker + cabinet + microphone emulator. More...
#include <speaker_cabinet.hpp>
Classes | |
| struct | BreakupMode |
| One DIMENSIONLESS breakup mode: a ratio to the archetype's anchor frequency plus a Q and a gain. More... | |
Public Member Functions | |
| void | prepare (double sample_rate) |
| Recompute every corner coefficient for a new sample rate. No allocation. | |
| void | set_driver_archetype (int index) |
| void | set_box_type (SpeakerBoxType type) |
| void | set_box_volume_l (double litres) |
| void | set_resonance_trim_semitones (double semitones) |
| void | set_q_resonance (double q) |
| Override the computed box Qtc. | |
| void | set_cone_breakup_amount (double percent) |
| void | set_treble_rolloff_hz (double hz) |
| void | set_drive_db (double db) |
| void | set_compression_amount (double percent) |
| void | set_mic_distance_cm (double cm) |
| void | set_mic_position_pct (double percent) |
| void | set_mic_axis_deg (double degrees) |
| void | set_diffraction_amount (double percent) |
| void | set_output_trim_db (double db) |
| SampleType | process (SampleType input) |
| void | process (const SampleType *in, SampleType *out, int n) |
| void | reset () |
| Zero every filter and excursion state. | |
| int | latency_samples () const |
| The chain is a cascade of minimum-phase filters with no block buffering and no oversampler, so nothing is held back. | |
| double | worst_case_gain () const |
| Sum of per-stage peak magnitudes across the parameter space. | |
| double | compliance_ratio () const |
| Compliance ratio alpha = Vas / Vb. | |
| double | resonance_fc_hz () const |
| Box resonance fc = fs * sqrt(1 + alpha), shifted by the voicing trim. | |
| double | resonance_q () const |
| Box Qtc = Qts * sqrt(1 + alpha), unless overridden. | |
| double | resonance_peak_db () const |
| Peak magnitude of the second-order high-pass at the resonance, in dB: Q / sqrt(1 - 1/(4 Q^2)). | |
| double | resonance_peak_hz () const |
| Frequency of that peak: fc / sqrt(1 - 1/(2 Q^2)). | |
| double | baffle_step_hz () const |
| Baffle-step transition c / (pi * W). | |
| double | ripple_hz () const |
| First edge-diffraction ripple c / (2 * d_edge). | |
| double | dipole_hz () const |
| Open-back dipole corner c / (2 * D). | |
| double | breakup_mode_hz (int index) const |
| Centre of breakup mode index, anchored on the archetype. | |
| double | offaxis_corner_hz () const |
| Off-axis corner f_on * (1 - k_ax * sin(angle)). | |
| double | proximity_gain_db () const |
| Proximity shelf gain, boost-only by construction and clamped at the ceiling: k_prox * (1/d - 1/d_ref) in dB. | |
| double | presence_shelf_db () const |
| Cap-to-cone traverse shelf, lerped bright-to-dark. | |
| double | air_loss_db () const |
| Air/distance HF trim, in dB (negative), scaling with distance. | |
| double | inductance_magnitude_db (double hz) const |
| Exact magnitude of the voice-coil inductance stage ALONE, in dB, from the coefficients currently in force. | |
| double | bl_beta () const |
| BL(x) falloff coefficient beta actually in force. | |
| double | cms_gamma () const |
| Cms(x) stiffening coefficient gamma actually in force. | |
| double | excursion () const |
| Normalized excursion produced by the most recent sample. | |
| double | dynamic_fc_hz () const |
| The resonance cutoff currently in force, including Cms stiffening. | |
| int | archetype_index () const |
| SpeakerBoxType | box_type () const |
| double | sample_rate () const |
Static Public Member Functions | |
| static const SpeakerDriverArchetype & | archetype (int index) |
| [design parameter] table; see SpeakerDriverArchetype and the model scope above. | |
| static const BreakupMode & | breakup_mode (int index) |
| [design parameter] shape. | |
Static Public Attributes | |
| static constexpr int | kArchetypeCount = 5 |
| static constexpr double | kSpeedOfSoundMs = 343.0 |
| Speed of sound in air at ~20 C, standard atmospheric value. | |
| static constexpr double | kBoxVolumeLDefault = 28.0 |
| Sealed-box internal volume. [dp, default 28 L, range 5..150 L]. | |
| static constexpr double | kBoxVolumeLMin = 5.0 |
| static constexpr double | kBoxVolumeLMax = 150.0 |
| static constexpr double | kResonanceTrimSemitonesMin = -12.0 |
| Voicing shift of the computed resonance. [dp, default 0, range -12..+12]. | |
| static constexpr double | kResonanceTrimSemitonesMax = 12.0 |
| static constexpr double | kQResonanceMin = 0.4 |
| Box Qtc override. | |
| static constexpr double | kQResonanceMax = 2.0 |
| static constexpr double | kConeBreakupAmountDefault = 100.0 |
| Depth of the cone-breakup bank. [dp, default 100 %, range 0..100 %]. | |
| static constexpr double | kTrebleRolloffHzDefault = 4000.0 |
| Voice-coil-inductance corner. [dp, default 4000 Hz, range 1500..8000 Hz]. | |
| static constexpr double | kTrebleRolloffHzMin = 1500.0 |
| static constexpr double | kTrebleRolloffHzMax = 8000.0 |
| static constexpr double | kSemiInductanceDefault = 0.25 |
| Leach semi-inductance blend and its shelf floor: the fraction of the un-rolled signal mixed back through a high shelf to give the "leaky", gentler-than-6-dB/oct HF decay real motors measure. | |
| static constexpr double | kSemiInductanceMin = 0.0 |
| static constexpr double | kSemiInductanceMax = 1.0 |
| static constexpr double | kSemiInductanceShelfDb = -12.0 |
| static constexpr double | kSemiInductanceShelfDbMin = -18.0 |
| static constexpr double | kSemiInductanceShelfDbMax = -6.0 |
| static constexpr double | kDriveDbDefault = 0.0 |
| Excursion drive. [dp, default 0 dB, range -12..+24 dB]. | |
| static constexpr double | kDriveDbMin = -12.0 |
| static constexpr double | kDriveDbMax = 24.0 |
| static constexpr double | kCompressionAmountDefault = 60.0 |
| Depth of the BL(x) / Cms(x) nonlinearity. [dp, default 60 %, range 0..100]. | |
| static constexpr double | kExcursionReference = 0.5 |
| Normalized reference excursion. | |
| static constexpr double | kExcursionReferenceMin = 0.1 |
| static constexpr double | kExcursionReferenceMax = 2.0 |
| static constexpr double | kBlFalloff = 1.5 |
| BL(x) falloff rate: g_bl = 1/(1 + beta*x^2), beta = amount * k_bl. | |
| static constexpr double | kBlFalloffMin = 0.0 |
| static constexpr double | kBlFalloffMax = 4.0 |
| static constexpr double | kCmsStiffening = 0.35 |
| Cms(x) stiffening rate: fc' = fc*(1 + gamma*x^2), gamma = amount * k_cms. | |
| static constexpr double | kCmsStiffeningMin = 0.0 |
| static constexpr double | kCmsStiffeningMax = 1.0 |
| static constexpr double | kMicDistanceCmDefault = 3.0 |
| Mic distance. [dp, default 3 cm, range 1..60 cm]. | |
| static constexpr double | kMicDistanceCmMin = 1.0 |
| static constexpr double | kMicDistanceCmMax = 60.0 |
| static constexpr double | kProximityGainK = 12.0 |
| Proximity shelf. | |
| static constexpr double | kProximityGainKMin = 0.0 |
| static constexpr double | kProximityGainKMax = 24.0 |
| static constexpr double | kProximityReferenceCm = 30.0 |
| static constexpr double | kProximityReferenceCmMin = 20.0 |
| static constexpr double | kProximityReferenceCmMax = 50.0 |
| static constexpr double | kProximityCeilingDb = 8.0 |
| static constexpr double | kProximityCeilingDbMin = 6.0 |
| static constexpr double | kProximityCeilingDbMax = 12.0 |
| static constexpr double | kProximityCornerHz = 250.0 |
| static constexpr double | kProximityCornerHzMin = 150.0 |
| static constexpr double | kProximityCornerHzMax = 400.0 |
| static constexpr double | kAirLossDbPerCm = 0.05 |
| Air/distance HF loss above a corner, scaling with distance. | |
| static constexpr double | kAirLossDbPerCmMin = 0.02 |
| static constexpr double | kAirLossDbPerCmMax = 0.10 |
| static constexpr double | kAirLossCornerHz = 6000.0 |
| static constexpr double | kAirLossCornerHzMin = 4000.0 |
| static constexpr double | kAirLossCornerHzMax = 8000.0 |
| static constexpr double | kPresenceCapDb = 3.0 |
| Cap-to-cone traverse: a high shelf lerped from bright at the dust cap to dark at the cone edge. | |
| static constexpr double | kPresenceEdgeDb = -8.0 |
| static constexpr double | kPresenceDbMax = 6.0 |
| static constexpr double | kPresenceDbMin = -12.0 |
| static constexpr double | kPresenceCornerHz = 2500.0 |
| static constexpr double | kPresenceCornerHzMin = 1500.0 |
| static constexpr double | kPresenceCornerHzMax = 3500.0 |
| static constexpr double | kMicPositionPctDefault = 30.0 |
| static constexpr double | kOffAxisOnAxisHz = 8000.0 |
| Off-axis rolloff: fc = f_on * (1 - k_ax * sin(angle)). | |
| static constexpr double | kOffAxisOnAxisHzMin = 5000.0 |
| static constexpr double | kOffAxisOnAxisHzMax = 12000.0 |
| static constexpr double | kOffAxisFactor = 0.7 |
| static constexpr double | kOffAxisFactorMin = 0.0 |
| static constexpr double | kOffAxisFactorMax = 0.95 |
| static constexpr double | kMicAxisDegMin = 0.0 |
| static constexpr double | kMicAxisDegMax = 90.0 |
| static constexpr double | kBaffleStepDb = 6.0 |
| Baffle step: +6 dB high shelf at c / (pi * W), depth scaled by diffraction_amount. | |
| static constexpr double | kEdgeDistanceM = 0.15 |
| Edge-diffraction ripple: two low-Q sections at c/(2*d_edge) and twice that. | |
| static constexpr double | kEdgeDistanceMMin = 0.08 |
| static constexpr double | kEdgeDistanceMMax = 0.30 |
| static constexpr double | kRipple1Q = 2.0 |
| static constexpr double | kRipple1Db = 2.5 |
| static constexpr double | kRipple2Q = 2.5 |
| static constexpr double | kRipple2Db = -2.0 |
| static constexpr double | kRippleQMin = 1.5 |
| static constexpr double | kRippleQMax = 4.0 |
| static constexpr double | kRippleDbMax = 4.0 |
| static constexpr double | kDiffractionAmountDefault = 50.0 |
| static constexpr double | kDipolePathM = 0.30 |
| Open-back dipole: first-order high-pass at c / (2*D) plus a notch. | |
| static constexpr double | kDipolePathMMin = 0.15 |
| static constexpr double | kDipolePathMMax = 0.50 |
| static constexpr double | kDipoleNotchRatio = 1.8 |
| static constexpr double | kDipoleNotchRatioMin = 1.4 |
| static constexpr double | kDipoleNotchRatioMax = 2.2 |
| static constexpr double | kDipoleNotchQ = 1.5 |
| static constexpr double | kDipoleNotchQMin = 1.0 |
| static constexpr double | kDipoleNotchQMax = 3.0 |
| static constexpr double | kDipoleNotchDb = -4.0 |
| static constexpr double | kDipoleNotchDbMin = -8.0 |
| static constexpr double | kDipoleNotchDbMax = -2.0 |
| static constexpr double | kOutputTrimDbMin = -24.0 |
| Output make-up. [dp, default 0 dB, range -24..+24 dB]. | |
| static constexpr double | kOutputTrimDbMax = 24.0 |
| static constexpr double | kDcBlockerHz = 5.0 |
| Input DC-blocker corner. | |
| static constexpr double | kDcBlockerHzMin = 2.0 |
| static constexpr double | kDcBlockerHzMax = 20.0 |
| static constexpr double | kSmoothingMs = 15.0 |
| Parameter smoothing time. [dp, default 15 ms, range 5..30 ms]. | |
| static constexpr double | kSmoothingMsMin = 5.0 |
| static constexpr double | kSmoothingMsMax = 30.0 |
| static constexpr int | kControlBlock = 32 |
| Coefficient recompute cadence, in samples. | |
| static constexpr int | kControlBlockMin = 16 |
| static constexpr int | kControlBlockMax = 64 |
| static constexpr double | kWorstCaseGain = 10.0 |
| Sum of per-stage peak magnitudes across the whole parameter space, the bound the Forge registry cites. | |
| static constexpr int | kBreakupModeCount = 4 |
| static constexpr double | kBreakupRatioMin = 1.0 |
| static constexpr double | kBreakupRatioMax = 4.0 |
| static constexpr double | kBreakupQMin = 1.5 |
| static constexpr double | kBreakupQMax = 8.0 |
| static constexpr double | kBreakupGainDbMax = 6.0 |
Physics-based speaker + cabinet + microphone emulator.
See the file doc block for the sibling relationship with ZeroLatencyConvolverT, the composition notes, and the anti-aliasing policy. Signal chain, in order: DC block, drive, Thiele-Small resonance (HP tap = pressure, LP tap = excursion), BL(x) compression, voice-coil inductance rolloff, cone-breakup modal bank, cabinet (baffle step, edge ripple, open-back dipole), microphone (proximity, air loss, cap-to-cone traverse, off-axis), output trim.
|
inline |
Air/distance HF trim, in dB (negative), scaling with distance.
|
inlinestatic |
[design parameter] table; see SpeakerDriverArchetype and the model scope above.
Ranges below each figure are the datasheet envelope the value is drawn from.
|
inline |
|
inline |
Baffle-step transition c / (pi * W).
|
inline |
BL(x) falloff coefficient beta actually in force.
|
inline |
|
inlinestatic |
[design parameter] shape.
Ranges: ratio 1.0..4.0, Q 1.5..8.0, gain +-6 dB. Honest gap: exact modal maps are driver-specific and are not published as citable tables; these are engineered presence-region values.
|
inline |
Centre of breakup mode index, anchored on the archetype.
|
inline |
Cms(x) stiffening coefficient gamma actually in force.
|
inline |
Compliance ratio alpha = Vas / Vb.
Zero in open-back: the rear wave escapes, so there is no trapped-air stiffness and the driver runs near free air. That is the real physical difference between the two cabinet types, exposed as one enum.
|
inline |
Open-back dipole corner c / (2 * D).
|
inline |
The resonance cutoff currently in force, including Cms stiffening.
|
inline |
Normalized excursion produced by the most recent sample.
|
inline |
Exact magnitude of the voice-coil inductance stage ALONE, in dB, from the coefficients currently in force.
The stage is a parallel blend of a first-order lowpass and a high shelf, so it cannot be read off the chain's response: every other stage sits on top of it, and the off-axis lowpass in particular is a second HF rolloff that is always present. Exposing the stage's own response lets its corner and slope be asserted directly — and lets a UI draw the rolloff the "treble" control is actually applying.
|
inline |
The chain is a cascade of minimum-phase filters with no block buffering and no oversampler, so nothing is held back.
|
inline |
Off-axis corner f_on * (1 - k_ax * sin(angle)).
|
inline |
Recompute every corner coefficient for a new sample rate. No allocation.
|
inline |
Cap-to-cone traverse shelf, lerped bright-to-dark.
|
inline |
|
inline |
|
inline |
Proximity shelf gain, boost-only by construction and clamped at the ceiling: k_prox * (1/d - 1/d_ref) in dB.
|
inline |
Zero every filter and excursion state.
No allocation. A zero-initialised instance is equivalent to a reset one.
|
inline |
Box resonance fc = fs * sqrt(1 + alpha), shifted by the voicing trim.
|
inline |
Peak magnitude of the second-order high-pass at the resonance, in dB: Q / sqrt(1 - 1/(4 Q^2)).
Only defined for Q > 1/sqrt(2); below that the response is monotone and there is no peak.
|
inline |
Frequency of that peak: fc / sqrt(1 - 1/(2 Q^2)).
NOT fc — a second-order high-pass peaks ABOVE its corner, unlike a bandpass.
|
inline |
Box Qtc = Qts * sqrt(1 + alpha), unless overridden.
|
inline |
First edge-diffraction ripple c / (2 * d_edge).
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Override the computed box Qtc.
Pass a non-positive value to return to the archetype-and-volume computation.
|
inline |
|
inline |
|
inline |
Sum of per-stage peak magnitudes across the parameter space.
Asserted, not estimated — see the worst-case-gain test.
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Air/distance HF loss above a corner, scaling with distance.
[dp: 0.05 dB/cm, range 0.02..0.10] [dp: corner 6 kHz, range 4..8 kHz]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Baffle step: +6 dB high shelf at c / (pi * W), depth scaled by diffraction_amount.
The +6 dB is the PUBLISHED half-space-to-full-space transition (Olson 1969), not a tunable.
|
staticconstexpr |
BL(x) falloff rate: g_bl = 1/(1 + beta*x^2), beta = amount * k_bl.
[dp, default 1.5, range 0..4]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Sealed-box internal volume. [dp, default 28 L, range 5..150 L].
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Cms(x) stiffening rate: fc' = fc*(1 + gamma*x^2), gamma = amount * k_cms.
[dp, default 0.35, range 0..1]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Depth of the BL(x) / Cms(x) nonlinearity. [dp, default 60 %, range 0..100].
|
staticconstexpr |
Depth of the cone-breakup bank. [dp, default 100 %, range 0..100 %].
|
staticconstexpr |
Coefficient recompute cadence, in samples.
[dp, default 32, range 16..64] Keeps transcendentals out of the hot loop beyond the resonator's own tick.
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Input DC-blocker corner.
[dp, default 5 Hz, range 2..20 Hz]
This must be set explicitly rather than left at DcBlocker's default pole of 0.995, which is a ~38 Hz corner at 48 kHz — inside the passband of every archetype here and directly on top of the Bass-15's 45 Hz resonance. A DC blocker's job is removing DC, not shaping the low end; at 5 Hz it is 18 dB below the lowest resonance in the table and the second-order-high-pass asymptote below fc is the driver's, not the blocker's.
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Open-back dipole: first-order high-pass at c / (2*D) plus a notch.
[dp: D 0.30 m, range 0.15..0.5] [dp: notch ratio 1.8, range 1.4..2.2] [dp: notch Q 1.5, range 1.0..3.0] [dp: notch -4 dB, range -8..-2]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Excursion drive. [dp, default 0 dB, range -12..+24 dB].
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Edge-diffraction ripple: two low-Q sections at c/(2*d_edge) and twice that.
[dp: d_edge 0.15 m, range 0.08..0.30] [dp: (Q 2.0, +2.5 dB) and (Q 2.5, -2.0 dB), Q range 1.5..4, gain +-4 dB]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Normalized reference excursion.
Signals here are normalized audio, not metres, so this and drive_db together set WHERE compression begins rather than claiming a physical Xmax. [dp, default 0.5, range 0.1..2.0]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Mic distance. [dp, default 3 cm, range 1..60 cm].
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Off-axis rolloff: fc = f_on * (1 - k_ax * sin(angle)).
[dp: f_on 8 kHz, range 5..12 kHz] [dp: k_ax 0.7, range 0..0.95]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Output make-up. [dp, default 0 dB, range -24..+24 dB].
|
staticconstexpr |
Cap-to-cone traverse: a high shelf lerped from bright at the dust cap to dark at the cone edge.
[dp: +3 dB at cap, -8 dB at edge, range +6..-12] [dp: corner 2.5 kHz, range 1.5..3.5 kHz]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Proximity shelf.
The gain law is k_prox * (1/distance - 1/d_ref), clamped to [0, ceiling] — the 0 dB floor is STRUCTURAL (the shelf is boost-only by construction), the ceiling is a design parameter. [dp: k_prox 12, range 0..24] [dp: d_ref 30 cm, range 20..50] [dp: ceiling +8 dB, range +6..+12] [dp: corner 250 Hz, range 150..400]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Box Qtc override.
[dp, default = computed from archetype + volume, range 0.4..2.0]
|
staticconstexpr |
|
staticconstexpr |
Voicing shift of the computed resonance. [dp, default 0, range -12..+12].
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Leach semi-inductance blend and its shelf floor: the fraction of the un-rolled signal mixed back through a high shelf to give the "leaky", gentler-than-6-dB/oct HF decay real motors measure.
[dp, default 0.25, range 0..1] and [dp, default -12 dB, range -18..-6]
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Parameter smoothing time. [dp, default 15 ms, range 5..30 ms].
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Speed of sound in air at ~20 C, standard atmospheric value.
PUBLISHED physical constant, not a tunable — it sets the baffle-step and dipole frequencies from geometry.
|
staticconstexpr |
Voice-coil-inductance corner. [dp, default 4000 Hz, range 1500..8000 Hz].
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Sum of per-stage peak magnitudes across the whole parameter space, the bound the Forge registry cites.
Asserted by the worst-case-gain test — a measured invariant, not an estimate.