Carn
Three great digital engines playing each other's hearts out.
carn · Welsh for a cairn, a pile of stones · said KARN, with a rolled r
Mellt, Tant and Tonnau each prove one engine. Carn puts all three on one set of voices, with one matrix, one sequencer and one set of effects reaching across them, so a plucked string can bend an FM operator and a wavetable can follow the chord. Sound and pictures come later. This page is just to whet your appetite.
Digital should do what digital does better.
Exact tuning. Bounces that repeat bit for bit. Memory as an instrument. Modulation at any rate. An instrument that knows which note it is playing. Randomness you can get back. That is the list Carn is built from. It doesn't model plates, springs, tape or anyone's hardware, and nothing on its panel pretends to. Nothing at Silicon Antiques is about modelling the real world, everything is about exploring the infinite possibilities of digital space in a never-ending quest for musically valuable treasures.
Timing comes before everything else. Every change lands on an exact sample, and two bounces of the same song are the same file. If you record a performance, you get that performance back. Any idea that breaks this is rejected, but any configuration that accepts it can then be judged on its musical value.
My test for every feature was simple. If it makes a musical decision easier, it stays. If all it does is make Carn sound like a photograph of hardware, it goes. Where an old digital behaviour is worth keeping, a stepped sweep or a cheap interpolator's grit, it comes back as Era: named and delivered via exact levers which are all at zero until you move them.
The effects are one machine.
These synths have guided a personal journey for me. I’ve learned so many new things, mostly from mistakes, and the learning started as soon as I started planning. The most useful thing I learnt planning Carn is that a delay, a chorus, a flanger, a reverb's dense core and Tant's plucked string are the same object: a buffer written now and read a moment later, with a feedback path. Change how far back the read head sits and one becomes the other. So Carn builds that object once, and the effects are front panels on it. A range control on each panel lets you slide a chorus into an echo, or a flanger into a tuned string, and hear that they were always the same thing.
The feedback path is where the music is. Anything placed in it compounds on every pass: a filter that darkens each repeat, a pitch shift that walks the repeats through the chord. A limiter always sits last in the loop, so feedback can go all the way up without running away.
Once you’ve realised these things are all the same object then it becomes obvious how and why effects can also live inside the voice. Each note gets its own chorus, its own resonator, its own small space, so a chord sounds like a section rather than a stack, and when you let go the note rings on in its tail. That costs processing, and Carn pays for it honestly, but it is worth it for the possibilities it opens up.
Modulation that follows the music.
I love an elegant solution and the modulation matrix is elegance defined. That is why the matrix is the core of Carn. All three engines, the effects and the sequencer meet in it, so connecting Tant to Mellt is a routing, not a project. Some sources can run as fast as the sound itself, and then modulation stops being movement and becomes tone: a Tant string, whose pitch is known exactly, modulating a Mellt operator. In Carn combining the Karplus-Strong equations with John Chowning’s work is a single PIN in a board.
The sources count more than seconds. A clock can count notes played, bars, or cycles of the note, so a contour lands on the phrase at any tempo. A random variation you liked is there tomorrow. And every voice knows its place in the chord: the bass can be the long one and the top the bright one, by a curve you draw once.
Carn listens, too. A follower hears a sound and fires when it starts, so a drum loop on the sidechain can play a pad's filter. Each echo can fire a shape, so the modulation echoes with the sound. And press into a released note: its tail answers.
A filter that knows the note and the time.
Every filter I can think of lives in hertz. Carn's harmonic filter counts harmonics: cutoff at eight means the eighth harmonic of whatever you play, so a sweep sounds the same on every key. Its resonance rings on exact harmonics of the note, with it or against it. Let it listen to the chord you're holding and it passes the overtones that agree. You see it as a row of harmonic bars, and you can draw on it.
The filter also knows the tempo. Its ring can last a note length and stop on the next step, and a late hit can land darker. Each step can tell the filter to carry its ring on, start clean, hold it, or save it and bring it back later. On Tonnau, another filter works along the wavetable itself: run the position into the end of the table and it bounces back.
Keep the way a sound moves.
A Carn patch comes in sections. An engine's sound can be saved on its own, as one stone of the cairn. The sources and their routings save as a rig: the way a sound moves, kept apart from the sound. Put a rig on another sound, even another engine, and it moves the same way; any routing with nowhere to land is shown, not hidden. A song becomes three things you can swap: the pattern, the sound and the rig.
Exactness is designed in.
A host hands an instrument its audio in buffers, and the size of the buffer is the host's business. An instrument that applies a change at the next buffer boundary is late by up to a whole buffer, and late by a different amount when the buffer changes. A large buffer lasts about 21 milliseconds, and a deliberate push or drag against the beat lives between 10 and 40. So nothing in Carn counts from the host's buffer. Every event carries a sample number, and where Carn needs a grid it uses its own: 16 samples long, counted from a named sample, which is the note's own start for a voice and the song position for anything global.
Think of a ruler laid along the note from its first sample, with a mark every 16 samples. The ruler belongs to the note, not to the host. A stepped change that arrives between two marks takes effect on the next mark, and one that arrives on a mark takes effect there. At 48 kHz the marks are a third of a millisecond apart. What falls outside this is named too. A control moved by hand on Carn's own panel while playing live carries no sample number, and neither does a value the host passes across once per buffer without one. Each takes effect at the start of the next buffer. The panel case never arises in a bounce.
A stepped setting changed under a sounding note (a table, a filter's routing, a drive curve) switches on that grid sample and doesn't jump. Old and new both run, from copies of the same state, and the output crosses from one to the other in a straight line over a hundredth of a second: each sample a little less of the old and a little more of the new, until the last sample is the new one and nothing else. The length is a whole number of samples, 480 at 48 kHz, and the weights are whole-number fractions of it, so nothing in the crossfade can depend on the buffer. Every smoothing in Carn is declared this way: a name, a rule and a length in whole samples. A smoothing with no name doesn't exist.
Landing on the right sample still doesn't make two bounces the same file, because floating-point addition depends on its order:
in 32-bit floats, with e = 2^−24: (1 + e) + e = 1 1 + (e + e) = 1 + 2^−23
e is a number so small that a 32-bit float can't tell 1 + e from 1: it is half the gap between 1 and the next number a float can hold. Add it to 1 and it rounds away. Add it again and it rounds away again. But add the two small numbers to each other first and together they are big enough to survive. Three numbers, two answers, and the only difference is the order. So every sum in Carn has a fixed order: routings add in the order of one list of names, and events that share a sample are taken in track order, then note order. For the same reason the build fixes whether a multiply and an add are rounded once or twice. The compiler isn't left to choose.
What I claim, then: on one machine, the same bits at every buffer size and from any starting point in the song, and two bounces that are the same file. I don't claim the last bit between different machines. Their arithmetic differs in just these ways, and I'd sooner say so.
The same rule decides what is left out. Processing that looks ahead at the audio adds delay, so Carn has none: the limiter acts on the sample in front of it, and bands are split with minimum-phase filters. And each rule is written together with the faults its test has to catch: a crossfade one sample short, a switch off the grid, a state not copied. A test that passes with the fault in proves nothing.
The loop, written down.
The object under the delay, the chorus, the flanger and Tant's string is one line of arithmetic.
y[n] = x[n] + g · y[n − D[n]]
x is what goes in and y is what comes out. D is how far back the read head sits, in samples, and g is how much of what it reads is fed back in. In words: the output is the input, plus a scaled copy of the output from a moment ago.
Hold D steady and the loop favours any frequency that fits a whole number of times into its length, because each trip round arrives in step with the last one and adds to it. So its response is a row of evenly spaced peaks: one pitch and all its harmonics, the pitch being the one whose period is the length of the loop. Turn the feedback upside down, with g negative, and the peaks move halfway along: the odd harmonics of a note an octave lower, and hollow.
The effect names are ranges of that one distance. Under 2 ms the peaks are 500 Hz or more apart, and sweeping the distance with the feedback up is a flanger. From 5 to 30 ms a moving read head is chorus and vibrato, because a read head that moves is a change of pitch, the same thing you hear when a siren goes past. A read head falling back a hundredth of a sample on every sample plays 1 per cent flat. From 30 ms up the ear hears a repeat. And when the loop is exactly one period of a note long, with g close to 1, it rings at that note and all its harmonics, which is a string (Karplus and Strong, 1983). The A at 110 Hz is a loop about 9 ms long: inside the chorus range. A range control on a panel is this one number.
Each pass multiplies what is in the loop by g, and a short loop goes round more often than a long one: thousands of times a second for a high note, a few dozen for a low one. So a fixed g gives every note the same number of cycles, not the same number of seconds, and the bass would ring far longer than the top. Tant's Decay is in seconds, the time to fall by 60 dB, and it is the same on every key, so the loss per pass can't be. For a four-second decay, the lowest C on a piano keeps about 95 per cent on each pass and the C six octaves above it keeps more than 99.9.
Put a filter in the path and the loss per pass becomes a different number at each frequency. A partial the filter trims by a hair has, after a thousand passes, been trimmed a thousand times. That is all "compounds on every pass" means, and it is why the controls I care about sit in the feedback path. A filter there doesn't set a tone. It sets a decay time for every partial.
The last thing in the path is a limiter with no memory. Each output sample is a function of its own input sample: unchanged below a knee K, bent between K and a ceiling C, flat at C.
|L(v)| ≤ C for any input v, so at any g
L is the limiter and v whatever reaches it. What goes back round the loop is never larger than C, so g can be 1, which is a freeze, or more, and the loop can't run away. K, C and the bend are set by ear; the inequality isn't. I rejected a limiter with a release time: a second time constant inside a tuned loop, and a smoothing I'd have to name. I rejected a bare hard clip as too harsh for a loop meant to run near ringing level. The cost is some mini skirt aliasing above the knee.
What I refused: true through-zero flanging. It needs either the future or a delayed dry signal, and a delayed dry signal is latency. So the flanger sweeps down to zero delay and stops there.
Tuning is in the fraction of a sample.
A delay line holds a whole number of samples, so by itself a loop can play only the pitches whose periods are a whole number of samples long, and nothing between. Low down that hardly shows: near the A at 110 Hz the loop is hundreds of samples long, and one sample more or less is about 4 cents. High up it is ruinous. Near C7 the loop is about 22 samples and one sample is three quarters of a semitone; a little higher and it is more than a semitone. And no note wants a whole number anyway: that A wants 436 samples and about a third of another. The tuning is in the fraction.
So the read head reads between samples, and in two ways, because one way can't do both jobs. At a steady pitch it reads through a one-pole all-pass (Jaffe and Smith, 1983): a very small filter that passes every frequency at exactly full level and only delays it, by a fraction of a sample set by the filter's one coefficient. So it moves the pitch and leaves the tone alone. But it has a memory, and a pitch that changes on every sample makes that memory ring. While the pitch moves, a four-point Lagrange read takes over. It takes the four samples around the spot it wants, runs the one smooth curve that passes through all four, and reads the curve at that spot. It has no memory of its own, so the spot can change on every sample. Its cost is some loss at the very top. Tant crosses between the two reads over 5 ms as a pitch starts and stops moving, and Carn's string is Tant's.
The whole loop has to add up at the note's own frequency:
D_whole + delay_ap(ω0) + delay_path(ω0) = fs / f0
On the left are the three delays in the loop: D_whole is the whole-sample part, delay_ap is the all-pass's, and delay_path is that of everything else in the feedback path (the damping filter, a dispersion stage). On the right is one period of the note, counted in samples. A filter delays different frequencies by different amounts, so each delay is measured at ω0, the note itself, and not down at zero where the sum is easier. That is what keeps a low note in tune when it is damped hard. A linear element has one delay at the note whatever the level, so it can go into this equation. Drive, a pitch shifter or a wobble has no single figure to put in. A loop with one of those in its path is marked on the panel as no longer tuning-safe. I'd sooner mark it than promise.
A stiff string isn't harmonic. Its partials run sharp, and the higher the partial the sharper it runs. The textbook stiffness number is a poor control: its useful range is a sliver, and the sliver moves with pitch. So the control is cents at the second partial, and the stiffness is solved from it at each note. Set it to one cent and the eighth partial is nearly 16 cents sharp: four times the partial number, sixteen times the stretch. The same control drives the dispersion stage in a loop and the tuning of a bank of resonators, so a string and a bank agree.
A bank is for what a loop can't do. A loop rings at whole multiples of its pitch; a bar rings at 1 : 2.76 : 5.40. A loop for each partial would ring at every harmonic of every partial, dense and costly, so each mode of a bank is one two-pole resonance, with its own pitch and its own ring time. How loud each mode starts depends on where along the length you strike, and a mode struck at a point where it doesn't move gets nothing. Strike at the middle and every even mode gets nothing, which is why Tant's pick at 50% takes out the even harmonics. A voice's bank has up to 32 modes; a global one, up to 64.
A source is a shape and something that counts.
An LFO, an envelope, a random stream and a velocity curve are one object: a shape, a position on it, and something that moves the position. The shape is a table, or a list of segments, and the output is the shape read at the position. When a clock moves the position, the position is a starting point plus the rate times a count: how many events of the source's clock have passed since a named sample, the note's own start or the song's. (That is the case of a steady rate; a rate that is itself modulated adds up step by step.) There are four clocks: samples, divisions of the beat, periods of the note, and any trigger. Take the clock away, let velocity or pitch drive the position, and the same shape is a response curve.
Because the position comes from a count, and not from how long the transport has been running, a source reads the same from any starting point in the song.
The third clock is the least familiar. A length of P periods of a note at f0 lasts
T = P / f0
seconds: the number of cycles, divided by the cycles in a second. A decay of 400 periods is over seven seconds on the A at 55 Hz and under one second on the A at 440 Hz: the same number of cycles, longer in seconds for the bass. A plain loop already keeps this clock. With a fixed gain per pass it dies away in the same number of periods at any pitch. Note time gives every source the clock a string has. I rejected making do with seconds and beats, which leaves anything proportional to pitch to be approximated by routings.
On the musical clock a cycle is a number of bars. Sources cycling every 3 and every 4 bars realign every 12 bars and then repeat exactly, with nothing random involved.
A driver can be a fact about the chord. Each voice has a rank, its place in the chord counted from the bottom, and Carn turns the rank into a position that runs evenly from 0 at the bass to 1 at the top whatever the size of the chord. (A single note sits at 0.) So one drawn shape read by that position is a voicing curve. Ties go to the note that started earlier, so two renders rank alike.
The shape can also be a random stream, and this is where repeatable matters most. Every random value is worked out from two things: a seed and a count. The seed is made, always in the same way, from the song's seed, the note's own identity and a variation number from 1 to 16 kept in the patch. The count is how many values have been drawn since the note's own sample, and it can be made to wrap round after a set length, so the stream comes back. (That is the form of it, not the code.) There is no other input, and the wall clock is never read. So a random value has an address. Variation 7 is a number a step can ask for, and it is there tomorrow. The cycle runs from 8 values up to never repeating; eight values at a sixteenth-note rate is a two-beat figure that comes back. What I refused is a generator reseeded when play starts, because then the bounce isn't the take you liked.
The matrix is a sum.
Every destination in Carn, in any engine, any effect or the sequencer, is reached through one pipeline.
v[n] = clamp( slew( curve( b + Σ_i a_i · q_i(s_i[n]) ) ) )
Read it from the inside out. b is where the knob sits. To it, each routing adds its source s times its depth a, and Σ only means "add them all up". q is an optional quantiser on a routing: to a scale, a chord, a tempo grid. Then come three things that belong to the destination, in order: curve is its response law, slew its smoothing floor, clamp its hard range. (The engines' own destinations keep the laws they came with.) A routing carries a depth and nothing more unless you ask.
The split is deliberate. Shaping kept on the destination alone can't tell a stutter from a glide into the same control. Shaping kept on the routing alone has no guard rails. So the rails are the destination's and the gesture is the routing's.
For a frequency the curve is exponential, so depths add in octaves, which is how the ear counts. Each destination has a range at a depth of 1. For pitch the engines' own figure is two octaves. For a cutoff in Tant and Tonnau it is five octaves, which makes their key tracking one routing: the note number into the cutoff, scaled so that the cutoff moves one octave for each octave played.
A sum is as fast as its fastest term. A control that is refreshed only every so often can't carry a modulation faster than half its refresh rate, because it has to catch each peak and each trough at least once. Refreshed every 64 samples at 48 kHz, a control tops out at 375 Hz; every 16 samples, at 1,500 Hz; every sample, at the whole audio band. Carn's control-rate destinations sit on its 16-sample grid, counted from each note's own start. (Mellt's keep the 32 they were built with, so that a Mellt sound arrives unchanged.) The sources themselves, the filter's cutoff and resonance, and any destination declared audio-rate (a phase, a cutoff, a delay time, a gain) are refreshed on every sample. A routing at zero depth is skipped, so a sound costs what its routings cost, not what the matrix could hold.
Two rules keep the sum exact. Its terms add in a fixed order, for the rounding reason given above. And a routing that closes a ring, a thing's output reaching back to its own input, reads the value from exactly 16 samples earlier. At 48 kHz that is a third of a millisecond, and it is the same lag at every buffer size, so a ring is always legal and always the same. Outside a ring nothing waits: one engine reaches another on the same sample.
One refusal. A per-voice source doesn't reach a global destination unless you opt in and take the newest voice's value. A chord's envelopes summed into one global control is not something anyone can predict.
A routing is stored as one line: a source's name, a destination's name, a depth. Never a row and a column. That is what lets a patch come apart. A rig is a patch's sources with every routing that starts from them. An engine's sound, one stone, travels with every routing that lands in it. On loading, a routing with both ends present is live; one that has lost an end is kept, marked dormant and shown. All three engines meet one filter block with one set of names, so a rig made on a Tant sound finds the same destinations on a Mellt sound.
Modulation fast enough to be tone.
Slow, a modulation is heard as movement. Fast enough, it is heard as tone: new partials beside the old ones. Modulate the phase of a sine at f_c with a sine at f_m (Chowning, 1973):
sin(2π·f_c·t + I · sin(2π·f_m·t))
= Σ_k J_k(I) · sin(2π·(f_c + k·f_m)·t)
k = … −2, −1, 0, 1, 2 …
The top line is the sound as it is made: a sine at the carrier frequency f_c, with its phase pushed back and forth by a second sine at f_m. The line under it is the same sound written as a stack of plain sines. I is the index: how hard the phase is pushed. The stack has a partial at the carrier, a pair one f_m either side of it, a pair two f_m either side, and so on, and nothing anywhere else. J_k(I) is the level of the k-th pair. It is a Bessel function, and you never need to work one out. What matters is that about I + 1 pairs carry nearly all the energy, so I is brightness. In Mellt a modulator at full level gives an index of 12.6.
If f_m and f_c are in a ratio of small whole numbers, every one of those partials is a multiple of one fundamental and the sound is harmonic. If not, it is a bell. What digital adds is that the ratio is a number and stays one. A modulator one cent sharp at 440 Hz is a quarter of a hertz sharp, and each pair of sidebands sits that much further again from the harmonics it should be on. Where oscillators drift, that slow churn is always there. Here it is zero until you set it.
Why the phase is the place to do this takes one more step. The other way is to swing the frequency itself, up and down by the same musical interval. But an octave up adds more hertz than an octave down takes away: from 440, up is 880 and down is 220. So the average frequency rises, and the note goes sharp as the depth goes up: by about a whole tone for a swing of an octave each way. A swing in phase has no such term: over a cycle it averages to zero, and the note stays put however hard it is driven. Every looped reader in Carn has a phase input. The filter's cutoff is exponential by default, which is how the ear hears a sweep, and has a linear setting on each routing for this case.
The modulator needn't be a sine, or even in the same engine. A Tant string is a sum of harmonics of its own pitch, which is known exactly from the length of its loop. Each of those harmonics makes sidebands of its own, and sidebands on the sidebands, but every one of them still lands on the carrier's frequency plus or minus a whole multiple of the string's pitch. So an operator at a whole-number ratio to the string stays harmonic, with no pitch detector anywhere. And the string's upper harmonics die soonest, so the push from the third fades before the second and the second before the first: the operator's spectrum narrows the way a plucked string darkens. One engine's decay law, shaping another's tone.
The cost is aliasing: partials past half the sample rate fold back. The sidebands reach about I + 1 steps of the modulator above the carrier, so the higher the note, the less index there is room for. With carrier and modulator both on the A two octaves above 440 Hz, at 48 kHz, the ceiling comes out just under what Mellt already reaches at full level. So the depth has a ceiling that follows the pitch, and a reader whose phase is being modulated is read at a higher rate and filtered back down: at twice the rate there is room for more than twice the index. (This is the kind of bound I mean, not the final rule.) Beyond what the three engines already do, Carn oversamples a reader when its phase is being modulated and not otherwise. A sweep through a table doesn't alias, and oversampling a whole voice to be safe is work spent on nothing.
A filter that counts harmonics.
A note is a fundamental f0 and partials at k · f0. A filter set in hertz does something different to partial k on every key:
set in hertz: gain of partial k = |H(k · f0 / fc)|
set in harmonics: fc = h · f0
gain of partial k = |H(k / h)|
fc is the cutoff, and H is the filter's response: how much of a partial gets through, given where it sits against the cutoff. In the top line the answer has f0, the note, in it. In the bottom lines the cutoff is itself a harmonic number h, which needn't be whole (8.5 is legal), and f0 has cancelled: it isn't in the answer at all. The eighth harmonic of every note is treated alike, a note keeps one spectrum at every pitch, and a sweep of h is one gesture on every key. A cutoff fixed at 1 kHz passes 18 harmonics of the A at 55 Hz and 2 of the A at 440 Hz.
Key tracking is a step toward this. Draw the cutoff against the pitch of the note, both in octaves, and tracking is a straight line whose slope is the tracking amount. At zero the line is flat: the cutoff ignores the keyboard and lives in hertz, which suits formants. At one it rises an octave for every octave played, and that is a harmonic number. Tant's and Tonnau's key tracking, described above, is this line with the routing's depth as the amount, read from the key and fixed when the note starts. In Carn the filter reads the voice's own pitch on every sample, bend, glide and vibrato included, and the amount is a control. (The family of law I mean, not its settled form.)
Tracking alone doesn't number the harmonics. A wavetable frame is one exact period, so its spectrum is a list of harmonics, 1 to 1,024, with nothing between them, and Carn rewrites the list directly: each harmonic is multiplied by a weight. For a lowpass the weights are full up to the cutoff harmonic and then fall by so many dB per harmonic, not per octave (the kind of curve, not the final one). The weights are a list of numbers, not a circuit's response, so the list can be a brick wall, a notch one harmonic wide, odds against evens, every third harmonic, or a shape drawn by hand. The frame is rewritten every two to three milliseconds with a crossfade. Rewriting it on every 16-sample grid mark would cost eight times as much for nothing audible, and an FFT filter on the audio itself would add a block of delay. This half is for Tonnau's tables; Mellt and Tant have no frame, and meet the other half.
The ring is a separate mechanism: up to eight resonators on whole multiples of the voice's pitch, those nearest h unless moved, weighted by closeness, so that 8 and 9 share it at h = 8.5. Ring time and sharpness are one thing seen two ways: a resonance that rings longer is a narrower peak, and one follows from the other.
Each resonator is locked to the oscillator's phase, so it can add to its partial or oppose it. In step, the two add and the partial is raised. Exactly out of step and at the same level, they cancel while the note sounds, and when the note stops the resonator rings on: a notch that rings.
The harmonics of a note seldom land on a piano key. Against the nearest key the third harmonic is 2 cents sharp, the fifth about 14 cents flat, the seventh 31 flat, the eleventh very nearly a quarter-tone flat and the thirteenth 40 sharp. So "pass the harmonics that agree with the chord" needs a tolerance. Anything between about 14 and 31 cents admits the fifth harmonic, a slightly flat major third, and refuses the seventh; where in that window it sits is a listening decision. And the count ends: the A at 880 Hz has 27 harmonics under half of 48 kHz, and no resonator sits above them.
Voices, tails and the count.
A voice in Carn can hold a delay, a resonator, a small space. When its key comes up, or its voice is taken for another note, there is still sound in those loops, and by the loop's own arithmetic it can last: a 2-second loop losing 1 dB a pass takes two minutes to fall 60 dB. Cutting it is audible. Folding it into a shared effect changes its character in mid-flight. Carn does neither. The oscillators stop, and the voice's loops, filter and modulation sources run on as a tail, still reading that key's pressure and bend.
A tail ends on a rule counted in samples. It ends when its output has stayed under a threshold for the whole of a hold time, or when it reaches the longest tail the patch allows, whichever comes first. My working figures are 90 dB below full scale for the threshold, 50 ms for the hold and 30 s for the cap, all three to be settled by ear. What is settled is that the test is made on every sample. Test once a buffer and the end lands on a buffer boundary, a different sample at each buffer size; the next note is then handed a different voice, and the bounce is a different file. The cap is there because a filter in self-oscillation, or a loop with its feedback at full, never goes quiet.
When every voice is busy, something has to give. The quietest tail goes before any held note, and after the tails the oldest held note. It isn't cut. It fades in a straight line over a hundredth of a second on a spare voice, exactly silent on its last sample, while the new note starts on its own sample. "Quietest" is read from each voice's envelope on the sample of the event, with ties settled by voice number. So the choice is a function of the events and nothing else, and two renders take the same voices.
Where work can be saved without changing a bit, it is saved. A loop is computed one sample at a time when it is shorter than 16 samples, or when its length is modulated at audio rate, and 16 at a time otherwise. The block is safe for a plain reason: if the read head sits at least 16 samples back, nothing a block of 16 reads through the delay was written inside that block. At 48 kHz a 16-sample loop is a pitch of 3,000 Hz, so a string above that takes the per-sample path. The block path is kept on one condition: that it gives the same bits as the other.
The rest costs processing, and the count says so:
N · c_voice + M · c_tail ≤ B
N is voices and M tails. c_voice is the cost of one voice: its engine, plus each per-voice effect, source and follower switched on, plus a charge for each extra unison copy. c_tail is the cost of a tail. Each cost is measured at 48 kHz. B is the budget: the busiest processor core at no more than 60 per cent on the slowest machine Carn supports, and no buffer taking more than three quarters of the time it lasts. (That is the form of the sum. The costs are measurements, and I'll print a number when they are made.) As a patch switches things on, c_voice grows and the N on the readout falls.
Ideas I didn’t run with: a fixed voice count that drops notes quietly when a patch is heavy, and a switch that trades fidelity for voices, because that gives every patch two sounds.
What Carn does.
Decided features only. The rest is below.
- Mellt, Tant and Tonnau as three parts of one instrument, on one pool of voices.
- One modulation matrix across all three engines, the effects and the sequencer, including audio-rate modulation from one engine into another.
- LFOs, envelopes, random, steps, followers and macros, all on musical clocks as well as seconds.
- Random variations you can get back, and choose per step.
- A sequencer built in: each track plays one engine or layers several, and a step can lock a setting for itself alone.
- Effects on one buffer-and-feedback machine, per voice or global, with tails that ring on.
- A resonator, sympathetic strings and a modal voice for Tant.
- One filter block for all three engines, with the harmonic filter and the clocked ring; a frame filter for Tonnau.
- Patches in sections, with sounds and rigs saved on their own.
- Mellt, Tant and Tonnau patches load as a part. Carn's filters are new, so an import may sound different, and Carn says what changed.
On the bench.
The sequencer's arpeggiator and chord steps, the final list and names of the effects, the reverb's detail and whether Carn has scenes are all open. The voice count will be measured, not estimated, before I print it.
Questions, or something you'd like Carn to do? Email [email protected]. Changes to the plan go on the Workbench as they happen.