-
Notifications
You must be signed in to change notification settings - Fork 5
feat: add 12AX7 triode clipper and inter-stage filtering #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7d57edf
cd94f5e
9b42c2a
db88b3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,29 @@ impl DcBlocker { | |
| } | ||
| } | ||
|
|
||
| /// One-pole low-pass filter. | ||
| /// | ||
| /// Models reactive elements like plate load capacitance. | ||
| /// `y[n] = y[n-1] + coeff * (x[n] - y[n-1])` | ||
| #[derive(Clone)] | ||
| pub struct OnePoleLP { | ||
| y_prev: f32, | ||
| coeff: f32, | ||
| } | ||
|
|
||
| impl OnePoleLP { | ||
| pub fn new(cutoff_hz: f32, sample_rate: f32) -> Self { | ||
| let coeff = 1.0 - (-2.0 * PI * cutoff_hz / sample_rate).exp(); | ||
| Self { y_prev: 0.0, coeff } | ||
| } | ||
|
Comment on lines
+60
to
+63
|
||
|
|
||
| #[inline] | ||
| pub fn process(&mut self, input: f32) -> f32 { | ||
| self.y_prev = self.coeff.mul_add(input - self.y_prev, self.y_prev); | ||
| self.y_prev | ||
| } | ||
| } | ||
|
|
||
| /// One-pole envelope follower with configurable attack and release coefficients. | ||
| #[derive(Clone)] | ||
| pub struct EnvelopeFollower { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TRIODE_TABLEis lazily initialized, and the firstClipperType::Triode.process()call will trigger allocation/table construction and one-time synchronization. If that first call happens on the real-time audio thread (e.g. when loading a preset using Triode), it can cause an audible glitch.Consider forcing initialization off the audio thread (e.g. during app/engine startup, or when building the amp chain if any stage uses
ClipperType::Triode) so audio processing never pays the init/lock cost.