wrestling math and electronics while following "from circuit to code"

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Archit3ch wrote: Sun May 31, 2026 10:59 pm You can make a potentiometer as 2 variable-resistors.
that's what i thought in the very very beginning so i just said "i'll keep it simple, every component has 2 pins"
anyway, i've fixed that, i got a potentiometer class now
Archit3ch wrote: Start with Ebers-Moll for audio.
i went with whatever is on qucs technical documentations (i think it's the gummel-poon with "gm" "go" stuff (the one that looked simpler to me)
Archit3ch wrote: We have an #analog-modeling channel in The Audio Programmer Discord. 8) There are people posting about their solver attempts.
i'm not a fan of discord, and most other newer chats with closed clients and inability to run your own server/network... i'm on IRC still
if the client is written in the spirit of "let's use a webbrowser engine for the GUI" - i don't have that much RAM to throw away (this same thing applies to my choice of text editor, IDE and such)
Archit3ch wrote:
antto wrote: Wed May 27, 2026 8:35 pm

Code: Select all

template<typename T>
struct capacitor
{
    inline void save(const T vd)
    {
        ieq += 2*(g*vd-ieq); // hardcoded trapezoidal integrator. not bad, but this should be abstracted out as an integrator choice
    }
};
it's still early, i think i'm far from the point where i can use the output of this for anything serious, i just added the ability for series resistors on components, and parameter presets (mainly for the transistor but also for the diode). currently i'm testing the result in another CLI app which can write the result in a .wav, or print values to the terminal
Archit3ch wrote: Uh, none of that is gonna run on a Cortex-M4F. :ud:

With the possible exception of the simplest of simple circuits.
i don't see why not, unless for the "float" being not enough for circuit simulation? (i already saw in a few places that double precision is used on the PC)
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote: Mon Jun 01, 2026 5:09 am
Archit3ch wrote: Start with Ebers-Moll for audio.
i went with whatever is on qucs technical documentations (i think it's the gummel-poon with "gm" "go" stuff (the one that looked simpler to me)
Start with Ebers-Moll. Add more detailed model with more parameters when you've convinced yourself that (1) you understand what they do and (2) you actually need them.

Post

Re: Melange
Looks vibecoded. :hihi: There are plenty of mistakes, scaling problems, etc.

To be fair, it looks better than "everyone's first circuit solver".

Depends on what's meant by "vibe coded". If it's the same general definition I use, ie "A person told an agent what they wanted and waited for it to be delivered", then no.

If it's "A software engineer using an agent assist to help implement a design" then yes.

And yeah, still very early alpha with several problems, hence no "release" or announcement or package or versions.

But it DOES need co-maintainers with more circuit solver knowledge before it's viable for much beyond hobby projects.

Post

I went out and got a copy of my friends course book he wrote while at Stanford back in the 70s. Intro to electronics, it was mostly analog back then, old school circuit modeling and whatnot with all the fundamental maths. :tu:

old library copy cost me $9

Post

afaiu, it's too late for Ebers-Moll, since afaik gummel-poon is fancier and if you turn off a bunch of parameters it simplifies to Ebers-Moll
now, i actually don't fully know which ones and i didn't follow all of the math of the gummel-poon, just about up to the "gm" "go" and "ieq" computations, so i don't know how much of Ebers-Moll this thing can do, but i think it is probably overkill for dumber audio circuits, i have the following params:

Code: Select all

    T BF   = (T)(100);   //!< Fwd beta
    T BR   = (T)(1);     //!< Rev beta
    T IS   = (T)(1e-16); //!< saturation current
    T ISE  = (T)(0);     //!< (C2) B-E leakage saturation current (if above 1 - multiplies IS)
    T ISC  = (T)(0);     //!< (C4) B-C leakage saturation current (if above 1 - multiplies IS)
    T NE   = (T)(1.5);   //!<      B-E leakage emission coeff
    T NC   = (T)(2.0);   //!<      B-C leakage emission coeff
    T NF   = (T)(1);     //!< Fwd emission coeff
    T NR   = (T)(1);     //!< Rev emission coeff
    T IKF  = (T)(0);     //!< High current corner for Fwd beta (0==infinity)
    T IKR  = (T)(0);     //!< High current corner for Rev beta (0==infinity)
    T VAF  = (T)(0);     //!< Fwd early voltage (0==infinity)
    T VAR  = (T)(0);     //!< Rev early voltage (0==infinity)
    T RB   = (T)(0);     //!< Base series resistance
    T RC   = (T)(0);     //!< Emitter series resistance
    T RE   = (T)(0);     //!< Collector series resistance
    T TNOM = (T)(26.85); //!< temperature
and these are compile-time constants, so i have reciprocals everywhere possible and i've added some special if constexpr checks to skip computing things that won't matter (there is a total of 4 exp() calls, and 2 of them depend on ISE and ISC respectively so those can go away, similarly VAF VAR IKF and IKR have reciprocals and when they're zero - a bunch of more stuff can be turned off

i added the RB RC RE on my own (it's not covered in the qucs page (or i didn't see it?)) by literally injecting hidden resistors in the circuit (only if they're non-zero)
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote: Mon Jun 01, 2026 6:52 pm afaiu, it's too late for Ebers-Moll, since afaik gummel-poon is fancier and if you turn off a bunch of parameters it simplifies to Ebers-Moll
Mathematically... yeah... computationally... well, you can implement Ebers-Moll in a much faster form... but whatever you do, you would really want to learn how the model actually works.

Post

i want to learn how transistors work since many years, but they're difficult and i'm dumb, well, i kinda understand a little bit more now, i've "designed" a bunch of different circuits involving transistors (by fiddling in falstad until the signal looks like what i need), but there is so much more to transistors, like, i recently learned about "translinear" circuits
EDIT: also, i'm okay if the transistor model i wrote is overkill for audio, as long as it works properly, i can always try to see if i can cut corners here or there, make more ghetto-grade variants.
i think this will strongly depend on the circuit it's used in.. so it will always be good to be able to try the "overkill" model and then have the result as a reference and start dumbifying it and comparing to the reference...

kinda unrelated but, in vb303 i have one distortion algorithm that is, i guess, "memory saturation"
basically it's a sigmoid of the form:

Code: Select all

 "y = x / (1 + abs(x))"
but with a little twist:

Code: Select all

"y = x / (1 + abs(lpf(x)))"
it sounded interesting back then so i kept it in... years later i began making PCBs and stuff, and i was wondering if i can make an analog(ue) version of it, asked some folks who know things.. they told me division is difficult, so one way is with some specialized ICs that are probably very $$$$ and overkill for this, and the other way is by turning the signals into log domain and then back (this involved opamps and diodes in funky setups)
so i tried to put together the 2nd option in falstad and it was quite scary.. i think it kinda worked but i didn't really wanna try to make a real PCB out of that (forgot why)

in the recent years i see how a bunch of the audio circuits actually work in "current" .. i mean, they turn the signal into current instead of voltage and do stuff there
and now i saw some "translinear loop" (i think) involving 4 transistors which can do multiplication and division with currents! so i guess i should try fiddling with this when i got time
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote: Mon Jun 01, 2026 7:40 pm i want to learn how transistors work since many years, but they're difficult and i'm dumb, well, i kinda understand a little bit more now
The way to think about BJTs is that there's a diode from base to emitter, which works exactly like an ordinary diode: as voltage across the diode increases linearly, the diode current increases exponentially.

Then in the Ebers-Moll model (which is usually what you need to design transistor circuits), you take that diode current, multiply by forward beta (hFE) and that's the maximum amount of current that can flow from collector to emitter. In practical terms, when you design circuits, you just assume that it saturates if you try to source too much current from the collector, but it turns out that Ebers-Moll elegantly handles this automatically...

...because you can swap the collector and emitter and get a transistors that's just kinda worse (lower beta). Mathematically, in Ebers-Moll model then, if we were try to source more current from the collector than is available, the reverse diode from base to collector also starts conducting and now we allow this current times reverse beta to flow from emitter to collector, so in a simulator you can just sum these two currents (from collector to emitter and emitter to collector) and as long as the parameters are plausible, they'll cancel out and you have a transistor that will saturate if there's not enough collector voltage available.

So.. two ordinary diodes, then you solve both currents as you would solve any other diodes, and then you force these currents multiplied by the forward and reverse beta to flow from collector to emitter and emitter to collector respectively. That's it. Series resistance of the diodes is worth modelling (on the order of 1 ohm typically) as it greatly improves convergence.

Post

as with many other posts, i will be going back and re-reading these posts, as i don't understand them at the moment.
i knew from about 2012-ish maybe about the "Ebers-Moll" at least as a name, i knew it was spice-grade..
but in the beginning of this (aka a bunch of days ago) i tried to find the math for it and couldn't figure out how to make it work.. i did find the qucs stuff and it looked too scary and i was skipping it, but i did notice that it says that gummel-poon "simplifies" to Ebers-Moll.. after i couldn't make anything out of it and gave up, i decided to throw it at "the chatbot" and asked for Ebers-Moll or something even simpler since this is for realtime audio, not anything fancy.. and as i said earlier - that resulted in several different piles of code and time spent that didn't get anywhere, and the chatbot was changing its mind on things, as if math isn't already confusing enough for me.. and after i couldn't get anything out of this too, i looked one more time on my own (and now after debugging the chatbot-generated semi-broken math, i was seeing some familiar things) so i ended up back at qucs and just tried to decrypt the math into code and see how far i can get.. so i wrote what i wrote and needed help from the chatbot again but only for the final bits of the math (i couldn't figure out how to get the conductances and "ieq" per pin, since they are shown there in a table/matrix, and i wasn't sure about the polarities (turns out that i had to flip the polarities of the ieq stuff for PNP)

anyway, thru the years i've been periodically going back and re-reading old posts here and sometimes i understand one new fraction of what was said back then...

an actual more basic question now:

Image

this is a pesky circuit that can be seen in several places in the 303
now, i understand it to some degree (i tossed it in falstad and tried to reproduce it in another way which i thought it works, and i saw that there is clearly a difference).

so it's an HPF which is pulled to 5.333V (actually, ignore the "vcc" name, it's a virtual ground) but that 5.333V is actually an LPF.
the AC signal from the HPF affects the vmid voltage, and the vmid voltage is what the HPF signal is pulled to, so the two filters depend on each other. the LPF actually is not really filtering anything, it's more like a local 5.333V reservoir capacitor that charges slowly from the source...
anyway, the DSP equivalent of this is not merely a HPF and a LPF

so...

Code: Select all

V1 vin  gnd
C1 vin  vout, 1u
R1 vout vmid, 2.2k
R2 vmid vcc,  2.2k
C2 vmid gnd,  10u
V2 vcc  gnd,  5.333

Code: Select all

eq0: 0 = -r1_g*(vout-vmid)+r2_g*(vmid-vcc)+c2_g*(vmid-gnd)-c2_ieq;
eq1: 0 = -c1_g*(vin-vout)+c1_ieq+r1_g*(vout-vmid);

Code: Select all

struct circuit
{
    double dt;
    as_bzzzt::capacitor<double> c1;
    as_bzzzt::resistor<double> r1;
    as_bzzzt::resistor<double> r2;
    as_bzzzt::capacitor<double> c2;
    static constexpr double V2 = 5.333;
    // ----
    double vcc;
    double vmid;
    double vout;
    static constexpr double gnd = 0.0;
    double vin;
    void init(const double Fs)
    {
        dt = 1.0/Fs;
        c1.init(Fs, 9.9999999999999995e-07, 0);
        r1.set_value(2200.0);
        r2.set_value(2200.0);
        c2.init(Fs, 1.0000000000000001e-05, 0);
        vmid = 0; // TODO initial value!
        vout = 0; // TODO initial value!
    }
    void tick(const float V1)
    {
        vcc = (gnd+V2);
        vin = (gnd+V1);
        // voltage equations from external math solver:
        const double _tmp1 = r1.g+c1.g;
        const double _tmp2 = 1.0/(_tmp1*r2.g+(c2.g+c1.g)*r1.g+c1.g*c2.g);
        const double _tmp3 = -c1.ieq;
        const double _tmp4 = c1.g*vin;
        const double _tmp5 = r1.g*(_tmp4+c2.ieq+_tmp3);
        const double _tmp6 = _tmp4+_tmp3;
        vmid = _tmp2*(_tmp5+_tmp1*r2.g*vcc+c1.g*c2.ieq);
        vout = _tmp2*(_tmp5+r2.g*_tmp6+c2.g*_tmp6+r1.g*r2.g*vcc);
        // end of equations
        c1.save(vin-vout);
        c2.save(vmid-gnd);
    }
};
now, DSP-wise, i think the voltage of the pull is irrelevant, it doesn't have to be 5.333, it can be 0 and things will still work the same.

i have the feeling that this kind of structure should be representable with something similar to an SVF, maybe?
and the TPT svf has much less "math", well, if i decide will never wanna change the resistor/capacitor values - i can just throw them at maxima and i'll get less "code" then, but the TPT svf is adjustable
and iirc the TPT svf had "tan()" in the coefficients, i somehow ended up not having it since my capacitor's conductance is "g = Fs*2*farads;"
i'm not sure if i'm doing things right even at this basic level of 2 resistors and 2 capacitors

and another question regarding the 303... in the VCF ladder, the bottom capacitor 18n while the other three are 33n, and 18n is roughly half of 33n, we all know that, but yet in one or more places i read that the transistors wired up as diodes act like variable resistors, but the bottom capacitor which is near the input/feedback transistors "sees" a different resistance and effectively 18n actually compensates for that if i'm understanding correctly? if that's true, then shouldn't the digital transfer function not use "2*a" for the first stage but just "a" like the other 3 stages?
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote: Mon Jun 01, 2026 9:19 pm i have the feeling that this kind of structure should be representable with something similar to an SVF, maybe?
You get the usual trapezoidal SVF code out of a state-space representation by using LU with the correct order of dimensions... but state-space and MNA are closely related and the real reason you get so much less math is because of buffering.
and iirc the TPT svf had "tan()" in the coefficients, i somehow ended up not having it since my capacitor's conductance is "g = Fs*2*farads;"
The tan(pi*f/fs) is the BLT prewarp. Essentially the way it works is that you start with an analog filter that you can tune... and then you observe that trapezoidal integration warps the the frequency response with atan() so you tune the analog filter with tan(pi*f*/fs) so that the tangent and arc-tangent cancel out.

i'm not sure if i'm doing things right even at this basic level of 2 resistors and 2 capacitors
i read that the transistors wired up as diodes act like variable resistors
Yes. In the transistor ladder the forward bias of the transistors makes them essentially act like buffers, so that each stage is independent. In the diode case there is no such buffering.
but the bottom capacitor which is near the input/feedback transistors "sees" a different resistance and effectively 18n actually compensates for that if i'm understanding correctly? if that's true, then shouldn't the digital transfer function not use "2*a" for the first stage but just "a" like the other 3 stages?
Well, in the analog version it doesn't really see a different resistance as such, because it's the cap that's half value ... so it just charges twice as fast (in terms of voltage) for the same current. You might be able to use "2*a" but I guess it depends on how you formulate the equations.

Post

antto wrote: Mon Jun 01, 2026 9:19 pm this is a pesky circuit that can be seen in several places in the 303
Oh... this one... it looks like pretty standard DC biasing.

C1 blocks DC, so we can choose the operating point. We choose whatever we have at V2 and C2 is likely just to block power supply noise with the resistors limiting current, so we only get a low frequency signal (ie. the "DC") without drowing out the AC over C1.

I think you can just ignore C2 and combine R1,R2 into one resistor (or if R2<<R1 then just ignore R2 as well). Usually modelling power bypass is kinda futile since it won't be very relevant unless you do PCB-level simulation (which is kinda unrealistic in realtime).

Post

mystran wrote: Tue Jun 02, 2026 12:09 am
antto wrote: Mon Jun 01, 2026 9:19 pm i have the feeling that this kind of structure should be representable with something similar to an SVF, maybe?
You get the usual trapezoidal SVF code out of a state-space representation by using LU with the correct order of dimensions... but state-space and MNA are closely related and the real reason you get so much less math is because of buffering.
and iirc the TPT svf had "tan()" in the coefficients, i somehow ended up not having it since my capacitor's conductance is "g = Fs*2*farads;"
The tan(pi*f/fs) is the BLT prewarp. Essentially the way it works is that you start with an analog filter that you can tune... and then you observe that trapezoidal integration warps the the frequency response with atan() so you tune the analog filter with tan(pi*f*/fs) so that the tangent and arc-tangent cancel out.
if i understand correctly, formulas for "continuous" stuff (in other words, formulas describing the analog filter design) when used in "discrete time" become slightly broken, and the tan() chunk is a correction?

when you take formulas from an analog(ue) filter and try to make a digital version - you know what you're doing so you'd put the tan() chunk. but when you throw a circuit of such analog(ue) filter into a circuit simulator - the simulator has no idea what the hell this is, so there's no tan() there, right? doesn't this make the hypotethical cutoff/resonant freq slightly wrong? and maybe the expected "cure" is the assumption that the simulator should be running at a much higher sampling rate than any of the signals of interest (where x and tan(x) are very close anyway)?
but the bottom capacitor which is near the input/feedback transistors "sees" a different resistance and effectively 18n actually compensates for that if i'm understanding correctly? if that's true, then shouldn't the digital transfer function not use "2*a" for the first stage but just "a" like the other 3 stages?
Well, in the analog version it doesn't really see a different resistance as such, because it's the cap that's half value ... so it just charges twice as fast (in terms of voltage) for the same current. You might be able to use "2*a" but I guess it depends on how you formulate the equations.
i looked back thru the old threads, Tim and kunn were talking about the filter response or transfer function or something, and while i still don't understand most of it, the word "half cap" is present there, and it seems like they were calculating things with or without it

i can't find it now, but recently, i seem to remember reading some info that says that the bottom of the ladder has a different impedance or something (compared to the upper stages), and that if you put a half-value capacitor - this will actually give you the 1st pole at roughly the same cutoff as the other 3 poles (so i understand this as "if the first cap was also 33n then the cutoff was going to be more away from the other three")

other than that, the formula (well, actually, transfer function i guess) of what i've thought is the 303 filter which i'm aware of is this one:
viewtopic.php?p=3794880#p3794880
afaiu, kunn, you, and Tim have analyzed and described the filter
i also went back to see karrikuh's diode ladder implementation (which appeared later), and there he uses "4*a" for the first stage, and "2*a" for the other three.. so that's a twice higher coeff on the first stage

i remember in the past that i've also tried to have the same coeff for the 1st stage, a "2*a" and even "(33/18)*a", but i don't remember what my conclusion was (in any case, since the other unknowns in the circuit were probably not right (like, all the cutoffs of the HPFs in the feedback), and the AC-coupling of the soundcard making things difficult, it was hard to tell)

i guess i should check it
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

mystran wrote: Tue Jun 02, 2026 12:26 am
antto wrote: Mon Jun 01, 2026 9:19 pm this is a pesky circuit that can be seen in several places in the 303
Oh... this one... it looks like pretty standard DC biasing.

C1 blocks DC, so we can choose the operating point. We choose whatever we have at V2 and C2 is likely just to block power supply noise with the resistors limiting current, so we only get a low frequency signal (ie. the "DC") without drowing out the AC over C1.

I think you can just ignore C2 and combine R1,R2 into one resistor (or if R2<<R1 then just ignore R2 as well). Usually modelling power bypass is kinda futile since it won't be very relevant unless you do PCB-level simulation (which is kinda unrealistic in realtime).
this kind of structure made me notice it especially when i built my yocto (an 808 clone), where you can clearly see an array of repeated Rs and Cs, when i looked at the schematic:
the 808 uses regulators to make +15V and -15V rails. but then those don't go directly to the synth like that - instead, the +15V goes into each subcircuit (each drum circuit) thru an R and then there's a C after it (i don't remember if it was 47R into 100u or 100R into 47u, something like that), and the same thing happens with the -15V
then when i looked back at the 303 schematic - this was also there but it's less easy to see because this is just one voice and these structures are kinda more scrambled around

so effectively this allows the sub-circuit to draw a lot of current only for short amounts of time, and the current then comes from the capacitor, and the voltage goes down, but after some time it'll charge back up to normal thru the resistor.
not sure if this scheme has a name, but basically could be reducing the interference/noise between the different voices. another effect it has is that if you look at the current drawn from the actual regulator - due to all of these structures - the current is less spiky, more "calm" (i sometimes do that in falstad too to see the average current that is drawn from a circuit that pulls current otherwise in a random fashion)

anyway... in the 303, this structure (the R and C on the voltage rail) can be found in several places, like, in the envelopes (they need to draw high current during envelope retrigger, but that happens rarely (compared to the duration of the retrigger pulse))

the "problem" is when an audio signal is AC-cupled and pulled to this
i mean, normally, you AC-couple a signal by slapping a series capacitor (at this point the other pin of the cap is floating, you need to pull it with a resistor to some voltage (source), and now this C-R makes an HPF), so you slap a pull resistor to GND or VGND or whatever
but in the 303, the pull resistor pulls not to the true voltage source, but to this structure.
so the result, afaiu, is unfortunately that the AC-coupling in many places in the 303 is not exactly a true 1st-order HPF, but this combined "hplp" structure in my picture

i tossed it in falstad, i ran a waveform thru it and scoped it
then i made a parallel structure with buffered HP and LP filter or whatever, and fed it with the same signal, and stacked the two scopes.. i fiddled with it to make the signals match (changing values, etc..)
the result and my conclusion is that the whole thing becomes 1 filter. it can't be faked with a normal HP and LP that have nothing in common (i mean like building blocks)

the AC chunks from the audio signal bleeds into the LPF which buffers the voltage source
and thus the voltage to which the HPF is being "pulled" is not a constant but has a "lowpassed ghost" from the audio signal, that's my dumb description of it at least

Q: does it matter?
A: it depends on the values

so this structure can be found on several places in the 303, but there is also some variations, particularly around the ladder inputs
on one side the VCO goes thru an HPF, on the other side, the feedback goes thru an HPF
both HPFs are pulled thru 2.2k into a common node which is not the 5.333V source but again a lowpass on 5.333V
i actually remember seeing the effect from this (without knowing why it happens) back 13+ years ago, when i was "scoping" my x0xb0x (with the soundcard)
on the side where the input enters - you could see a faint version with resonance, i was NOT expecting that, and also, on the side where the feedback enters - you could see a faint version of the raw unfilitered oscillator

now i can clearly see it in the schematic
both sides' HPFs are pulled thru 2.2k into something that is a lowpass filter (not a true V-source), which allows the two signals to "see each other"
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

so, i think i rememeber from Andy that for the simple RC lowpass, there was a trick like - pretend that the resistor is 1 ohm (so conductance then becomes 1/1 = 1) and thus the conductance can be ditched, and for the cutoff - just adjust the capacitor value
so this effectively makes the current much higher (typically) but in DSP we don't care about current, we want only the signal, which is the voltage, and since the cutoff is "Fc = 1/(2*pi*R*C)" if you ditch the resistor, you can transfer its value to the capacitor to get the same cutoff without having extra variables for it..

now i wanna try to make a more optimized version of the "hplp" structure from earlier
when the two resistors are both the same value (2.2k) i think i can still replace them then with 1-ohm. right?

however, not all instances of this "hplp" have the same values for the resistors and then i'm not sure if that's still right, or maybe something else has to be done (like "divide all resistor values by the value of the the most used resistor, such that most resistors become 1 ohm and the remaining ones will need to have a coefficient")

next, i will choose that i don't care about the 5.333V rail being 5.333V, in DSP i don't need a DC bias (and if i did, i could just add it after the output of this), so i will set that voltage source to GND to further simplify things

so i take the node equations and sprinkle some constants

Code: Select all

kill(all);
gnd: 0;
vcc: 0;
r1_g: 1;
r2_g: 1;
eq0: 0 = -r1_g*(vout-vmid)+r2_g*(vmid-vcc)+c2_g*(vmid-gnd)-c2_ieq;
eq1: 0 = -c1_g*(vin-vout)+c1_ieq+r1_g*(vout-vmid);
optimize(ratsimp(factor(expand(solve([eq0, eq1], [vmid, vout]))))), numer;

Code: Select all

t1 = 2*c1_g
t2 = c1_g+1;
t3 = 1/(t2*c2_g+t1+1);
vmid = t3*(c1_g*vin+t2*c2_ieq-c1_ieq);
vout = t3*((c1_g*c2_g+t1)*vin+c2_ieq-c1_ieq*c2_g-2*c1_ieq);
and now, the 3 temp vars are all coming from what would be cutoff paramters, so they don't have to be calculated every sample, and they could even be const (once Fc is known).
and in vout there's "(c1_g*c2_g+t1)" that can be taken out of there too, so:

Code: Select all

t1 = 2*c1_g
t2 = c1_g+1;
t3 = 1/(t2*c2_g+t1+1);
t4 = (c1_g*c2_g+t1);
vmid = t3*(c1_g*vin+t2*c2_ieq-c1_ieq);
vout = t3*(t4*vin+c2_ieq-c1_ieq*c2_g-2*c1_ieq);
and now, gotta add the init code, and the ieq memory "save":

Code: Select all

// combining the resistances with the capacitances into one:
c1_g = Fs*2*(2.2e+3*1e-6);
c2_g = Fs*2*(2.2e+3*10e-6);
t1 = 2*c1_g
t2 = c1_g+1;
t3 = 1/(t2*c2_g+t1+1);
t4 = (c1_g*c2_g+t1);
// --------------------
vmid = t3*(c1_g*vin+t2*c2_ieq-c1_ieq);
vout = t3*(t4*vin+c2_ieq-c1_ieq*c2_g-2*c1_ieq);
c1_ieq += 2.0*(c1_g*(vin-vout)-c1_ieq);
c2_ieq += 2.0*(c2_g*(vmid)-c2_ieq);
is this right?
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post Reply

Return to “DSP and Plugin Development”