Salt - tech preview / test demo

Official support for: signaldust.com
Locked New Topic
RELATED
PRODUCTS

Post

mystran wrote:As for LM13700 .. I actually plan on adding a "not so realistic" model of that, probably as the first integrated component. All the current mirrors in that thing can make a simple filter quite expensive in terms of CPU, so IMHO an "economy" version would make a whole lot of sense here.
I don't think there is any need for even moderately extensive model of OTAs. I've done some extensive analysis some time ago, only mirrors you should care about are output pair of mirrors, for their output impedance and because they could saturate in some topologies (OTA-C with high impedance unity gain buffer, instead of opamp based integrator, Roland and SEM in short), and even in those topologies OTA output is nowhere near rails in real life synths. So, OTA output resistance is more than enough IMHO.
On input side, bias currents, hfe vs Ic variation and bulk emiter resistnace of input pair has some influence, so I would go with 3 options: a) two npns on input, ideal mirrors, and output resistance, b) same as a) but two npns replaced with VCCS, linear hfe and c) ideal OTA with just tanh for nolinearity.


BTW, it would be really nice if you could include some utility compononents, for example varibale gain inverting on noninverting amp (linear, inf Zin, 0 Zout, gain can be changed between say 30d and -30dB, in the same way as resistance of resistors), also varibale gain instrumentation amp (diff in -> single end out) and variable gain differential driver (single end in -> diff out) would be great as well. I miss those more than pnp.

Post

urosh wrote:Just few quick comments:
I find editor very easy, fast and usable (I use Simetrix most of the time), only thing I miss a bit is some way to select and move several components (not that it matter much since I haven't figured out the way to enlarge schematic, so I'm kind of limited in number of components).
Well, larger working space eventually, obviously. Kinda same with the multiple select, the whole GUI handling is mostly build for testing rather than serious use.
Distortions are working great, including Serge type wavefolder. With VCFs I had a bit of a problems regarding CPU consumption (I have rather old T7600@2GHz). Non voltage controllabe SVF with nonlinearities is ok. My machine managed to pull korgish diode ring VCF, but ladder filters were no go, second order diode ladder is ok, add third cap with diodes and it's stutter city. This is all in stereo.
Well, the amount of diode junctions to solve grows pretty quick, especially if you use transistors in a ladder (each transistor is 2 non-linearities). Sadly the time to solve the thing also usually grows faster than linear as the complexity increases. But I intend to eventually have "budget" version for transistors (assume forward bias, save half the work) and some lumped components (say transistors pairs) for situations where you don't really need everything simulated at the full detail.
BTW, that diode vcf ventured into bizzar behavior at onset of selfoscilation, I we got some intense stero effect now and then (meaning drasticaly different response from left and right channel). I'm sure you didn't model noise or parameter spread for components, so I'm not sure why this happens.
Hmmh.. pretty tiny differences in input can sometimes throw some circuits into slightly different states. IIRC there is a bit of dither which might be enough to get you different phase for self-oscillation and such.
I would really like if you could include input gain, output gain and dry gain.
Yes, also need in-circuit pots, multi I/O, probably some built-in function generators and in general a whole lot of other crap :D

Post

As for the OTA and utility stuff, yeah, something like that was what I had in mind..

Post

urosh wrote:As for LM13700 ..
You've just described all the existing macro-models provided by manufactures, and exactly what mystran was talking about implementing.

I have found however, as you would if you were working with these circuits on the bench and in spice on a regular basis, that the macro-models are better at simulating strange effects outside the audible range we're typically interested in, while they fail at reproducing many of the effects related to saturating the inputs, going beyond the rails and so on.

Those can be accomplished using the simple transistor model, which has a required prerequisite of good small signal npn + pnp models.

For circuits where you want only a rough approximation of response to inputs, saturation and output resistance I believe mystran intends to do exactly that.
urosh wrote:BTW, it would be really nice if you could include some utility compononents, for example varibale gain inverting on noninverting amp (linear, inf Zin, 0 Zout, gain can be changed between say 30d and -30dB, in the same way as resistance of resistors), also varibale gain instrumentation amp (diff in -> single end out) and variable gain differential driver (single end in -> diff out) would be great as well. I miss those more than pnp.
Here you seem to be describing a simple "voltage function" block configured for multiply. A "differential driver" you would have to construct out of ideal current mirrors or transistors.

I think it would be best to keep to the widely supported foundational building blocks you can find in existing spice implementations, and use them in the same manner. Inventing whole new models and functionality doesn't make much sense.

If macros were implemented and netlists could be typed in, including equations, you could do the computation yourself in any way you want and build a custom symbol for it.

For example:

Code: Select all

pins: v_in_p, v_in_n, v_out;
db = variable set by an input column for the macro;
gain = 10^(db/20);
v_out = (v_in_p - v_in_n) * gain;
That is a bit difficult to implement and a lot of UI work, though.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

urosh wrote:and even in those topologies OTA output is nowhere near rails in real life synths.
I just wanted to point out, also, that you're giving the "copied from reference implementations in data-sheet" circuits in synthesizers by roland as an example here.

This has nothing to do with "real life synths". In fact the majority of implementations out there won't be much like the typical bread-and-butter because they are instead designed to allow them to be driven in interesting ways.

https://soundcloud.com/aciddose/real-world-synth

This one is LM13700 based and I need to clip the inputs to the VCA or decrease the gain because the OTA is saturating there, but only on the negative. It is bypassed both at input and output, and buffered by a fet opamp (tl07x). The saturation occurs entirely in the LM13700 portion of the circuit and the transistor buffers are unused!

The levels here are 5v to 10v peak, noise is very low, around -112db. Impossible with a typical synthesizer where the noise will tend to be -80db or worse instead.

Anyway this is not an example of something you want to happen, but it is something you want to emulate correctly. Simulating this circuit with the macro-model doesn't produce this effect. A discrete transistor model does.

In the meantime I'll adjust the gain to make this work correctly. :hihi:
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

mystran wrote: Well, larger working space eventually, obviously. Kinda same with the multiple select, the whole GUI handling is mostly build for testing rather than serious use.
Doing your own GUI editor for circuit components is a lot of work, and I think you've made a great start Mystran! I decided it was too much work for me since my circuit solver is only for me so I took the easy way out, I use LTSpice to generate a netlist, which I then parse and turn into a C++ class which I compile and run as a plugin. Some day I hope to allow this to all happen dynamically, but right now it is a re-compile and a re-load of the host to listen, which is only around 10 seconds so not too bad.

mystran wrote: Well, the amount of diode junctions to solve grows pretty quick, especially if you use transistors in a ladder (each transistor is 2 non-linearities). Sadly the time to solve the thing also usually grows faster than linear as the complexity increases. But I intend to eventually have "budget" version for transistors (assume forward bias, save half the work) and some lumped components (say transistors pairs) for situations where you don't really need everything simulated at the full detail.
I've found that the time taken does increase in a roughly linear way, the systems are pretty sparse so although the linear algebra could be around O(n^2.4) to O(n^3) with the number of nodes usually this doesn't come into it, I've found that around 0-1 div and around 2-20 total add mul sub operations per node. The computational load tends to be on non-linear function evaluations, which scale linearly with the number of non-linear components. As an example I have 4 pole filter circuits with 20 nodes that solve quicker than cascading two 2 pole circuits with around 12 nodes each, (so that is 24 total nodes). If there was a ^2 thing going on then the situation would be roughly 20^2 = 400, vs 2*12^2 = 288, so the two * 2 pole should be quicker, but the 4 pole solves faster! It is purely down to the two * 2 pole circuit having more non-linear elements in total than the 4 pole circuit.

Also for the transistors I've found it useful to optionally include different parts of the model via the model definition. For example in my basic BJT model I have the following parameters:

Code: Select all

qmod1 npn is=50e-15 nf=1.0 nr=1.0 bf=206 br=4 vaf=80 var=68 rb=0.3 rc=1.2 re=0.01
If you leave out nr / nf then it only evaluates the forward / reverse exponential function, if you leave out bf / br then it sets the forward /reverse beta to be infinite and so on. So for a perfect forward biased transistor you would use:

Code: Select all

qmod1 npn is=50e-15 nf=1.0
and only one exp is evaluated.

mystran wrote: Hmmh.. pretty tiny differences in input can sometimes throw some circuits into slightly different states. IIRC there is a bit of dither which might be enough to get you different phase for self-oscillation and such.
Yep I agree here, but not even just the dither will do this, when it comes to self oscillating type things then even a tiny difference in the input signal can cause one filter to start oscillating before the other and create a phase difference in the sine waves.
The Glue, The Drop - www.cytomic.com

Post

andy-cytomic wrote: Doing your own GUI editor for circuit components is a lot of work, and I think you've made a great start Mystran! I decided it was too much work for me since my circuit solver is only for me so I took the easy way out, I use LTSpice to generate a netlist, which I then parse and turn into a C++ class which I compile and run as a plugin. Some day I hope to allow this to all happen dynamically, but right now it is a re-compile and a re-load of the host to listen, which is only around 10 seconds so not too bad.
Well, yeah there's work into the GUI editor, the current one is very simple though. That said, what the "backend" takes from the GUI is basically just a list of components and a list of wires. Doing node-unification from the set of wires is pretty trivial, so essentially my backend works from a netlist too.
mystran wrote: I've found that the time taken does increase in a roughly linear way, the systems are pretty sparse so although the linear algebra could be around O(n^2.4) to O(n^3) with the number of nodes usually this doesn't come into it, I've found that around 0-1 div and around 2-20 total add mul sub operations per node. The computational load tends to be on non-linear function evaluations, which scale linearly with the number of non-linear components.
Well, the main issue with linear algebra is that the inner iterative "Newton-core" tends to be less sparse than the overall circuit. Essentially I use block-LU reduction (well, a variant anyway) to fold any "constant detail" (resistors, etc) into the remaining nodes, then another pass for stuff that is linear (capacitors, io, etc) and then just the non-linear block runs in the inner iteration loop. This saves a lot of run-time work, but it does tend to increase density in the inner blocks. [one thing I'd like to improve is the pivoting strategies, to try to use heuristics to keep the total complexity down; currently my pivoting scheme is still a bit on the "try to get it to work" side of things]

Since the inner block runs with iteration, it tends to be the dominant factor; if that block stays small, then the non-linear evaluations dominate, but as that block grows the costs turns super-linear. It's not necessary O(n^3) but it's more than O(n) anyway. Also, approximation methods I've tried to use [so far] here mostly seems to hurt Newton convergence, leading to more iterations, and ultimately worse performance.

As for simplified component models, yes, your approach is one possibility.. using some flag parameters (eg "fwdonly") is another (might work better with UI so one can toggle simplifications and leave the reverse parameters in when doing comparisons on whether they have an effect or not).

Post

mystran wrote:Well, the amount of diode junctions to solve grows pretty quick, especially if you use transistors in a ladder (each transistor is 2 non-linearities).
What I've constantly encountered with VCF emus is is that CPU load goes trough the roof when you get close to self-oscillation. For example, in mono mode my machine manages diode ladder without much problems, up to moderate resonance. But when resonance gets closer to self-oscillation CPU load quickly increases to unusable level (another issue is that I'm not sure how reliable is CPU monitor in Reaper). Therefore, I'm quite certain that this is issue with convergence of solver. BTW, I'm not sure what "iters" mean on UI, because it wiggles below and up to 2, and if I got that correctly 16 iterations is hard limit for JIT solver. I think it would be nice to know average number of iterations and especially if hard limit of iteration numbers is reached.
mystran wrote: Hmmh.. pretty tiny differences in input can sometimes throw some circuits into slightly different states. IIRC there is a bit of dither which might be enough to get you different phase for self-oscillation and such.
It's more drastic than phase difference between oscillation on left and right channel, it exhibits almost chaotic behavior, and circuit it self should not be chaotic. It's something like this: filter is just beyond point of self-oscillation so it sustains oscillation without any input. Input level is high enough that self-oscillation is forced, so channels should be locked to some extent at least. However, now and then left or right channel bursts into distortion. Just dither noise should not do that, it seems to me there is some much more dramatic disturbance. To make a wild guess, there could be two possible causes: aliasing products throw solver into erratic behavior or, with strong positive feedback solver doesn't converge in 16 iterations, so solver produces junk and this junk is used as input for calculation of next sample so it gets weird fast. On the side note, I have noticed something else: when filter is highly resonant (near self-oscillation) it sounds a bit "grainy", and it sounds very nice when I pull down resonance a bit, so again, maybe again issue is accumulation of errors.

Post

The "iters" is simply a running average of iterations per time-step. Essentially 1 means the initial guess (or solution to a linear circuit) and higher amounts mean that additional Newton steps were taken to refine the guess.

There is currently a simple hard-limit on iterations, but it should not normally become an issue, it's mostly there to keep things from getting too badly out of hand if the solution fails to converge (when this happens, typically additional iterations don't really help anything).

As for chaotic behavior, I think I now understand what you mean. Yeah that indeed sounds like a solver glitch and there are at least some known ways to get this to happen (and sometimes even make it panic). It's unlikely that the iteration limit is an issue as such, more likely the solver runs into some ill-conditioned math; the current opamp model especially is a bit prone to causing this, thanks to the near-infinite voltages and currents it can supply instantly (which is obviously something that no real components would do).

But in any case, it's still just a tech demo, so not very robust in all situations. If you have specific (and preferably reasonably simple) test-cases that fail, feel free to send them as .fxp to (teemu@signaldust.com) and I can try to make them work in future versions.

edit: anyway, I've done some work towards rewriting the whole solver for better internal diagnostics and such (and hopefully eventually allow automatic work-arounds for problems), but this work is still rather badly "in progress". :|

Post

i don't know much about circuits,but it's a great idea.
working in eXT2 but doesn't load in eXT1.
looks great,i'll need to do some reading first i think.:)

Post

Hello mystran !

Any news on this project ? If you plan to work again on it, I'd like you to tell me since I may have a lot of things to share with you on this subject ;)

Post

Wolfen666 wrote:Hello mystran !

Any news on this project ? If you plan to work again on it, I'd like you to tell me since I may have a lot of things to share with you on this subject ;)
Oh, I haven't abandoned it, there are just a lot of components that need various amounts of changes and/or rework and right now I might not have much time to work on this specifically (putting food to the table goes first) ... but feel free to share.

Post

Still using Salt often, so it has my well wishins.
An Inductor would be fantastic though, even if idealized. Is there problems with numeric range trying to simulate these?

Post

I suspect the major issue is still going to be GUI stuff... At least from my own perspective GUI makes up 90% of everything.

Especially when you take into account the enjoyment / hobby aspect of writing the actual audio stuff, GUI ends up being a pain in the neck.

My perspective on this is that if it makes sense to have a spice-like script, that would also be absolutely awesome. Even if it has bugs or cryptic rules and regulations :hyper:

http://www.youtube.com/watch?v=m9wdYy3tCm4

Fifty-one seconds.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Well, when it comes to this one, there are at least half a dozen things that take 90% of time. :P

But like I said above, major contribution to the slow development here is the part where I need to have food on the table, which means I currently need to spend most of my time on stuff that actually generates me income.

Locked

Return to “Signaldust”