Sloth Torpor simulation
January 8, 2025 · View on GitHub
This is a software emulation of the Torpor variant of the Eurorack module Sloth Chaos by Andrew Fitch at Nonlinear Circuits. Sloth Torpor is a chaotic oscillator that emits two slowly changing voltages designated and .
The behavior of this circuit is unpredictable over time, but more orderly than random. It is often used as a low frequency control voltage in cases where an LFO would be too predictable, but a random signal would be too erratic.
Sloth Torpor provides two inputs: a performer-controlled potentiometer and a control voltage .
This document explains how the hardware design was converted into a software simulation. It requires some understanding of electronics theory and single-variable differential calculus. For a better understanding of the analysis below, I recommend watching this video.
Circuit description and definitions

The circuit consists of resistors, capacitors, and a
TL074 quad op-amp chip.
Three of the op-amps on the chip, U2, U3, and U4,
use feedback to operate as linear amplifiers.
In other words, the node voltages
, , , and
change smoothly with time and stay within well-defined limits
away from op-amp saturation.
The inverting (−) inputs to U2, U3, and U4 can be assumed
to be fixed to a voltage very near that of their noninverting (+) inputs,
which are all 0 V. These inverting inputs are called virtual grounds.
In contrast, the remaining op-amp U1 acts as a comparator
that outputs a binary state voltage
I measured the voltages above using my own construction of the circuit on a breadboard. These op-amp saturation voltages are consistent with their ±12 V Eurorack supply rail.
Circuit analysis
The analysis is based on Kirchoff's Current Law (KCL). Like water, electrical current is highly incompressible. This means that the amount of current flowing into a node must be equal to the amount of current flowing back out. By defining currents as positive when they flow into a node or negative when they flow out, KCL can be stated as: the sum of all currents flowing into a node must be equal to zero.
We use Ohm's Law for resistors:
where is the current flowing through a resistor measured in amps, is the voltage difference across the resistor's terminals in volts, and is the resistor's resistance in ohms.
For capacitors, we use the formula
where is the capacitance in farads. This tells us that the current flowing through a capacitor is proportional to how fast the voltage across its terminals is changing with respect to time.
Using KCL, the sum of currents into the node at the (−) input of U3 must be zero:
where .
The corresponding equation for the node labeled is
The op-amp U4 has the following current equation for the node connected to its inverting input:
The currents flowing through the node connected to the inverting input of U2 also sum to zero:
Software simulation
The simulation is implemented as the C++ class
SlothCircuit.
The method SlothCircuit::update is called once per
audio sample to calculate the next circuit state.
All calculations use 64-bit IEEE floating-point arithmetic
to ensure stability and convergence.
The capacitors , , and are like analog memories. Their initial charge states are boundary values for the differential equations. It is reasonable and practical to assume the circuit powers up with uncharged capacitors, so we define the initial node voltages as
The control voltage and the variable resistance are sampled once at the beginning of each time step . Although and are time-dependent inputs, inside the time span of each sample they are treated as constants.
Rewrite equation (2) to find the infinitesimal change in :
We know the values of everything on the right hand side of equation (6). We can update the value of over a finite time step by approximating the infinitesimal quantities as finite differences:
In similar fashion, use equation (3) to estimate the next value of :
Use equation (4) to estimate the next value of :
Solve equation (5) for to obtain
We could evaluate steps (7) through (10) for each successive sample to generate the output signal. But this model is too simple for good accuracy.
Refined stability and precision
Approximating infinitesimals like with finite differences like is risky for accuracy and numerical stability.
Therefore, it is better to refine the algorithm above by using iteration to converge on mean values , , , and over the continuous interval between samples and . We will do this wherever a capacitor is being charged/discharged continuously during the time interval.
Use equations (7) through (10) to compute initial estimates of , , , and , as described in the previous section.
Then calculate estimated mean values over the time interval as
We also need a representative value for the time interval. Usually will be a constant over the time interval, because the values of and almost always have the same polarity.
But the mean value requires care when and have opposite polarities, or more precisely, when . In this case, use a weighted mean value of over the time interval. Assuming that is approximately linear over the time step, let $0 \lt \alpha \lt 1z(t) = 0$. Then
Then compute the weighted mean
Now we have updated estimates for the mean values of all the voltage variables over the time interval.
Update our estimates of the voltages in the next time step by using modified versions of steps (7) through (9):
Unlike the other voltage variables, we can assume the op-amp U2
responds instanteously to its input, since there is no capacitor
to be charged or discharged. Therefore equation (10) remains valid.
We still have to re-evaluate (10) on each iteration because the
estimate of keeps changing. This yields an improved estimate
for the next value of :
Convergence and efficiency
Iterate the above steps until the values , , , and converge within tolerance.
More precisely, we keep track of the values of the voltage deltas
and define the changes in successive estimates of the deltas as
where is the convergence iteration counter. Note that increases by one every time we update our estimates of , , and .
Keep iterating and incrementing until
where is a voltage error tolerance. I use a tolerance of one picovolt (). At a sample rate of 44100 Hz, convergence almost always happens in 3 iterations, but it never takes more than 4 iterations.
It is important in general to test at different sample rates and input conditions to make sure convergence happens, and to provide a failsafe iteration limit. In my implementation, I never allow more than 5 iterations.
On a typical 64-bit processor, this algorithm generates one hour's worth of output signal at 44100 Hz using only a few seconds of CPU time. CPU overhead is thus less than 0.5% even on modest systems.