52#ifndef SBL_DSP_PM_MASS_SPRING_DAMPER_HPP_
53#define SBL_DSP_PM_MASS_SPRING_DAMPER_HPP_
69 static constexpr float MIN_Q = 0.05f;
70 static constexpr float MAX_Q = 1000.0f;
117 float q()
const {
return q_; }
118 float mass()
const {
return mass_; }
135 const float v = g_ * force + h_;
136 x_ += HALF * (v + v_);
138 a_ = (force - c_ * v - k_ * x_) * inv_mass_;
147 float energy()
const {
return HALF * (mass_ * v_ * v_ + k_ * x_ * x_); }
165 static constexpr float HALF = 0.5f;
166 static constexpr float QUARTER = 0.25f;
171 k_ = mass_ * w0 * w0;
172 c_ = mass_ * w0 / q_;
173 inv_mass_ = 1.0f / mass_;
175 const float d = mass_ + HALF * c_ + QUARTER * k_;
181 void update_history() {
182 h_ = (mass_ * v_ - QUARTER * k_ * v_ - HALF * k_ * x_ + HALF * mass_ * a_) * inv_d_;
185 float frequency_hz_ = 220.0f;
191 float inv_mass_ = 1.0f;
201static_assert(is_load_v<MassSpringDamper> && is_described_v<MassSpringDamper>,
"MassSpringDamper is a Load and describes itself (physical-modeling.md §4.1, §7)");
Clamping (Cross-cutting — Math)
uint8_t add_node(Kind kind, const char *name, uint8_t group, float value=0.0f, float value2=0.0f)
static constexpr float MAX_FREQUENCY_FRACTION
of the sample rate
diagram::Ports describe(diagram::Graph &g, uint8_t group, const char *name="mode") const
One Load node: frequency and Q. Never called from audio code (AP-037).
float energy() const
Stored energy ½mv² + ½kx², for passivity tests.
static constexpr float MAX_MATCH
static constexpr float MIN_MASS
void set_frequency(float hz)
Undamped resonance, Hz.
static constexpr float MAX_Q
float match() const
The damper relative to the string's impedance: c / Z with Z = 1.
void set_mass(float m)
Mass in string-impedance units; heavier is closer to rigid.
float commit(float force)
Apply this sample's force and advance: returns the velocity.
void set_resonance(float hz, float q, float match)
The musical parametrisation: where, how wide, how much it takes.
static constexpr float MIN_MATCH
float admittance() const
Instantaneous admittance g: how much of this sample's force shows up in this sample's velocity.
static constexpr float MIN_Q
void set_q(float q)
Quality factor: how many cycles the ringing lasts.
static constexpr float MIN_FREQUENCY_HZ
static constexpr float MAX_MASS
The numbers every layer reaches for.
What a load, an exciter, a termination and a friction law provide (Physical modeling — cross-cutting)
Fixed-point constants and audio sample types.
A model's wiring, as data (AP-037)
@ Load
a lumped body; value: Hz, value2: Q
constexpr float clamp(float x, float lo, float hi)
x held to [lo, hi]; NaN → lo.
Physical modeling: laws, bows, junctions, loads, resonators, strings (docs/conventions/physical-model...
The ports a component exposes after describing itself, so an owner can wire them.
uint8_t in
where a wave enters (the junction, the load)
uint8_t out
where a wave leaves (the pickup, the reflection)