D2MS (Drums to Midi Synths) ....Musings on my first ever Script

So, I posted an Idea for an app over on the “Ideas” category, and it was suggested that the Process area might be a good place for me to keep the community updated on the goings on of this journey and to seek wise words and encouragement to carry on with what will no doubt be a VERY mamoth task as somebody who never even changed my myspace layout back in the day, let alone tried to devise and code a LUA script…

so, without further ado, let me introduce to you my script idea ( reposted from the original “ideas” thread for completeness…

=============The Idea ===========

OK folks, this might be a long one so I will try and break it down into chunks to keep interest

Working Name – D2MS (a drum-to-midi-synth)

Overview – A bridge to take non-melodic “drum trigger” midi note data and reinterpret it as timing (and dynamics) data to be used by melodic sequenced or “constrained-random” data.

Background – My first exposure to the concept here is the awesome drummer Andre Duracell, who used drum triggers running into a computer to create step advances ( and shifts between sequences) in sequences pre-prepared on his computer .
I wished to work from this idea base to create something that could operate this way without a full laptop setup , and also extend the scope of the project to take in “constrained variable randomisation“ (i.e. give me a bass motif off my kick drum , notes within two octaves of middle C on my snare, change the bass drums root note each time I tap my tom and make it all generate within C major etc)
The niche of this idea is using static Midi notes to drive “Lanes” of midi melodic note data , rather than the more conventional use of triggering other drum samples in a non melodic way.

How I’ve been doing it so far (outside of Norns)…
The nearest I have managed so far is using a Midibox Seq V4 which does have a “step advance” function which uses a whole channel as a “bus” input to then tell another track to advance by one step each time a note input is revied on the receiving channel …. This got me to the following kind of situation…
Scale = Major , Root = C ,
Bus 1 receives on channel 1 from Kick drum sends to track 1 outputting on track 1 with a randomly generated 8 step pattern or notes
Bus 2 receives on channel 2 sent from my snare, which sends from a randomly generated 16 notes ( with added “humanisation” to vary these notes even more over time)
Bud 3 and 4 receive on channels 3 and 4 from both my toms but are both output to channel 3 set an octave apart with two different random sequences , this allows me to make “chords” where the higher or lower part of the chord can shift upon a hit with the other being held as a drone note.

What could a norns/grid version add?
To me there are some very obvious things that could be very useful

The first being that there is a LOT of data what is not being used in my current Midibox “proof of concept ”setup… basically we are limited to just 4 buses and they can only use the note to step advance , all other data that could be used ( I’e more notes , velocity, aftertouch, extra pedals etc is being discarded.
To me an optimal setup would contain the following

  1. Grid support for quick pattern creation / re-randomisation ( lets say a page of “lanes to select track length and note ) plus function buttons per track to set play method, randomise the notes in that lane etc.
  2. The ability to use some specified notes as “step advancers” and other midi notes to , for example, switch between patterns or modulate patterns ( for example, to change a the filter cutoff of the synth connected to midi output, or to reverse the note order of a sequence
  3. The ability to use things like the velocity data of the step advance note to control things such as a velocity of the synth being controlled…but this being de-coupled so that it could be re-parsed as a filter CC# or higher velocities leading to longer decay etc.

Why help?
Well, basically, this is me putting my dreams out there and seeing what sticks… I am loving the norns eco system and I am taking teensy steps to add a button here and there to other peoples scripts that I really love, but clearly, the scope of this idea is MUCH bigger than my current knowledge base, so I thought , in the spirit of the community, I would see if the idea resonated with anyone who might be able to run with it from a coding aspect.

---- next steps----

I decided it would be a good “ thought process” to try and write a manual for the script as if it did exist ,therefore what follows is a full manual for a how the script would work i theory.

Grid Layout Page 1 – “Performance”
This consists of four repetitions of 2 x 16 “lanes”
The top line of these lanes are “functions” that then apply to the lower 16 buttons which form a 16 step sequence grid.
It is important to note at this point that a “sequence” is simply an “order in which the selected notes will play” , it is not a sequencer in the traditional sense as the notes are diven by the incoming Midi drum hits data, not by a clock etc. …all time based data is dependent on receiving midi notes that correspond to the “driver channels” as defined in the Options page on Norns
By further extension , in Random mode, these “sequences” are basically just a “note pool” from which the random note will be drawn, to increase the likely hood of a specific note being played in random step mode, it can be inserted more times into the pool.

-------------ROW A —Functions Row----------
A1-A7 (full lit for active notes half lit for omitted notes) are the notes selection section in the chosen scale ( in all examples I will use the C major scale so , for example this would be notes C,D,E,F,G , A, B , holding any of these keys and pressing a sequence step will specify that note in the sequence to be sent at the point where that step is triggered.

A8 – Currently unused for visual definition (can be used with the shift button to activate “velocity mode”

A9-A10 +Octave and –Octave (full lit) . These buttons set which octave range of the note that will be input into the step sequence Shift + either octave button will transpose the whole sequence up or down by adding or lowering by one octave per press relative ot the input notes
A11 – Range marker button ( Half lit) – This button is held along with pressing a note on buttons A1-A7 and with help of the octave keys or within the steps of the sequence or the Sequence buttons B1-16 ….and is used similar to making open and closed quotation marks “” to define the highest and lowest notes that will be used in the random note generation and replay functions (in the case of the A1-7 notes buttons being pressed) or the steps to play between in the case of the sequence B1-16 being pressed.

A12 - Currently unused for visual definition

A13- Sequence Direction - (toggles between off/ half/ full lit ) This specifies if the sequence is played through in order in a loop forwards , the same but backwards, or random.
A14 – Randomise (full lit) – this button would insert notes into each step of the sequence at random but constrained by the scale / octave and range selected …a repress will re randomise the pattern

A15 Sustain buttons (toggle between off and half bright) suppresses note off messages to allow for midi notes to drone and just hold the note until the next note is received
A16 Shift ( Full Lit)
This button is combined with others to allow the following functions

— Shift Functions ----
Shift+ A1-A7 takes that note out of the note pool for randomise functions (the coinciding button goes to half brightness ) another press would re-enable it.

Shift + A8 is a special function button that disables the sequence mode ( all sequence lights B1-16 dim to half brightness when ON ) … it activates “velocity mode” see OPTIONS for further info.

Shift +A9/10 ( Octave +/-) Transposes the playing sequence up of down by just one semitone allowing for on the fly transposing of the sequence

Shift + A 11 lets you re-define the midi channel on which the sequence is sending ( this can also be defined in setup and saved) with both buttons held the channel is displayed by a flashing cursor on whichever of the B1-B16 sequence steps represents the channel ( I.e B3 flashing would indicate midi channel 3)

Shift +A13 Sequence Direction : re randomises the random sequence if in random direction mode ( same underlying notes are in the actual sequence just played in a new order)

Shift + A14 Randomise : clears the sequencer of all notes

Shift + A15 Sustain – sends all notes off message to that channel to allow stuck / sustained noted to be cleared

----------ROW B – Sequence Lane ------
B1 – B16 are all steps of a playback sequence that will loop over at the row end… remember , in distance to a normal “sequencer” the step is only advanced based on the triggered input midi note received as defined in its channel setup…

Shift + B1-B16 will delete any note inserted in that step of the sequence

A note on Blank spaces – Blank spaces in the Sequence Lanes are the default of a new /cleared sequence… or can be made by shift clicking any step as this would delete the data in the step… in performance a blank space is acknowledged by the playhead moving to that step , however no midi note is output…this allows for thing like gaps in the melody during performance, i,e, a drum could be hit without always having an accompanied melodic note.
---------- Other Tracks/ Lanes ---------
We have 4 tracks to send up to 16 notes of data on each can have
• A different channel
• A different sequence
• A different playback type
• Different notes omitted from the master scale ( via shift selecting)
• A different octave and range
These for tracks are a repetition of rows A and B three motr times i.e:
Track 2 rows C and D
Track 3 rows E and F
Track 4 Rows G and H

----------- ON NORNS SCREENS AND DATA ----------
Button 1 will more between screens

Screen 1 – Performance.
(this is the screen that would be displayed with the grid as the main performance view )
This screen would give a simple overview of what Root and Scale is being used on the performance grid.
Encoder 2 would navigate the Root notes C, C#, D etc without changing the used root, whilst pressing
Button 2 would confirm the choice selected by E2 and bring it into use
Encoder 3 would navigate the Scales, Major, Minor, Lydian etc without changing the used scale, whilst pressing
Button 3 would confirm the choice selected by E2 and bring it into use

Screen 2 – Setup
This page would be navigated soley on Norns itself and would allow for the initial setup of options
Encoder 1 scrolls to each option, and when hovering on a specific option encoders 2 and 3 are used to set the highlighted options with button 2 used to cancel and changes and button 3 used to accept .

Driver Channel / Note 1 = what channel and note will control the advance of steps of Lane 1
Driver Channel / Note 2 = what channel and note will control the advance of steps of Lane 2
Driver Channel / Note 3= what channel and note will control the advance of steps of Lane 2
Driver Channel / Note 4 = what channel and note will control the advance of steps of Lane 4
Encoder 2 sets the channel Encoder 3 sets the Note , Button 2 exits the selected menu layer Button 3 accepts changes

Preserve Empty Sequence Steps - (OPTIONS YES/NO) if this is set to on steps in the sequence that have been defined as empty (no note when triggered) will be preserved when the note randomise button is used
Random Empty Steps – (OPTIONS YES / NO ) if yes, then an empty step is possible an an optin for any step in a randomised sequence lane, if no , then all 16 steps will contain note data.
If this is set to off, a note will be written to every step in the sequence ( including those outside of the defined start and end points although these wouldn’t be heard unless the points are re-expanded.

Velocity Mode Min / Max 1
Velocity Mode Min / Max 2
Velocity Mode Min / Max 3
Velocity Mode Min / Max 4 -sets lowest and highest velocity
E2 sets min E3 sets Max, B2 cancels B3 accepts changes

Velocity Invert 1
Velocity Invert 2
Velocity Invert 3
Velocity Invert 4 ( higher velocity = lower note if ON ) these are off by default.
E2 changes from off to on E3 accepts E2 canels

About Velocity Mode – velocity mode uses the same base of selecting a root/scale ( and notes within that scale ) along with a highest and lowest note point using the grid,
But rather than using the sequence steps to chose which note is played, Velocity mode slices the refined note range across the 0-127 ( or less if the range is constrained above) so that harder velocities are interpreted as higher notes within the note pool) … the smallest gap possible must not be less than 1 velocity step per defined note range ( i.e. if one octave is defined then 60 to 67 would be the smallest definable gap in velocity ) … in practical usage larger ranges allow small to medium note ranges to be mapped with reasonable intervals between each note being switched to the next ( i.e. if minimum is 40 and max is 120 then a 2 octave range would be divided so that there is a new note every 5 velocity levels ( 80 velocity levels divided by 14 note options rounded down )

Command 1 Channel / Note
Command 2 Channel / Note
Command 3 Channel / Note
Command 4 Channel / Note
These set which incoming midi channel and note will be used as a “command” E2 sets channel E3 sets note, B2 cancels B3 accepts changed values.

Command 1 – Type / Value
Command 2= Type / Value
Command 3 = Type / Value
Command 4 = Type / Value
Options of Command Type are as follows: CC/Rand/Rev/Retrig

CC = sends a midi CC number as defined in the VALUE this function uses midi velocity in a “sample and hold” way to represent value off the CC number that will be sent when a hit is detected…this is useful for (for instance) using a rimshot to alter the filter cutoff of the synth that is played with the snares main midi note.

Randomise= when this specific midi channel/note combination is received, it will randomise the sequence for that defined Lane. ( i.e. you could use an auxiliary snare set to send a command channel note , to change the notes played by the bass drums Lane.

Reverse playhead, this command note will reverse the direction of the playhead in the specified Lane ( tap once to engage and once again to “reverse the reverse” back to normal

Retrig –reversing the playhead direction AND playing the note that it is reversed to … this has a specific purpose of allowing for playing back up and down a single step or few steps rapidly , therefore allowing “creccendo” by using it and the normal trigger note for that lane to re step the same note or few notes over and over again

Sequencer Velocity 1 = Min / Max
Sequencer Velocity 2 = Min / Max
Sequencer Velocity 3 = Min / Max
Sequencer Velocity 4 = Min / Max
( this sets the lowest and highest midi note velocities that will trigger the advancement of a step along the sequence lane… it is used to “tune out” specific dynamics, so that a drummer can play either soft or hard notes knowing they WON’T trigger a step advance…allowing for dynamic playing )

------------Future Expansion -----------

I would really love to have another grid page that allowed for the selection of and storage of multiples patterns per lane that could then use more “command modifiers” to for instance use a tom drum hit to switch between verse and chorus sequences or notes…however, I think there is quite enough here to be going on with.

Running Changes to Original Idea

  1. the Note section will now run over 8 steps (octave note now included) as this seemt o be inline with other exsisting code in the MusicUtils library.
  2. therefore the Shift+A8 function (velocity mode) should now be moved to Shift+A12
  3. I am considering a new function of splitting the 16 Sequence Steps into an A and B ( verse and chorus) parts… where another midi note could be used to switch between them…however I need more time to consider how to map this out.

so, today has been an interesting “getting up to speed day” after last nights late discovery of the musicUtils library , and today has spun my head in new and interesting ways… I have just spent some great time with the vimeo video by @dan_derks et al dealing with hacking a script to add midi output, as clearly, i was thinking this is some concepts I would need to become more familiar with …it also raised another thought point of how nice it might be to have an “on norns” sound making option for times where I might want to go super minimal ( with my e-drumin module being VERY customisable I could see a usage case of my nephews in Spain really getting a kick out of turning up with four clip on “tuner” piezo pickups and making sounds out of bashing tables etc)… but I digress…

so , as I am considering all this , another of Dans videos loads up…tis time dealing with Less Concepts… this is where my mind kinda blew…

so, I was not familiar with less concepts at all, ( i am sure after some jamming tonight that will change) … but I could instantly see some wonderful synergy ( or at least a starting off point) between the generate sounds based on midi clock and “stuff”… vs my idea of "hit things and make notes because of “stuff”…

So I am going to , have a really deep dig into the wonderful work I can feel ooozing out of Less Concepts to see if I can learn things form it to apply to my own small idea.


Wow. You’ve really thought it all out so well.

I was digging through my studio the other day and unearthed my midikiti drum trigger brain and was going to dust it off and plug it into my digitone but this sounds a lot more fun!

Can’t wait to see it working.


This sounds super cool, and is kind of similar to an idea I had for either norns or max after seeing the different ways some people use the sensory percussion equipment to achieve a something like this. I commend you for laying it all out so clearly and thinking through the design as a whole (I never got father than tossing the idea around in my head lol). I think this could be a cool script to pair with an electronic drum pad/kit (like the Octapad) for something more performative, but also sending midi triggers from a drum machine like the Digitakt to get more “clocked” results. A cool next step after getting the initial midi stuff figured out could be to then have the ability to load samples to “sequence” in a similar fashion.


post -weekend update…

Well, I am back down to earth with a bump :slight_smile: I set aside two evenings to try and progress my idea, feeling genuinely enthused by the groups very kind support and encouragement… I had it to mind that i could " code hack" my way to at least getting some of the “basics” in place… but almost straight way fell foul of what a certain Rummy Rumsfeld called " the unknown unknowns"…

I managed to write some commented into page stuff ( the welcome page that shows up as a script starts) so at least I know my folder and file naming is ok :slight_smile:

and decided to make the grid connect with a view to programming my button behaviours, but I kind of instantly hit a crossroads tat I could not square based on what I (don’t) know …

My only working example to date of making buttons light successfully, is the wonderful help that @Olivier gave be to add some buttons to Compass…

but from the guide I watched on vimeo ( I think it was there) there seems to be a different way to make buttons do things using tables… I was trying to follow the study that is in the “we” folder

What I drew form these two different (to me) ways of working is that buttons that behave "button like) i…e. a static main function and maybe a secondary held function … could be programmed like Oliviers example ( x/y/ brightness) where as things like the 7 ( now eight) buttons that owuld select a “scale” would be better defined as one “lump” of buttons because their behaviour would change all at once , is that makes sense …i.e. they either all changes form c major to d minor or none of them do…

so, anyways, long story short, I was a little demotivated at the “oh, I have no idea what I am doing” moment… but I am sure I can push through.


Hi all , had another full evening of diving into the tutorials , and to he honest…it’s just not clicking…

I have a lot of disconnects between kind of following step by set along many tomorrow and so on…but then trying to apply what in"think" I have learnt… I.e. when I try my “take” on getting stuff on the screen…I just get a black screen but can’t work out what’s wrong or what I did different …

Obviously to make my own script…I will need to deviate from the lessons , but apply them, but at the moment I seem to he able to follow them like recipes and they work, or deviate, and the don’t…but I lack the fundamentals to know why.

I know I have said I before, it’s those unknown unknowns again…

I might try and break my idea down differently by “what hits to try to script in what order”…if anyone can offer approaches to this wlthat would be awsome.

I am super aware of how precious everyone else’s time is…and I’m deffo wanting to learn…bit I feel that of someone could just give me the confidence that …for example …this is how we start…and here is how one button works … Then I can probably get the logic to then extend that idea myself.

Sorry for the bummed out post.

hi Phill! so glad to see you continue to engage this thread, though sorry to see the trouble you’re describing. if it helps, i have been exactly where you are – i remember many saturday mornings spent on our couch throwing my headphones off across the room as i mis-read softcut arguments and accidentally caused feedback nightmares lol

the post below has so many fantastic points of reflection, so i’ll just add that as a way to build confidence, so much can be gained by seeing what you tried and ran into issues with — eg. screen drawing is introduced in study 2, so study 1 / many tomorrows isn’t set up for screen hacking without a little oomph. many folks here (myself included) would be happy to take a peek at code you’re working on and offer advice — gist.github.com is a great way to drop work-in-progress code in front of others. there’s also the #wip channel in the norns study discord! i find that the best way to feel encouragement is to have the thing you’re working on be brought to working order through collaboration, rather than be pointed to a bunch of stuff that already works.

on that note, though, the “full experience” of the norns tutorials should take 6 weeks at least. their pacing is slow and focused + their content is very deep regardless of your coding background. they describe Lua as a coding language, introduce the ways that norns uses it to accomplish musical ideas (so, Lua plus a bunch of magic words specific to norns), and they incrementally showcase individual components of norns scripting rather than giving a ‘here’s a very robust musical tool’ mega-example. there are also so many wonderful adjacent paths to the main docs, including this recent fantastic boilerplate from @tyleretters, which totally exemplifies the ‘what basic components are present in every norns script?’ stuff.

honestly, if you just share a list of stuff that feels opaque to you after going through the existing resources, that’d be amazing. API docs (like the amazing lib/ui docs contribution from @Fardles) get built from this sort of gap identification, so please feel free to post here or DM :slight_smile:


Little edit: Please read the post above first!

First, apologies if any of the following sounds condescending. Not my intension! Just trying to encourage you!

I’m a bit of a programmer. Not professional, but I know enough to be dangerous. :smiley:

If you’ve never done any programming before, as you seem to say, it’s easy to feel like you’re getting nowhere, or feel like it’s too much, when you first start a big project like this. You might be feeling that more than most as you’ve chosen to do something which has a lot of moving parts: norns scripting, MIDI processing, grid interface, data storage and manipulation, user interface design…

Don’t feel bad. I think your frustration might just be your brain soaking things up and making connections. Hopefully you’ll reach a saturation point where things begin to click.

Stick with it, but maybe start to think about breaking down your project into manageable mini-tasks to help you progress and learn as you go along. One way to do this is to make lots of small “learning scripts” for yourself so you can get confident in specific areas before you tackle parts of the larger project.

For example, make small scripts that:

  1. Draw text and shapes to the norns screen. Nothing else, just experiment with the screen commands. Spend an evening on that.
  2. Then expand on the above by messing with norns buttons and encoders. Make something change on the screen when you press a button or change an encoder, and so on.
  3. Then start to mess about with MIDI. Maybe make a square light up on the norns screen when the norns receives a MIDI note. By then you may be more confident in knowing what the screen stuff is doing, so any “errors” are going to be with you getting used to MIDI processing.

Another approach is to do the above small steps stuff, but with an eye on the bigger picture, e.g., make a script that does something on the norns screen, and sends out one random MIDI note, when you send the norns a MIDI note from your kick drum.

Doing that will help your learn about MIDI (channels, note ons / offs, note values, note velocity, how to use the midi.connect() and midi.event stuff in the norns library) and so on.

Maybe using the above as a basis, you can then replace the “one random MIDI note” with a note from random MIDI notes stored in a Lua table? Which means learning about Lua tables. :smiley: So, more mini fun scripts, more understanding Lua tables, and then you can apply that knowledge to your slowly building bigger script, etc.

Maybe that’s the way to build up the app? Something like…

  1. Sort out what the kick drum does. It creates a new pattern of random notes. So, process the kick drum MIDI note, then create a new bunch of notes in a Lua table. You can worry about how to make sure the notes are all MIDI C major notes later. (Which is another fun and interesting mini project. :smiley: Note scales!)
  2. Sort out what the snare drum does. It progresses through the pattern of random notes. So, process the snare drum MIDI note, send out the “next” note in the pattern from the Lua table, which means keeping a counter to remember the current position in the pattern / Lua table, etc.

And so on. :slight_smile:

Again, sorry if this sounds condescending or mean or superior or something. Not what I mean at all. Maybe thinking about your big script in small chunks and building it up that way may help?

Also, comment every script you do in annoying detail, as you’ll forget what you were thinking when you come back later.

And having a list of things in a book you can cross out to say “that bit’s done!” feels good, too! :slight_smile:

Good luck!

Little edit: I forgot to add. As a friend of mine used to say, “You know you’re making progress when you see a different error message!” :smiley:


@dan_derks and @alanholding thank you both so very much for your kind words and guidance.

I decided to take a few days off the project as I was hanging my head against the wall with it , I will look again on Monday.

I must say, I am aware I am a very poor student…I am impatient and have a poor concentration span,unless I am focussed on an objective of my own divising… But there is a big hint here in breaking my idea down into smaller parts to try and show progress … I would guess a good spot could be to begin with getting the midi grid buttons lit as that is the conclusion nenbit of code that I am most familiar with

Then try to tackle printing screen menus…does that seem like a reasonable shout?

Thanks again for all the help

1 Like

That sounds like a plan. :slight_smile: Just take it slow and easy and you’ll get there.


thank you all for your kind words, I am feeling much more positive after a rather downbeat weekend… I think, another thing that may help me, is to compartmentalise the two things I need to do

  1. go through the studies and understand them
  2. build my script

I think I was kind of skimming over the studies hoping to just kit bash the bits and bobs I will need for my own purposes…however, I take the point that this is not an entiely helpful way to proceed …so I am going ot try and stick with the longer course despite my own worries of my own learning skills.

thanks again, I will maybe be away for a while, but hopefully the next post will have something positive in it.

all the best



I was working my way through the norns study on patterning and this script idea kept creeping it’s way into my mind. I decided to come up with a super simple (can’t stress ‘super simple’ enough lol) proof of concept for this script idea while playing with nested tables and trying to understand them more thoroughly. I would love to share what I came up with, @phillwilson, if you are interested. I don’t want to step on your toes regarding this script since it was your idea, but it’d be great to collaborate and help make this cool idea become a reality. Let me know and I can post my code, or if you’d rather figure it out, no worries at all!


Oh wow …what a lovely development … Yes…let’s Collab… I’m so happy that my idea sparked something inside another person…so yes totally… Would you be up for a Skype or similar to discuss it further?

I was slowly refining my thoughts too so perhaps there is a way this can benefit us both? Just drope a pm

Btw…general update…I had a massive fall whilst skating (I know, at my age I should have known better) hence the very slow updates

But I have been reading a little more whilst I heal up.

All the best