SILICONAntiques™
12 Nov 2026Mellt FM-1, Tant KS-2 and Tonnau WT-3 are out: version 1.0.0, free.Apple Silicon only for now; the universal build for Intel Macs is next.What I'm doing this week →
Silicon Antiques › Coming soon › Arweinydd
Coming soon · planned, not finished

Arweinydd

A step sequencer that teaches new tricks to old dogs.

arweinydd · Welsh for a conductor · said ar-WAY-nith (th as in "the")

Arweinydd makes no sound of its own. It plays the synths in your room over MIDI, with the same sequencer as the other instruments I'm building, and it knows each synth by name and by how long it takes to answer. Where it can be exact, it is; where it can't, it measures and tells you. The ambition is sample-accurate timing from beautiful analog gear.

The thinking

The step owns its values.

A parameter lock is a value that belongs to a step. Copy the step and the filter setting comes with it. Move the pattern and the lock moves. Delete the note and the lock goes.

In a DAW the same thing is an automation lane beside the notes, and it drifts from them the moment either is edited. Automation is a curve drawn over time; a lock is a fact about a step. A filter that opens on the third step of every bar, a release that's long on the downbeat and short everywhere else: each is one value on one step, and it stays there through every edit.

Arweinydd sends each lock as the message your synth understands, shown on screen in the synth's own words, and sends it before the step's note, so the synth is already set when the note sounds.

Think in patterns, not bars.

A song is a chain of patterns, and a pattern is a set of tracks that needn't agree about length or speed. A bass line of thirteen steps runs against a part of sixteen; they drift apart and come back round. A step can play on every third pass, or when the step before it didn't, or some of the time, by a rule that gives the same answer every time the song plays. A value can grow a little on each pass and reset at the top.

That's how parts evolve without randomness: nothing changes by accident, and nothing repeats for a long time. Scenes hold whole states of a pattern for you to move between, and they're sent to the rig.

It's the same sequencer as Dwndwr and Carn. Learn one and you know the others. But the sequencer is just one part of the chain.

Knowing the hardware.

Every synth gets a profile, and the profile is the heart of the thing. It holds the synth's parameters by name and the message each one takes, how many notes it can play at once, its quirks, and how long your chain takes to answer. So the sequencer speaks in Cutoff and Resonance, not in controller numbers.

You can build the map by turning the synth's own knobs: Arweinydd hears each one, proposes the row, and you name it. The map is the half you can share with other owners of the same synth. Once Arweinydd is live we plan to host maps for as many synths as we can on this site. You show us yours and we’ll show you ours. The timing really is yours, because the delay belongs to the whole path, from the plug-in through your interface and cable to the oscillator, and it's kept with the date and conditions it was measured under.

Measured, not typed in.

Arweinydd plays a short test song; you record your synth playing it and drop the recording on the Measure page. It finds every note's onset and works out how late that synth sounds. From then on it sends to that synth early by exactly that much, so its notes land on the beat with the rest of the rig. A patch change goes early the same way, so the new sound is ready on the downbeat.

It also measures how much the synth wanders from note to note, and shows you that as a fact about the instrument rather than pretending to correct it.

Arweinydd doesn’t expect you to accommodate it, it learns your studio and does it your way, just better.

Honest timing.

Every message leaves Arweinydd on its exact sample, in a fixed order, the same at any buffer size. After that, the host, the interface, the cable and the synth itself each take their share, and no plug-in can make a cable faster. So everything past that point is measured and shown, never pretended.

The screen shows what Arweinydd last sent, not what the synth "is at". It says when someone has turned a knob on the synth itself. It says when a sweep asks for more than the cable can carry: a note or a lock is one small message, a smooth sweep is many, and the lamp tells you the cable is full before the synth tells you by stuttering. And it says when a note lands late: Arweinydd knows and the panel tells you.

Exact where it can be, measured where it can't, and a lamp when you ask for more than the wire can do.

The engineering

From a place to a sample.

One sample at 48 kHz lasts about twenty millionths of a second, a fifteenth of the time one byte spends on a MIDI cable, and nobody will hear it. I hold to it anyway, because "close enough" has no stopping place: a tolerance has to be some size, it's a different size at another buffer, and then nothing can be proved. Exact can be tested. Two streams of bytes are the same or they aren't, and a computer can give the same answer twice and show that it has.

A hit's place in the music is a fraction. A message's sample is a whole number. I want one sum between the two that depends on the host's sample count and on nothing else: not the buffer, not where the last hit fell, not which way a decimal happened to round. In a song at one tempo, in a host whose count gives the position, the sum is

n(g) = floor( (g0 + g) · K / T + 1/2 ) − A
K    = 60 · R
A    = floor( g0 · K / T )

g is the hit's place in the music, in quarter notes from bar 1, with its nudge and groove included. K / T is the length of a quarter note in samples, worked from the sample rate R and the tempo T exactly as the host reports it, and it is rarely a whole number. g0 is there because the host starts counting its own samples some way before bar 1, 40 quarter notes before in the host I measured, and A is where that count has got to by bar 1. The half is ordinary rounding to the nearest sample, with an exact tie going to the later one. All of it is done in whole numbers and exact fractions, never in decimals.

At 120 BPM and 44.1 kHz a sixteenth note comes to a whole number of samples and a half. The sum deals with the half by making the gaps between successive sixteenths one sample longer and one sample shorter in turn. No hit is more than half a sample from its true place and the error never grows, because every place is worked out from the count and none from the hit before. Do it the obvious way instead, rounding the gap once and adding it on each time, and the part is 8 samples out after a bar and 240 after a minute.

g0 looks like pedantry. It isn't. The host's grid of samples starts before bar 1, and it is that grid which decides where the host's own roundings fall. Take a cycle of bars 1 to 7 at 172 BPM and 44.1 kHz. Multiply it out the plain way, 28 quarter notes times the length of one, and the answer has a fraction on the end. The host plays a whole number of samples on every pass, by measurement, and it is one more than the plain sum rounds to. A sequencer that trusts the plain sum is a sample further out each time round.

Inside a buffer each message carries a stamp that says how many samples into the buffer it belongs. The buffer's size appears nowhere in the sum above, so the stream of messages is the same at buffers of 32, 64, 512 and 1,024 samples. The alternative is to stamp every message at the buffer's edge, and then a hit can be out by anything up to a whole buffer. At 48 kHz and a buffer of 512 samples that is as much as ten milliseconds, with a typical scatter of about three, and it moves whenever the buffer size does.

Two limits go with the claim. A host tells a plug-in its tempo and position once a buffer, so a start, a jump or a tempo change that the host reports part-way through one, and a tempo ramp, are exact to what the host reports and no better. And the claim ends where the bytes leave Arweinydd.

Long cycles from short loops.

The family's sequencer lays out its grid in whole numbers of one very small unit: a beat is 80,640 of them. The number looks odd and was chosen with care. It divides by two eight times over, by three twice, by five and by seven, so a step is a whole number of units at all eleven track speeds, from an eighth to four times, and so are a 240th of the shortest step and a step cut into anything up to eight equal parts. The reason for the trouble is that a third of a beat is a number a computer cannot hold exactly as a decimal, and a comparison between two such numbers is where a step gets lost or gained at a boundary. Counted in whole numbers, "is this step at or after the loop point?" has one answer.

A track comes round when its steps run out, and several tracks come round together at the earliest moment that is a whole number of laps for every one of them. Thirteen steps against sixteen, both at normal speed, meet again after 208 sixteenths: thirteen bars of 4/4, 26 seconds at 120 BPM. Slow the sixteen-step track to three-quarter speed and it is 52 bars, 104 seconds. The pattern has a length of its own, in bars, and every track starts again when the pattern does, so the pattern's length is a choice. A pattern of thirteen bars holds the thirteen-against-sixteen cycle exactly, and anything shorter cuts it.

A conditional step lengthens the cycle without lengthening the loop. The rule reads "play on pass a of every b", and it is settled by counting the track's passes and nothing else. Give the thirteen-step part one step on "1 of 3" and the sixteen-step part one on "1 of 4" and the whole comes round every 156 bars: 5 minutes 12 seconds at 120 BPM, from two loops you can see on one screen. A value that grows on each pass and then resets is the same kind of thing, an answer worked from the pass count.

"Some of the time" needs more care. The usual way to get it is a random generator that runs from step to step, and then each answer depends on every draw before it. Here the draw has no memory.

x = H( seed , pass , track , step )
plays  when  x < q

seed is a number kept in the song, q is the chance you set, and pass, track and step are the step's address: which time round, which track, which step. H is a fixed function from that address to x, a number between 0 and 1. Which function is a detail; what matters is its arguments. None of them is a clock, a buffer or a count of what has already played, so the thousandth draw can be had without the 999 before it. Back to the musical value of all this chicanery - Play from the same place in the track and the result is the same, every time and at every buffer size. In a song the pass is counted from the place in the song itself, so a bounce, a cycled stretch and a start from bar 40 agree as well. A part that surprised you last night will do it again tonight, on the same step. You find the take with the magic and Arweinydd will bottle it for you.

Even spacing by arithmetic.

A Euclidean pattern is k hits spread as evenly as n steps allow. The published route to one is Bjorklund's (2003), who wanted it for the timing of a neutron source, and Toussaint (2005) showed that the results are rhythms people already play. Bjorklund builds the pattern by repeated regrouping, which is Euclid's algorithm for the greatest common divisor in other clothes. The family's sequencer gets the same spacing from one line.

hit(i)  when  (i · k) mod n < k ,   i = 0 ... n − 1

i is the step, k the number of hits and n the length of the cycle. Walk along the steps adding k each time; a hit falls on every step where the running total reaches or passes a multiple of n. It's the rule for drawing a straight line through a grid of whole points (Bresenham, 1965): the line is perfectly even, the grid isn't, and the rule says which grid points to take so as never to drift from it.

If steps could be divided, every hit would have an ideal place, with all the gaps exactly equal. The rule puts each hit on the next whole step at or after its ideal place: never early, and less than one step late. The gaps follow from that. Every gap is one of two neighbouring lengths, a short one and one a step longer, which is what "as even as possible" means (Clough and Douthett, 1991), and the long gaps are themselves spread as evenly as possible among the short ones. That is the same question again on a smaller scale, and it's where Euclid comes in.

3 in 8     x . . x . . x .                    gaps 3 3 2
5 in 13    x . . x . . x . x . . x .          gaps 3 3 2 3 2
7 in 16    x . . x . x . x . . x . x . x .    gaps 3 2 2 3 2 2 2

An x is a step with a hit and a dot is a step without. Rotation moves every hit the same number of steps later. The one-line form and Bjorklund's regrouping make the same ring of hits and gaps. Where they differ, it is in which step they call the start, and that is what the rotation control is for.

I prefer the one line for a reason that has nothing to do with speed. It has no table and no memory. Whether a step has a hit is a question about that step, the number of hits, the length and the rotation, and about nothing that happened earlier, so the layer can be read from any step, in either direction, at any track speed, and it gives the same answer in a bounce as it did live. The layer sits under the steps you place by hand, and a hand-placed step always wins. The pattern is the answer to a sum, and you can overrule it one step at a time.

The cable, counted.

I’m not as young as I once was and a five-pin MIDI cable is the only thing in the studio slower than me, and its speed is not a matter of opinion. MIDI 1.0 sends 31,250 bits a second, and each byte travels as ten bits: a start bit, eight of data and a stop bit. The rest is arithmetic.

t_byte = 10 / 31,250 s = 320 µs
t_msg  = 320 · b µs
C      = 31,250 / 10 = 3,125 bytes a second

One byte occupies the wire for 320 millionths of a second, a message of b bytes for b times that, and C is the most the cable carries. A note-on is three bytes, so it takes just under a millisecond to arrive, and so does a seven-bit controller. A program change is two bytes and a little quicker. A fourteen-bit controller is a pair of messages, nearly two milliseconds. A fourteen-bit NRPN is four messages, two to choose the parameter and two for the value: nearly four milliseconds, four times the cost of the same move at seven bits. A clock tick is one byte and there are 24 to the quarter note, so at 120 BPM the clock takes about one and a half percent of the cable.

So "how much fits in a step?" has an answer. At 120 BPM a sixteenth note lasts an eighth of a second and has room for 130 three-byte messages. At 174 BPM it has room for 89. That is the whole cable, and all sixteen channels on the port share it: notes, note-offs, locks, sweeps and clock.

Three decisions sit inside that count.

The standard lets a sender leave out a status byte that repeats, which it calls running status, and a run of controllers then costs two bytes each. I count every message at its full length and say so. Counted that way the figure can be wrong in one direction, towards a cable fuller than the real one.

I don't round a byte to a whole number of samples. A byte lasts a little over 14 samples at 44.1 kHz and a little over 15 at 48 kHz, and the odd fraction matters. Call it 14 and the count is a whole sample out within nine bytes; call it 15 at 48 kHz and it is out within three. So the length of a byte stays an exact fraction.

And the speed belongs to the chain, not to Arweinydd. 31,250 is the default, the figure for a five-pin cable. A synth on USB carries far more, but USB delivers in frames, so a faster wire is not always a tighter one, and the measurement says what each is. A chain with no declared speed is shown as not counted. It is never shown as fitting.

What a busy step costs.

When a pattern asks for more than the cable carries, a sequencer can drop messages, thin them without saying, or let them queue. Arweinydd drops nothing and moves nothing. Every message is handed over on its own sample, in a fixed order, and the queue that follows is worked out and reported.

The model is one figure for each port: the time until which its cable is busy. When a message's sample comes round, either the cable is idle and the message starts down it at once, or the cable is busy and the message waits until it is clear. Either way the busy-until time then moves on by the length of that message. That is the whole model. It is Lindley's recurrence for a single queue (1952) with the chance taken out, because the arrivals are the song, and it is kept in whole numbers throughout. Three things are reported: how many messages waited, the longest wait rounded up to a whole sample, and the waits of clock ticks, listed apart.

The order on one sample is fixed: the clock tick, then every note-off, then the tracks in the song's order, each track's lock values ahead of its note-on. Note-offs lead so that a lock meant for a new note never reaches the old one while it is still held; on a mono synth you would hear it.

Take one step with four controller locks and a note, on an idle cable. The locks go down the wire one behind another, each waiting for the one in front, and the note-on goes last. It starts down the wire nearly four milliseconds after its sample and has arrived just under five milliseconds after it, where a bare note has arrived in just under one. So the four locks cost that note nearly four milliseconds, and one fourteen-bit NRPN lock costs the same. The order is also the lead. The note-on takes just under a millisecond to arrive after the last lock has landed, and that's the time the synth has to act on the lock. Whether it is enough is a fact about the synth, and the profile has a field for the synth's own smoothing.

Now the whole rig: sixteen tracks, each ending one note and starting another on the same downbeat. That is 32 messages and about thirty milliseconds of cable, and the last note-on waits for very nearly all of it. At 120 BPM that's about a quarter of a sixteenth. No sequencer shortens it down one cable. What a sequencer can do is refuse to make it worse, and say what it is.

Two other designs were turned down. A cap on messages per buffer, with the rest left out, makes what plays depend on the buffer size, and that is a fault, not a compromise. Counting bytes against a window for each track looks tidy, but sixteen tracks share one cable, and a window per track reports a shared cable wrongly.

A click, a threshold and a median.

The delay of a chain is a measurement, so it needs a method that gives the same figure from the same recording every time, and a reference inside that recording. The test song plays a click beside every note, from the host's own audio output, cabled straight back into a spare input. The synth is recorded on one track and the click on another, in one pass. The recording then holds both what the host called "now" and what the synth did about it.

The click is one smooth bump, 64 samples long, that swells to half of full scale and dies away again with no corner anywhere in it. Engineers call the shape a raised cosine. It is defined in samples, so it's the same shape at any rate. The shape was chosen against two others. In the theory of an ideal converter a flat pulse comes back with ripples ahead of its edge of about 9% of its height, close under the threshold below, and a single-sample spike comes back as the converter's own ringing. A smooth bump has nothing sharp in it. Nearly all of its energy lies low down, below 1,500 Hz at 48 kHz, and what little lies above falls away quickly (Harris, 1978), so there is nothing near the top of the band for a converter to ring on, and it should come back as the same bump, later.

Finding where a note starts is done on the recording as written in the file, with no smoothing and no filtering. Each note has a window that runs from its own click to the next note's click. Arweinydd finds the note's own peak in that window, and the onset is the earliest sample in the window that reaches a tenth of that peak. The threshold is relative for a reason. Turn the whole take up or down and the peak and the threshold move together, so the onset doesn't move. A fixed threshold would make the delay depend on how loud you recorded. The click is read by the same rule. Its shape is known exactly, so the sample on which it reaches a tenth of its peak is known too, and its place is counted back from there.

A note's lateness is the gap from its click to its onset, in samples. The chain's fixed delay is the median of those: line the latenesses up in order and take the middle one. With an even count I take the lower of the two middles, so the delay is always a lateness that happened and always a whole number of samples. The spread is found the same way, as the middle value of how far each note sits from that delay. All of this is taken over the song's opening group of 31 notes, unevenly spaced, in an order in which no pair of neighbouring gaps occurs twice, so any three onsets in a row say where in the song they are. I use the median because up to 15 of those 31 could be wild and it would still sit among the sound ones. An average moves for one.

The host's own share, the click's place in the recording against its place in the file, is kept apart and reported. Correcting by the latency a host says it has was turned down: those settings drift between sessions, and the reference has to be in the same recording as the thing it corrects.

Early by a whole number.

Arweinydd does not sell snake oil, nor does it predict anything. It reads the song ahead and it knows how late each chain answers, so it sends early by that much. The difficulty is in "that much". The measurement is in samples at the rate of the recording, and a song has to mean the same thing at every rate. So the song stores whole microseconds, and the two conversions are chosen as a pair.

m = ceil( D_m · 1,000,000 / R_m )
D = floor( m · R / 1,000,000 )

D_m is the measured delay in samples and R_m is the rate it was recorded at. m is what the song stores: the same delay in whole microseconds, rounded up. R is the rate of the session and D is the early figure for that output in whole samples, rounded down. Up on the way in and down on the way out: that is the pair.

Go in and come out at the same rate and you get back the count that was measured, exactly. The rounding up adds less than a microsecond, a sample at any rate in use is far longer than a microsecond, and so the rounding down takes off just what was added. Rounding down on the way in looks more natural and is wrong: a delay of one sample at 48 kHz would be stored a shade short and come back as none. At another rate the figure plays as near as that rate allows, short by less than one sample and never long by as much as a microsecond. The measured count and its rate stay with the chain as the authority. Nothing ever converts the stored figure back into a measurement.

Every message for that output, clock ticks included, leaves that many samples before the sample its hit belongs to. To do that the sequencer has to be ahead of the moment. A store of messages can hold one back; it can't send one early. So the design has the sequencer run ahead of the host's count by a declared lead, a whole number of samples fixed when play starts, and each output holds its own messages back.

made at     n − L
held for    L − D
leaves at   n − L + (L − D) = n − D

n is the sample a hit belongs to, D is that output's early figure and L is the lead, at least as long as the largest D on the port. The lead cancels out: whatever its size, the message leaves D samples before the hit. What the sequencer makes at n − L depends on the host's count alone, so the stream is the same at every buffer size. A cycle is covered, because the host reports both of its ends and the wrap sample is known beforehand.

D is the fixed part of the delay. The spread is left alone. After compensation each note lands as far from the beat as its own lateness was from the median. Apply that to the take that was measured and at least half the notes land within the spread of the beat, and none lands further out than the earliest and the latest sat from the median. Those are facts about one recording, and I show them as that. Subtracting more would not make the synth steadier.

Two other routes were turned down. A host's track delay is typed in milliseconds, sits outside any proof and doesn't move the clock ticks. Holding every output back to the slowest gets the rig together by giving up on the beat.

What a lamp may say.

A MIDI cable is one-way. Nothing comes back down it to say that a message arrived or what the synth did with it, and a synth with a panel can be changed by hand at any moment. So a screen that showed "where the synth is" would be showing a guess with a number on it. Each of Arweinydd's lamps is confined to something Arweinydd holds as a fact: what it sent, when it sent it, and what came back.

SENT is the last value sent to a parameter. It is a whole number out of a top value the profile declares for that parameter: 127 for a seven-bit controller and 16,383 for a fourteen-bit one, which travels as two bytes, a coarse half and a fine half. No value reaches the wire by way of a decimal, so the figure on the screen is the bytes and not a rounding of something else. A glide, a curve or a modulation source becomes a run of such values by one rule: send a value when it differs from the last one sent, and no sooner than a set spacing after it. The spacing is the track's or the parameter's own floor from the profile, whichever is longer. Nothing is sent when nothing has changed. When the spacing holds a change back, what goes on the next allowed sample is the latest value, not the oldest, so a sweep may be thinned but it always ends on the value the song asked for. With one parameter moving on a track, SENT trails the source by no more than the source travels in one spacing.

OVER BUDGET reads the queue: the count of messages that waited and the longest wait, from the busy-until figure above. The usual cause is a fine sweep, and the cable sets a limit of its own whatever the spacing says. A full seven-bit sweep is 127 changes and cannot take less than about an eighth of a second on an idle five-pin cable. A full fourteen-bit NRPN sweep sent value by value would take just over a minute.

SYNTH MOVED needs the synth's MIDI output connected back. It lights when the synth itself sends a value for a parameter in the map and that value is not the one Arweinydd last sent. It is a comparison of two numbers Arweinydd holds, and when they differ the screen stops claiming the knob.

LATE covers the one stretch that can't be sent early: the moment play starts, or lands after a jump. A hit that falls within the output's early figure of that moment has a message that should have left before it, and cannot have. It goes on time and lands late by the early figure, once, and the lamp says so. After that stretch nothing is late. The lamp also lights when the delay a song carries is not the one measured for the chain in front of it.

None of the four claims to know the state of the synth. Each can be checked against the bytes, which is the test I apply to anything on the screen: if it can't be shown from what was sent and what was received, it doesn't get a lamp.

What it does

What Arweinydd does.

Decided features only. The rest is below.

  • Sixteen tracks, one per MIDI channel.
  • Parameter locks in your synth's own words: Cutoff, not CC 74. Each one is sent before its note.
  • Tracks with their own length and speed, conditional steps, values that grow on each pass, Euclidean patterns, grooves, scenes, and songs built from patterns.
  • A step roll for melodic parts: chords up to what the synth can play, slides, and a key and scale to write in.
  • Step entry and live recording from your keyboard.
  • Turn the synth, not the mouse: move its own knobs as the pattern plays, and each move becomes a lock on its step.
  • A profile for each synth, its map learned by turning the synth's knobs, with six favourite controls on the front panel.
  • A Measure page that works out each synth's delay from a recording.
  • A patch for each synth on each pattern, sent early so the sound is ready.
  • The family's modulation sources on any parameter in the map, sent no faster than the cable can carry.
  • Notes, controllers (7-bit, 14-bit and NRPN), program change, pitch bend and channel pressure.
  • MIDI clock out when you want Arweinydd to lead, placed as exactly as the notes. Off unless you turn it on.
  • Lamps that tell the truth: SENT, SYNTH MOVED, OVER BUDGET and LATE.
  • Arweinydd is designed to sequence melodic parts. If you want to drive a drum machine, Dwndwr MIDI FX is the friend you are seeking.
Still being decided

On the bench.

Some of the things I’m planning aren't settled, scoped or coded yet and I'd rather say so than promise their delivery at this point: an arpeggiator of its own; playing several mono synths as one polysynth, each note going to whichever synth isn't busy; control voltage out, for synths with no MIDI socket at all; and the newer version of MIDI, for synths that describe their own controls are all at the earliest planning stage. If you want to see them move into production drop in on the Workbench where updates to the plan are recorded and dated.

If you have a room of hardware and a view on any of this, tell me: [email protected].

All five on the Coming soon page