M18s (0.4 update, ux improvements + output modes)


a two voice sequencer for monome norns based on the RYK M-185

Here’s a quick example of the crow standalone version of m18s controlling two sequences:

m18s uses the concept of steps and stages to tell time. each step has a specified number of stages, which can be expressed in a way similar to Morse Code.

In the above picture, voice 1, step 1 has 1 stage, and then step 2 has 8. step 3 has 3 sages, but only 2 have dots. this is because it has a different gate mode where only every 2nd stage triggers. there are 8 gate modes like this. these are:

  • “off”: don’t trigger any gates during the step
  • “single”: only trigger a gate for the first stage of the step
  • “all”: trigger a gate for every stage of the step
  • “every2”: trigger a gate every other stage
  • “every3”: trigger a gate every 3rd stage
  • “every4”: trigger a gate every 4th stage
  • “random”: (this is represented by the dots of the step dancing along to the beat) 50% chance you trigger a gate for each stage
  • “long”: (in the picture, the long solid line for voice 2, step 1) gate should go high on stage 1 and low on the last stage. If the step is 1 stage long, just do a standard gate pulse

There will be a number of programs (which will be able to be changed by scrolling with E1) which you’ll be able to use to interact with and modify the sequence. The first of these, reset is currently the only one currently implemented (so I made E1 just cycle through docs of the current interface for now). While in Reset mode you can restart the sequence to wherever the cursor is currently set to. move the cursors with E2 or E3 and reset the sequence with K2 or K3.

Note that you can change the sequence by randomizing the sequences (do this by holding K2 and K3 together.) This will cause the number of stages, stage gate modes, and note from the scale in the params menu). in the future these will be able to be set within the norns interface.

There are also a number of sequence advancing modes (currently addressable in the params menu. These are:

  • forward: go to the end and then restart back at the beginning (note: currently always resets to position 1, not what the cursor highlights. will probably change)
  • pingPong: go to the end and then go towards the beginning (note: in reverse the stages are still iterated from lowest to highest…so it’s more of a zigzag than a true reverse. will probably change this. will also probably make the cursor the reset point)
  • fixedLength: go a specific number of notes and then reset (this one is great for creating more rigid timings). this is currently the only sequencer advance mode which will restart to the cursor instead of position 1.
  • random: randomly jumps to a new note in the sequence after all the stages of the current note have finished.

legacy crow standalone version docs


crow, connected to druid or ^^derwydd so that you can modify and modulate the sequence


at the bottom of m18s.lua you can find configuration/initialization and setters sections:

you’ll find two sections of variables, one for each voice. these are the variables that crow uses to define the sequences it is running on boot.

here are those variables for voice 1, annotated:

gateLength1 = .01          # length of pulse for non-held stages
mode1 = "forward"          # direction of step advancement
                           #    can be "forward", "random",
                           #    "pingPong", or "fixedLength"
oct1 = 0                   # octave offset
fixedLength1 = 10          # for "fixedLength" mode, number of stages until reset

scale1 is the possible notes the sequence can be in 12-TET semitones
seq1 is a table of steps. each step is defined as a table of:

  1. note to play for the step
  2. number of stages until you advance to the next step
  3. stage gate mode. this can be:
    • “off”: don’t trigger any gates during the step
    • “single”: only trigger a gate for the first stage of the step
    • “all”: trigger a gate for every stage of the step
    • “every2”: trigger a gate every other stage
    • “every3”: trigger a gate every 3rd stage
    • “every4”: trigger a gate every 4th stage
    • “random”: 50% chance you trigger a gate for each stage
    • “long”: gate should go high on stage 1 and low on the last stage. If the step is 1 stage long, just do a standard gate pulse
scale1 = { 0, 4, 5, 7, 9, 12, 16, 17 }
seq1 = {
    { scale1[1], 1, "off" },
    { scale1[2], 2, "single" },
    { scale1[3], 3, "all" },
    { scale1[4], 4, "every2" },
    { scale1[5], 5, "every3" },
    { scale1[6], 6, "every4" },
    { scale1[7], 7, "random" },
    { scale1[8], 8, "long" }

Note that neither scale, nor seq have to be of length 8 (and they don’t have to be the same length either).

m18s is not a sequencer you perform with manually. Rather than an interface of knobs and switches, you are given an interface of functions which can be used to modify and modulate the sequences produced in real time. Note that you can also manually change the sequence using any of the variables mentioned in the configuration/initialization section above

Make sure crow is connected to your computer and you have one of the repl environments open, druid in the terminal or the ^^derwydd maxforlive device in ableton.

For all the following functions, _v is the voice paramter, and can be 1 or 2. this specifies which sequence you are targeting.

List of basic setters:

  • setMode(_v, _m): where _m can be “forward”, “random”, “pingPong”, or “fixedLength”
  • setFixedLength(_v, _fL): where _fL will set the fixedLength variable
  • setStepNote(_v, _s, _n): where _s is the step and _n is the note
  • setStageCount(_v, _s, _sC): where _s is the step and _sC is the stage count
  • setStageGateMode(_v, _s, _sGM): where _s is the step and _sGM can be “off”, “single”, “all”, “every2”, “every3”, “every4”, “random”, or “long”

More complex setters:

  • setThisSequenceOntoOther(_v) sets the sequence of _v onto the other sequence, replacing it
  • randomizeMode(_v) sets the sequencer advancement mode to one of the possible ones, randomly
  • randomizeStep(_v, _s) randomly sets a new note (in scale), stage length, and stage gate mode for the specified step (_s)
  • randomizeAllSteps(_v) randomizes every step of the sequence (maintains current sequence length)


Available in the maiden package manager (as soon as the commit to add it is merged!)

V 0.4 (7/26/20)

  • Bug Fixes
    • Fixed name typo in docstring
  • UX improvements (thank you for the feedback @papernoise!)
    • Make note indicator (top row) the full width of the note
    • Spacing cleanup
    • Make note numbers the note names (A, G# etc.)
    • Randomizes sequences on startup (instead of playing my test sequence on startup)
    • Allow for randomizing sequences independently
    • Shuffle of params screen to make things a little easier to use
  • Output modes (thanks to all awake contributors…used heavily as a reference for these! output modes are independently configurable and can be layered)
    • Audio output (polysub engine) can now be turned on/off
    • Midi output and channel selection
    • Dual CV/Gate output (1+2 / 3+4) via crow (both v/oct + v-trig and hz/v s-trig supported)
    • JF synth mode output with independent octave offset

V 0.3 (5/26/20)

  • initial norns version
  • move of crow standalone version to lib/crow_standalone subfolder

V 0.2 (5/9/20)

  • BUGFIX: Fix issue where changing sequence lengths could cause unresponsiveness
  • Fixed readme which I hadn’t updated the title/description from when I copied/pasted it in from another repo.
  • Added scratchpad.lua, which contains an in-prog function for printing sequences so you can paste them back in to m18s.lua
  • Added .gitignore for druid log file


  • figure out what input 2 should do. ideas are start/stop, manual reset, 2nd clock for individually clocking sequences 1 and 2. Currently thinking I might leave this intentionally blank, and then give a number of potentially useful snippets you could add.
  • introduce slew, probably per-step, along with setter function
  • introduce the concept of muting a sequence, along with setter function
  • figure out how to optimize the code length so that I’m not running up against max script length issues as I build out these other features

Also just want to shout out the RYK Modular M-185. It seems like a really well thought out module with a lot of useful programming features…there’s quite a bit more configuration and programming that you can do with it than this script touches, not to mention it seems like a very, nice playable interface. Also the manual was very good (I used it as the basis to create a skeleton of the code).


alrightee, I think I’m finished with documentation for the time being.

as far as making music with this script, some cool things I’ve been doing as I’ve been working on it:

  • randomizing the two voices with calls to randomizeAllSteps(1)/randomizeAllSteps(2) until I find something I like.
  • looking at the repl read out to figure out any parameters that don’t sound quite right, and changing them specifically with one of the setters.
  • time-synced delays really make things move in a cool way and feel like they go on forever because the sequence lengths are so strange (if you’re not using the fixedLength mode that is).
  • tomorrow my plan is to try to make some more complex generative stuff by changing the sequences over time using strokes to clock calls to my setter functions. if that turns out good I might try to use that as a basis for my lines community livestream set.

Hey that’s cool :slight_smile: I did a similar thing in maxmsp, I’m definitely going to play with your script now!

1 Like

Very very cool! I miss my Metropolis so this will be fun to mess around with. Could see this being an awesome app on Norns with some fun visuals. Maybe even adding grid support too. Any lines members out there up for moving this onto Norns?


This is really cool, @jlmitch5! I’ve been excited about learning more on coding sequencers for crow (& just friends etc) after @Galapagoose’s most recent twitch session. I had a few days off and was diving into that. This looks like answering a few questions I had after that, thanks! I came across the Vermona MeloDicer today and immediately thought about how to re-create it in crow / norns etc (video here). Anyways, thanks for this and the nice documentation.

1 Like

thank you for this wonderful script @jlmitch5. i’ve been studying Maps w/ Trent video and your other script in the past few days, a_weekend, i’ve learned so much and also really love the music you made with it. i never do any coding in my life, but so interested and been trying to understand how everything works in scripting druid for crow. it is so hard for me to grab at first, but slowly i think i’m beginning to understand a little bit now :sweat_smile: looking forward to try the M18s and study it.


Porting to norns might be something I’m interested in doing once I finish some other things, but also totally open and super stoked if someone from the community wants to first!

At a very basic level, this would be really easy to do…you could copy the script over, update the lines doing output to interfacing with something like the polyperc engine (or whichever engine you’d like really), and move to using some sort of clock on norns instead of the input 1 stuff.

Grid would lend itself well to the control of the stage count and stage gate modes. The 16 8-way sliders give the M-185 128 different stages, same as the modern grids :slight_smile:

For note entry, you could have it be something that is done with norns and encoders (and be able to map to a midi controller) or have it be on a secondary interface on the grid which appears with some sort of knob turn or button press on the norns

Of course it could definitely get more complex from there…programmable gate patterns, more fine grained probability than “coin flip”, midi/crow sync.


crow is a great platform to get started coding with. I will say the advance1/advance2 in this script are somewhat complex and hard to reason about. Partially due to all the modes and different things that can happen (though I could probably make more elegant for sure).

That being said, the stuff at the bottom of this script should be really easy to interface with, and I tried to write a lot of documentation information of how to above so people could jump in and start using them, even if you don’t have coding experience. And of course, if any questions arise about this script, feel free to reach out to me in this thread and I’ll do my best to answer.

If you are looking for a good place to start, the crow studies have a tutorial based flow which walks you through the code highly recommended. @Galapagoose has also done a few really cool live stream walk-throughs of some crow script ideas the past few weeks that would be cool to check out, you can find out more on this thread. My a weekend scripts are also pretty simple if you want to check them out, tonight.lua especially.


did a lot with m18s for my lines community set, figured I’d share some of the details here.

The first 9 minutes use a modified version of the script (gist here), that maps input 2 to a 8-position selector (which I control manually with a 0-5v offset knob from my quadratt). I did this so that I could change the sequence as time went on.

11-14 minutes in, the tape is playing back some early experiments as I was writing m18s, overdubbed and pitched down using ableton’s “beats” warping algorithm to turn it into some less “on the grid” and more “texture-y”

EDIT: also new version of m18s.lua (just a bugfix and some repo housekeeping)


Made a fork of the script to be usable with JF synth mode :slight_smile:

Code here: https://gist.github.com/lctrt/738c35cfd6970402e4556157f10428a6


sounds awesome! i see a Mangrove, what other oscillator?

1 Like

@electret this is awesome! Gonna have to pull this down and try it out.

@Rollingpeople thanks! It’s plaits in formant mode. They both go into 3 sisters all input.


I’ve been trying, but for some reason whenever I try and run or upload this script to crow in druid, druid just freezes and I can’t get it to work. This and the Just Friends forked script from this thread don’t work for me. I have the latest crow firmware and the latest version of Python, and still can’t get it to work. All the other scripts work fine, and I can still reset everything after quitting the Terminal. Any ideas?

1 Like

Hmm. Thanks for the report. This script is super close to the max script length…maybe it’s just not able to write it but it’s failing silently for some reason. Can you try ^^c in Druid to clear it out, and then running the script.

1 Like

Sure thing! I’ll try later tonight and report back.

1 Like

cool sounds good! Vaguely remember some stuff like that when I was developing it

Now I cleared the script on crow and when I run the m18s.lua I get:
[string “eval”]:1: syntax error near ‘m18s’

So it’s definitely different because before it was freezing up druid.

1 Like

this happened to me once where the name of the file somehow got put on the top line…can you check that? if so, could you delete it and try again?

i did just successfully run what’s on the latest master branch of the repo and it works for me btw

It was something like that ^