Polyrhythmic Tap Sequencer



Now that I have a scale-driven mechanism for deriving chord tones, I decided use that feature to simplify the sequencer. The 25-bit quantizer goes away. Tone loop one uses the lookup part of the quantizer, so I made a version with only the queries, “how many tones (degrees) are there in the current scale” and “what is the nth tone on this scale?” Tone loop 2 still uses a quantizer.

Losing several unnecessary quantizers made it possible to use my 16-step progressions machine. There are three ways to run a progression—midi keyboard, seven-button and octave knob widget, and progression machine. With the simpler progression controllers the overall project runs at about 75% of the processor load of my most recent upload. (Remember to hit the “-key” button if you’re using rhe midi input.)

The most obvious change is the method of chord input. I made a big patch board to connect major scale intervals to one or more sequencer steps, up to 16 steps. Instead of some big switch matrix thing, I just made a place to connect a chord tone to one or more sequencer steps. The steps get to the sequencer via a 16x1 mux. The arpeggiator and the random tone generator now just select mux inputs to get a new scale tone.

To derive triads from scales, you look at scale tones, starting at reach tone of the scale (the root tone of the standard 1-3-5 triad) and counting off to get the triad and its extensions. To implement this, I decided to rotate the current scale by however many steps to place the current tone as step one. If I want a third, for example, it’ll be a minor third for some positions on
the scale and a major third on others.

I haven’t done exhaustive testing, but it does appear to be working.
2 2 loop polyrhythm tone seq chord apregg v 9.12.18-1.audulus (2.4 MB)


version 9/15/19-1

Nagging errors. To get something I could wrap my head around, i converted the sequencer internals to a C- based octave. It helped. I also reworked the sequencing of the arpeggiator. Fixed a really boneheaded indexing problem caused by the fact that musical notation does not have a “zero.” I knew that, of course, but plum forgot to apply it to the apreggiator, as it ran through the chord intervals. For now, the fixes only work over the 15-interval (two octaves + one top tonic), so it’s not yet scalable for a wider range. I’m pretty sure I can come up with a more elegant solution that scales to an arbitrary number of octaves, but my brain is still cooling off from the latest flurry of activity.

I narrowed the fill pulse to 100 microseconds. Probably not a huge effect, although now the fill lights aren’t on long enough to see. I might up the pulse to 50ms or so later on.

Fixed various limit issues with the quantizer and scale query patches. Added a new output to the quantizer (which you’ll find in the new MIDI progression patch) that gives you the scale degree (as in i, ii, iii, iv, etc) you’ve hit, based on current key and scale.

The new midi progression patch now uses a quantizer to generate the degree of scale and octave hit, and because this requires knowledge of the current key, its output becomes key-neutral, which eliminates the need for the “-key” button on the sequencer.

The complete project’s chord tone patch board is set up to produce a straight 15-step arpeggio, beginning at the tonic and ending at tonic, two octaves up. Zero Hz freq from the midi at startup still defaults to C two octaves below A440. If you are in C-Major, you shouldn’t see any sharps or flats from the arpeggiator.

2 2 loop polyrhythm tone seq chord apregg v 9:10:18-1.audulus (2.4 MB)


New one v9.18.18-1

2 2 loop polyrhythm tone seq chord apregg v 9.18.18-1.audulus (2.3 MB)

Switched to one scale for everything.

Important signal types:
I haven’t been totally consistent with signal naming in the project, but here are what I’d call the musically important signal types

  • Scale: integer (1 - 4095—Binary-derived) decimal code for various musical scales. The LSB is tonic, so scales will nearly always have an odd numbered code)
  • Key: octave-format —the current key frequency
  • Progression Octave: integer—, where 0 is original key octave
  • Progression Degree: integer (1-7)—the current degree of scale of the progression
  • Scale-rotated: integer (1 - 4095)— Scale code, bit-rotated to place the current progression degree of scale at position 1, allowing chords and arpeggios to remain in-scale (note that the code will always be an odd number if the scale is rotated correctly)
  • Progression-interval: octave-format—root frequency of the progression, normalized to the current key.
  • Melody interval: positive integer (1,2,3…)— in-scale tones, normalized to the current progression root.
  • Melody octave: integer (…-2, -1, 0, 1, 2…)—number of octaves to the current melody tone.
  • Melody interval: octave-format—melody, normalized to the current progression root.
  • o TL out: octave-format—sum of key, progression octave, progression interval, melody octave, and melody interval.

Added a “tap” button to the tone loops to allow you to tap out tones from midi if the loop is off-auto. Once you have a nice loop tapped out, you can run it over a progression.

Tone loop 2 now randomly plays any in-scale tones over a two octave (plus 1 for high-tonic). You dial in the lowest tone you want and the highest (note, this is scale-based numbering, where 1 in a seven-tone scale represents the root, 8 is the root up one octave, and 15 is the root up two octaves.

Setting both dials in tone loop 2 to the same number forces the loop to just output that one tone. If you set the upper dial lower than the upper, You get the same tones as you’d get the other way, but inverted in order. For a random set of tones, direction has no meaning, but for arpeggios, in which you’d be actually outputting sequential indexes to the mux loaded with the tones, reversing the roles of the dials would reverse the arpeggio.
SO—I’m planning to add this two-dial approach to tone loop one, and probably make a single random/arpeggio patch to be used in both tone loops, were the chord tone patch board would be used by tone loop 1 and a straight sequence would be thre arp source for loop 2.

All octave signals outside of the sequencer UI are in Audulus A440 format, for compatibility with other folks’ patches.

Inversions: to do inversions (remember, this thing arpeggiates—it doesn’t do full-voiced chords) you just place the intervals where you want. Want to put the third below the root? You can, but that slides the rest of the chord up an octave. The problem with this at present is that my method of progressing up 1-7 intervals is via a brute-force if-then-else method which falls apart at two octaves. A better one’s coming! I swear! Some lovely, naturally terminating, recursive sort of expression for an arbitrary number of octaves is right on the tip of fingers! I’m certain this is reinventing the wheel. I believe, however, that reinventing the wheel is important if you want to learn more about wheels!

Will I be using any of this stuff in a year? Dunno, but it’s fun now, and still inspiring to listen to. Keeping everything in-scale may not help it sound more interesting, but I’ve figured that to develop an ear for a musical scale, you’d need to be exposed to it properly played. I hope I’m approaching that.


This is crazy intricate. I love diving into the sub patching to see how it all ticks. Inspiring as always.


Latest, with a identical new bidirectional arpeggiator / random number generators on each tone loop. You set the start and and value on the knobs (lower knob is the start value) and the counter starts counting from start to end value. If you set the starting value higher than the ending number, a downward count results. Same value for stop or start just continues on that one value. Tone loop one uses the generator to select “sel” inputs to the patch board, so there are a maximum of 16 steps, corresponding to the 16 addresses for the patchboard. Tone loop two has its range interpreted as chord intervals, and is calculeted as follows: current scale’s tones par octave (calculated by the scale query patch) times number of octaves (currently 2), plus one to allow one tonic in the top octave.

2 2 loop polyrhythm tone seq chord apregg v 9.25.18-1.audulus (2.4 MB)

It’s connected to the progression generator again. Runs at about 60 % on my iPad Pro and at about 40% on my new old iMac (5 yo machine).

The new arpeggiator is kind of interesting in that you set the output range you want, and it scales the number of steps to fit in the 0-1 input range. This was done to allow simple switch from arpeggiator to random generator, allowing one little patch to do it all, instead of the kluge of using two hastily slapped together patches with fairly Byzantine signal/control routing.





Added resets to the new arpeggiators. Forgot you need these things to restart at each progression change!

2 2 loop polyrhythm tone seq chord apregg v 9.25.18-3.audulus (2.5 MB)


Been meaning to to this: It occurred to me yesterday that since my arpeggiators now issue scale intervals, for which the numbering scheme is zero-free, I can now properly handle the “empty time slot on the chord tone patchboard” problem.

When a time slice on the patchboard (any selector from 1 to 16) is not patched to a scale degree, a value of zero appears at the appropriate time at the patchboard output. As there is no “degree zero,” this zero value is captured and converted to an octave signal which, while legal, is too extreme for any practical audio application.

2 2 loop polyrhythm tone seq chord apregg v 9.26.18-1.audulus (2.5 MB)

At the tone sequencer, before the octave signal is converted to Hz for storage in the loop, a test for that level is made. Any sample frequency meeting that criteria triggers a zero velocity value to be stored in the “gate” sequencer, effectively killing the tone loop output for that time slice.

The tone sequencers provide the value at the “Fnull” output, to allow encoding of the octave signal:


Another wrinkle: Allowing that sudden drop of 50 octaves — even without a gate pulse — seemed to give me a peek at the step response of my modified res drum pseudo-synths! So, I added an expr to the tone sequencers that swaps in zero as the frequency (octave format) for samples that contain the Fnull value (currently -50), rather than allowing it to pass on through.

2 2 loop polyrhythm tone seq chord apregg v 9.27.18-1.audulus (2.3 MB)


Beautiful monstrosity dc! I’m attempting to do something similar and learning a lot from your work.


I appreciate the nod! God speed, Justin Carper!