Old thread revival:andy-cytomic wrote:I have not analysed the CEM3320, but if anyone wants to point me towards a schematic I'll be happy to
Something like this?
CEM3320 Filter designs
CEM3320 Data sheet.pdf
Old thread revival:andy-cytomic wrote:I have not analysed the CEM3320, but if anyone wants to point me towards a schematic I'll be happy to
Code: Select all
.SUBCKT LM13700 7 6 2 3 4 5
Q1 13 8 2 QPNP
Q3 13 6 15 QNPN
Q4 12 7 15 QNPN
Q5 15 5 10 QNPN
Q6 5 10 3 QNPN
Q7 14 11 3 QNPN
Q8 4 14 11 QNPN
Q2 14 13 8 QPNP
Q10 12 9 2 QPNP
Q9 4 12 9 QPNP
Q11 11 11 3 QNPN
Q12 10 10 3 QNPN
Q13 9 9 2 QPNP
Q14 8 8 2 QPNP
.MODEL QNPN NPN ()
.MODEL QPNP PNP ()
.ENDS LM13700
I guess that is the curse of IC's.aciddose wrote:Without doing component-by-component modelling which is way too expensive on current hardware, most filter designs can be broken down to a series of non-linear equations applied in specific places. It turns out that modelling a CEM3320 vs. a minimoog ladder vs. BA662 vs. LM13700 you get very similar results and it is simply a matter of adjusting the coefficients and identifying which non-linear stages can be optimized away to save on processing.
In any case it certainly isn't a lack of access to schematics or anything like that, it is more an issue of it being entirely impractical to do full component models.
Note that the linked datasheet does not contain a schematic of the internals of the chip, so we are left to assume a design such as the LM13700 or similar.
Yep, I've already got those. What I need is the internals of the triangles labelled "delta A" and "B", they are the business end of the deal. I have worked out some of how they are structured with the help of Antti, but I'm not confident until I have a chip in front of me and do some thorough investigations. The CEM3320 is not the same as a CA3080 (or LM13600/700, which are CA3080s with buffers and linearising diodes added).eXode wrote:Old thread revival:andy-cytomic wrote:I have not analysed the CEM3320, but if anyone wants to point me towards a schematic I'll be happy to
Something like this?
CEM3320 Filter designs
CEM3320 Data sheet.pdf
It's hard enough with the schematic to get an accurate model, without one it's even harder. I like to start with a full component count circuit simulation as well as the actual chip to double check against, the the full component count circuit simulation matched as close to the chip as possible and then start simplify from there.aciddose wrote:...In any case it certainly isn't a lack of access to schematics or anything like that, it is more an issue of it being entirely impractical to do full component models.
A quote from the developer of the LM13600/700 take from here:aciddose wrote:The CA3080 is a way more complicated design. Ultimately it'll simplify to the same type of model I posted for the lm13700.
If you like the SSM2040 then also check out the CEM3372, which is similar in style but even more minimal, dispensing with the darlington buffers and feeding back the signal straight from the caps.eXode wrote:Thanks for all your input.
I am myself quite interested in the SSM2040, as it imho is one of the best (i.e. musical or whatever you wan't to call it) low pass filters that I know of. It suffers from a similar problem as the CEM3320 thanks to it being an integrated circuit (i.e. actual components/OTA's used is hard to know?). I have found J. Habiles take on it which should be pretty good though.
I also found the MOTM 440 which sounds pretty darn good, and it being available as DIY you get a full component list and schematics.
Cheers Andy. I know of the CEM3372 from it's brilliant implementation in the Xpander/Matrix 12 as well. Really clever solution imho.andy-cytomic wrote:If you like the SSM2040 then also check out the CEM3372, which is similar in style but even more minimal, dispensing with the darlington buffers and feeding back the signal straight from the caps.
Code: Select all
dVc1/dt = tanh(Vin-R*Vc4) - tanh(Vc1)
dVc2/dt = tanh(Vc1) - tanh(Vc2)
dVc3/dt = tanh(Vc2) - tanh(Vc3)
dVc4/dt = tanh(Vc3) - tanh(Vc4)
Code: Select all
y1[n+1] = s1[n] + f.tanh(x[n]-R*y4[n+1]) - f.tanh(y1[n+1])
y2[n+1] = s2[n] + f.tanh(y1[n+1]) - f.tanh(y2[n+1])
y3[n+1] = s3[n] + f.tanh(y2[n+1]) - f.tanh(y3[n+1])
y4[n+1] = s4[n] + f.tanh(y3[n+1]) - f.tanh(y4[n+1])
Code: Select all
y1[n+1] = s1[n] + f.t0.(x[n]-R*y4[n+1]) - f.t1.(y1[n+1])
y2[n+1] = s2[n] + f.t1.y1[n+1] - f.t2.y2[n+1]
y3[n+1] = s3[n] + f.t2.y1[n+1] - f.t3.y3[n+1]
y4[n+1] = s4[n] + f.t3.y1[n+1] - f.t4.y4[n+1]
Code: Select all
t0 = T(x[n-0.5]-R*s4[n])
t1 = T(s1[n])
t2 = T(s2[n])
t3 = T(s3[n])
t4 = T(s4[n])
Code: Select all
y1[n+1] = s1[n] + f.tanh(x[n]-R*y4[n+1]) - f.tanh(y1[n+1])
y2[n+1] = s2[n] + f.tanh(y1[n]) - f.tanh(y2[n+1])
y3[n+1] = s3[n] + f.tanh(y2[n]) - f.tanh(y3[n+1])
y4[n+1] = s4[n] + f.tanh(y3[n]) - f.tanh(y4[n+1])
You almost certainly don't want to invert any matrices, just solve the system using LU or similar and the code should look similar enough to what I originally wrote.Wolfen666 wrote: From there, obtaining the value for each yx[n+1] is easy in theory, but the inverse matrix I got has very complicated terms, where mystran's code seems to have very short terms. So I think I made a mistake somewhere, or missed a point. Is it possible to help me here ?
Code: Select all
dvc1/dt = f.(tanh((vin-vout)/(2*Vt)) + tanh((vc2-vc1)/(2*gamma)))
dvc2/dt = f.(tanh((vc3-vc2)/(2*gamma)) - tanh((vc2-vc1)/(2*gamma)))
dvc3/dt = f.(tanh((vc4-vc3)/(2*gamma)) - tanh((vc3-vc2)/(2*gamma)))
dvc4/dt = f.(-tanh((vc4)/(6*gamma)) - tanh((vc4-vc3)/(2*gamma)))
vout = (K+1/2)*vc4
gamma = n*Vt
n = 1.836
Code: Select all
// initialization (the resonance factor is between 0 and 8 according to the article)
f = tan(Pi * cutoff/sampleRate);
r = (7.f * resonance + 0.5f);
Vt = 0.5f;
n = 1.836f;
gamma = Vt*n;
g0inv = 1.f/(2.f*Vt);
g1inv = 1.f/(2.f*gamma);
g2inv = 1.f/(6.f*gamma);
// the input x[n+1] is given by 'in', and x[n] by zi
// input with half delay
float ih = 0.5f * (in + zi);
// evaluate the non-linear factors
float t0 = f*tanhXdX((ih - r * s[3])*g0inv)*g0inv;
float t1 = f*tanhXdX((s[1]-s[0])*g1inv)*g1inv;
float t2 = f*tanhXdX((s[2]-s[1])*g1inv)*g1inv;
float t3 = f*tanhXdX((s[3]-s[2])*g1inv)*g1inv;
float t4 = f*tanhXdX((s[3])*g2inv)*g2inv;
// This formula gives the result for y3 thanks to MATLAB
float y3 = (s[2] + s[3] + t2*(s[1] + s[2] + s[3] + t1*(s[0] + s[1] + s[2] + s[3] + t0*in)) + t1*(2*s[2] + 2*s[3]))*t3 + s[3] + 2*s[3]*t1 + t2*(2*s[3] + 3*s[3]*t1);
y3 /= (t4 + t1*(2*t4 + 4) + t2*(t4 + t1*(t4 + r*t0 + 4) + 3) + 2)*t3 + t4 + t1*(2*t4 + 2) + t2*(2*t4 + t1*(3*t4 + 3) + 2) + 1;
// Other outputs
float y2 = (s[3] - (1+t4+t3)*y3) / (-t3);
float y1 = (s[2] - (1+t3+t2)*y2 + t3*y3) / (-t2);
float y0 = (s[1] - (1+t2+t1)*y1 + t2*y2) / (-t1);
float xx = (in - r*y3);
// update state
s[0] += 2 * (t0*xx + t1*(y1-y0));
s[1] += 2 * (t2*(y2-y1) - t1*(y1-y0));
s[2] += 2 * (t3*(y3-y2) - t2*(y2-y1));
s[3] += 2 * (-t4*(y3) - t3*(y3-y2));
zi = in;
out = y3*r;
© KVR Audio, Inc. 2000-2024
Submit: News, Plugins, Hosts & Apps | Advertise @ KVR | Developer Account | About KVR / Contact Us | Privacy Statement