How a circuit simulator hears a circuit
A circuit simulator writes one equation per node (currents in equal currents out), turns each capacitor into a step rule, and solves diodes and transistors by Newton's method, usually in 2–3 guesses a sample. SynthMaker runs diode circuits at twice the output rate and checks its models against ngspice.
circuit Clipper oversample 1x setting input: 8 V, from 0.5 V to 40 V setting output: 1.2 V R1 in out 1k D1 out gnd 1N4148 D2 gnd out 1N4148 # C1 out gnd 10nendPress Play to see the wave after the circuit, at out.
What you're hearing
The circuit is a diode clipper at its simplest. A 1 kΩ resistor feeds two 1N4148 diodes facing opposite ways. A high sine, about 1976 Hz, drives it at 8 V peak, and the diodes hold the peaks to 0.68 V. The flattened wave gains odd harmonics: the 3rd (5.9 kHz) 11 dB under the note, the 5th (9.9 kHz) 16 dB under, and on past the top of hearing.
The three buttons change only how often the circuit is worked out. At 1×, SynthMaker solves it once per output sample: 48,000 times a second at 48 kHz. At 2× it solves it 96,000 times, then a filter takes away everything above the audible band on the way back down to 48,000. At 4×, 192,000 times. The note and the level are the same on every button: the three peak within 0.2 dB of each other.
At 1×, you hear tones that aren't part of the note. Audio at 48 kHz can only hold frequencies up to 24 kHz. The clipped wave's harmonics go on far past that, and they can't simply vanish: each one folds back into the band, mirrored at 24 kHz or a multiple of 48 kHz. That's aliasing. The 13th harmonic, at 25.7 kHz, lands at 22.3 kHz. The 25th, at 49.4 kHz, lands at 1.4 kHz, right beside the note. Folded tones don't belong to the note's harmonic series, so they sound like a faint, out-of-tune whistle under it. Here the strongest is 30 dB under the note.
At 2× and 4×, the folding moves out of earshot. At 96 kHz, a harmonic has to pass 48 kHz before it folds at all, and most of what folds lands above 24 kHz, where the filter takes it away. Only harmonics above 72 kHz (96 kHz minus 24 kHz) fold back into the audible band, and they're far weaker. At 4×, only those above 168 kHz do. The strongest stray tone falls from 30 dB under the note at 1× to 51 dB at 2× and 65 dB at 4×.
From parts to equations
At every node, the currents in add up to the currents out. That's Kirchhoff's current law: charge can't pile up at a point, so whatever flows into a node flows out again. A node is any point where parts meet, and a simulator writes one such equation for each one. This circuit has one node besides the input and ground: out, where R1 and both diodes meet.
Worked by hand: the current through R1 equals the current through the diodes. Call the node's voltage V. R1 carries (Vin − V) / 1 kΩ into it. D1 carries Is (e^(V / n·Vt) − 1) down to ground, and D2, facing the other way, carries the same with −V. For the 1N4148 model, Is = 2.52 nA and n·Vt = 45.3 mV. So the node's equation is:
(Vin − V) / 1 kΩ = Is (e^(V / 45.3 mV) − 1) − Is (e^(−V / 45.3 mV) − 1)
At the peak, Vin = 8 V and V = 0.6744 V. R1 carries (8 − 0.6744) / 1 kΩ = 7.3 mA. D1 carries 2.52 nA × (e^(0.6744 / 0.04532) − 1), also 7.3 mA. D2 leaks 2.5 nA the other way, too little to matter. Currents in equal currents out. The model also has 0.57 Ω inside each diode, which adds about 4 mV: SynthMaker's answer is 0.679 V.
A voltage source adds an equation of its own. The input, a supply or an ideal op-amp's output sets a voltage rather than a current, so each one gets an extra row. Nodes plus sources: that's modified nodal analysis, the way SPICE simulators set up a circuit.
The straight-line parts are worked out once, not every sample. Resistors and capacitors give straight-line equations. Whenever a value changes, SynthMaker solves those once, by Gaussian elimination, into a few small tables of numbers. Each sample then leaves only the nonlinear parts to find: here two unknowns, one per diode. Knobs are read every 16 samples, and working the tables out again takes 170–270 ns. This is the nodal DK method (Yeh 2009; Holters and Zölzer 2015).
Capacitors: a step rule with a memory
A capacitor's current depends on how fast its voltage changes. Its law is i = C dv/dt. So the current can't be worked out from this instant alone: the simulator has to remember where the voltage was a sample ago. That memory is what gives a circuit a sense of time, and it's why capacitors make filters.
The trapezoidal rule turns a capacitor into a resistor and a remembered current. Over one step of T seconds, it averages the current at the start and the end of the step:
i[n] = (2C / T) × (v[n] − v[n−1]) − i[n−1]
To the node's equation, that's a conductance of 2C / T plus a current carried over from the last step. A 10 nF capacitor at 96 kHz (T = 10.4 µs) looks like 1.92 mS, a 521 Ω resistor, with a current beside it that remembers the past. At 48 kHz it looks like 1,042 Ω. After each step, the simulator updates that remembered current. Coils get the same rule the other way round, a conductance of T / 2L.
The rule's error falls about four times for each doubling of the rate. On a clipper with a 10 nF capacitor, driven by a 1 kHz sine of 4 V, SynthMaker is 6.4 mV rms away from ngspice at 48 kHz, 2.1 mV at 96 kHz, 0.44 mV at 192 kHz and 0.10 mV at 384 kHz. The clipped peak is 0.6 V.
A circuit of resistors, capacitors and ideal op-amps needs no guessing. It's then exactly a digital filter: the analog circuit through the bilinear transform. The one cost is a slight squeeze at the top of the range. An RC low-pass (1 kΩ, 100 nF) at 1× is 0.43 dB off the analog curve at 6 kHz, and oversampling shrinks that.
Newton's method: guess and correct
A diode's current is an exponential, so the node's equation can't be rearranged for V. Newton's method finds V instead. It starts from a guess, follows the straight line that touches the curve there, and jumps to where that line crosses zero. Then it does the same again from the new point.
Worked by hand: four steps from 0.65 V. Take the peak, 8 V in, and leave out the diode's 0.57 Ω for simplicity. From a guess of 0.65 V, the steps land at 0.6823 V, 0.6751 V, 0.67442 V and 0.674411 V, and the next step moves it by less than a nanovolt. The guess is 24 mV off, then 8 mV, 0.6 mV and 4.5 µV. Once it's close, each step roughly doubles the number of correct digits.
In practice the guess is the last sample's answer, so 2–3 steps are enough. One sample later the voltage has hardly moved, so Newton starts close. On music, SynthMaker's circuits take 2–3 steps a sample. The diode pedal from the diode clipper page takes 2.6 at 1× and 2.2 at 2×, because at a higher rate each sample moves less. Driven hard on a high note, the clipper on this page works harder: 4.5, 3.9 and 3.5 steps a sample at 1×, 2× and 4×. Each answer is held to a nanovolt. Each step is limited the way SPICE limits a diode's, so a guess can't shoot far up the exponential. A diode circuit gets at most 8 steps a sample; circuits with op-amps or transistors get 16.
Transistors bring more unknowns. A transistor has two junctions, each like a diode, and each one's current depends on both voltages. So every full-model transistor adds two unknowns that Newton solves together. The transistor ladder filter's 12 transistors make 25 unknowns with the full model, and 13 with the simpler model that page plays.
Oversampling and aliasing
Oversampling runs the circuit faster than the output, then filters it down. A linear circuit runs at 1×, because it makes no new harmonics and has nothing to fold. A circuit with diodes, an op-amp's rails, transistors or a noise source runs at 2×, and one with a real op-amp model (a 741 or a TL072) at 4×. A parts list can choose its own rate with a line such as oversample 4x.
The filters on the way down are steep. They're half-band filters: 59 taps for 2×, and 31 more for 4×. They're flat to 0.4 times the output rate (19.2 kHz at 48 kHz) and about 90 dB down where aliases would land in the band. The cost is a short delay: 29 samples at 2×, 0.6 ms at 48 kHz.
Sharp corners fold far more than gentle curves. SynthMaker's own check uses this very circuit. Driven by a 1 kHz sine of 2 V, its aliases are 60 dB under the harmonics at 1×, 101 dB at 2× and 149 dB at 4×. Driven by a 5 kHz sine of 8 V, nearly a square wave, they're 9, 16 and 37 dB under. A square wave's harmonics fall only as 1/k (k is the harmonic's number), so some fold even at 4×. The same goes for hard clipping's sharp corners: their harmonics reach further up, so more of them fold.
Oversampling isn't the only cure. The antiderivative method changes the formula instead: it takes the curve's average between one sample and the next, which rounds off the corners that alias. On a transistor wavefolder's formula, built as a code module on the wavefolders paper page, the antiderivative method at 2× matches 4× oversampling.
Speed: why bigger circuits cost more
A small circuit costs about what a filter does. On our test machine, an RC low-pass takes 8–10 ns per voice per sample. The diode pedal takes 102–118 ns at 1×, 168–189 ns at 2× and 321–369 ns at 4×. At 2× that's about 1% of one processor core per voice. The time goes on Newton's 2–3 steps, each an exponential per diode and a small solve, at twice the rate, plus the oversampler's filters.
The solve grows faster than the circuit. Each Newton step solves a small system by Gaussian elimination, and its work grows with the cube of the number of unknowns: double the circuit, and each step can take up to eight times as long. Before the speed-ups below, the full-model ladder filter spent 65% of its time on that elimination. In a research test, a chain of 1 to 32 buffered transistor stages, solved whole, went from 150 ns to 43,456 ns a sample.
The speed-ups so far leave the sound bit for bit the same. SynthMaker skips work whose results are never read, writes the solve out in full for each size up to 26 unknowns, and steps two voices side by side in the processor's vector instructions. Together, these made the full-model ladder 32% faster, and pairing voices made the diode pedal 21–25% faster. Every render stays byte for byte what it was. Ideas that would change the sound, such as tables or a better first guess, are measured against ngspice and aren't used by default.
Splitting at buffers keeps the growth in a straight line. A buffer, such as an op-amp's output or an emitter follower, drives what comes after it without being loaded by it (see op-amp rules). So the part after a buffer can't change the part before it, and the two can be solved one after the other, exactly. In the same research test, the 32-stage chain split at its buffers took 4,835 ns a sample instead of 43,456: nine times faster. Its cost grew in a straight line with the number of stages, and its output matched the whole circuit's within −84 dB, the test's own limit.
How the simulator is checked against ngspice
ngspice is the reference. It's an open-source descendant of SPICE, the standard circuit simulator, and SynthMaker uses it only as a test tool. SynthMaker's diodes, transistors and JFETs use SPICE's own equations with ngspice's constants: Shockley's equation, the Gummel-Poon model and the Shichman-Hodges model. For each check, the same circuit goes into both, and the outputs are compared three ways.
Curves, responses and sounds in time. A curve sweeps the input slowly: this clipper's curve, from −8 V to +8 V, is within 0.1 µV of ngspice's. A response compares a linear circuit's frequency response: SynthMaker's ideal op-amp filters match ngspice's within 0.00002 dB, compared at the frequencies the bilinear transform maps them to. A sound in time sends a sine through the circuit and compares it with ngspice's own run, sample by sample.
"Within 0.01%" means the difference is a ten-thousandth of the peak. The course pages measure the difference's rms against the output's peak, across the audible band (up to 20 kHz), at the rate the page plays. A two-OTA filter at 2×, for example, is 2.9 mV rms away from ngspice on a 29.4 V peak: 0.01%. That's 80 dB under the peak. It counts only the note's own harmonics, so aliasing isn't part of that figure; the aliasing figures on this page are measured separately.
The browser and the app play the same samples. SynthMaker computes its own exponentials and logarithms, so in every check so far, a circuit renders bit for bit the same in the browser and in the app.
What the models leave out. The diodes and transistors have no capacitances of their own (the circuit's own capacitors set its tone), and nothing changes with temperature. Nothing is noisy unless a noise source is written. Op-amps are ideal unless a real model is chosen.
Try this
- Leave input at 8 V and step through the buttons. At 1×, listen under the note: there's a whistle of tones that don't belong to it, two of them at about 1.4 kHz and 2.6 kHz. At 2× it's faint, and by 4× it's gone.
- On 1×, turn input down to 0.5 V. The diodes only bend the peaks, to 0.45 V, so the high harmonics are tiny. The aliases fall to about 99 dB under the note: clean even without oversampling.
- Turn input up to 40 V and press 4×. The wave is now nearly square, and even at 4× the strongest stray tone is only about 46 dB under the note.
- Open it in SynthMaker to change the parts. Delete the
#at the start of C1's line. The circuit now has a capacitor, so it has a memory: 1 kΩ and 10 nF make a low-pass at 1/(2π × 1 kΩ × 10 nF) ≈ 15.9 kHz between the peaks, which softens the clipped corners. Or changeoversample 1xto2xand hear the whistle go.
The parts list
circuit Clipper setting input: 8 V, from 0.5 V to 40 V setting output: 1.2 V oversample 1x R1 in out 1k D1 out gnd 1N4148 D2 gnd out 1N4148 # C1 out gnd 10nendThis is the circuit SynthMaker's own aliasing check uses. The buttons play it at 1×, 2× and 4×; the parts list as written plays at 1×.
How we checked it
Checked against ngspice, a standard circuit simulator: this circuit's curve, swept from −8 V to +8 V, is within 0.1 µV of ngspice's. Its aliasing figures for the 1 kHz and 5 kHz sines are SynthMaker's own measurements of this circuit.
Build it step by step
- The circuit format: Your first circuit, for writing parts, nodes and settings in a parts list.
- A diode clipper, built part by part: the lesson A distortion pedal from six parts (opens in a new tab) and its video, This distortion pedal is six lines of text: a real circuit, simulated. The video loads only when tapped.
Next and previous
- Previous: What makes analog sound analog: tolerance, drift, noise and sag (planned)
- Next: A synth voice from parts (planned)
Further reading
- D. T. Yeh, "Digital Implementation of Musical Distortion Circuits by Analysis and Simulation", PhD thesis, Stanford University, 2009 (the DK method). PDF
- M. Holters and U. Zölzer, "A Generalized Method for the Derivation of Non-Linear State-Space Models from Circuit Schematics", EUSIPCO 2015. PDF
- The reference simulator and its device models: ngspice documentation; background in Wikipedia: SPICE.
- Currents in equal currents out: Wikipedia: Kirchhoff's circuit laws.
- One equation per node, plus one per source: Wikipedia: Modified nodal analysis.
- Guess and correct: Wikipedia: Newton's method.
- The capacitor's step rule: Wikipedia: Trapezoidal rule (differential equations)); for linear circuits it's the bilinear transform.
- Folding back above half the sample rate: Wikipedia: Aliasing.
- The antiderivative method, explained with patches: a 2017 wavefolder paper, read along with live circuits.