Wednesday 30 December 2020

MIDI Distribution Processor - a different approach to making a sequencer

Step sequencers tend to follow a very well-defined blueprint, and getting away from fixed step timings, deterministic playback, fixed swing, limited probability controls, boring repeated velocity and other immutable articulations can be difficult. If you look back through my MaxForLive devices then you will find a few of my attempts to break free of the constraints, and this blog post aims to highlight my latest version.

When I created a tee-shirt design featuring a fictional modular synthesizer module with controls in the shape of a Christmas Tree, the plan was not to trigger the creative process. But my mind is strange, and that triangle shape got me thinking, and before I knew it, my brain had produced an idea for a very different type of sequencer - and it was different again from the Non-Euclidean, Non-Linear sequencer that I released only a few weeks ago.

The Christmas Tree looked like one of those marble-based binary decision trees that ends up with a Gaussian distribution of outputs, where the outermost 'bins' are the least likely to end up with a marble in them, whilst the innermost on are the most likely, and there is the familiar bell-shaped curve connecting them. What struck me was that the 'tree' of decisions was allowing control over the distribution of the outputs, and it was like a light coming on inside my head: I couldn't think of any sequencer that allowed control over the distribution of notes, not even any of mine!

MIDIdistPROC

So I did some exploratory programming, then tidied it up through a couple of iterations, and finally smoothed a few rough edges. The result is MIDIdistPROC, a MIDI note distribution processor that allows you to explore what happens when you choose a set of notes, and can then control the frequency of occurrence of those notes. It is kind of like a sequencer where the concept of 'notes in a specific order' doesn't exist. 

So if you give it C, E and G (as MIDI Note Numbers!), then the simplest (and the default) distribution would be for each note to be equally likely, so you would get outputs like CEG, CGE, GEC, GCE, ECG...  If you increase the likelihood of the C, then you might get CGC, CEC, GCC, ECC...  Ultimately, if you raise the likelihood of C to the max, then you might just get CCC, CCC, CCC... That struck me as being too much like current pop song melodies, so the design deliberately doesn't allow you to go quite that far, and you will always get a few other notes sprinkled here and there. If you want to use it to generate pop song melodies then you will just have to edit those 'other' notes out. Sorry.

Velocity uses the same principle: a 'pool' of velocity values where you control the distribution, but not the order. Over time, the values will fit the specified distribution, but without requiring a fixed sequence to happen.

Previously, I have looked at different 'flavours' of randomness, and a bit of experimentation resulted in another design decision: to provide a simple 'structured' source of notes where the user controls the amount of order or disorder. So there's a 'Mix' slider which has Random notes on one extreme (the left, of course), and a rising sequence of notes on the other extreme (the right), and so you can choose how much chaos you want to inject into the notes or velocities.

Following on from the many asynchronous clocks that I've been incorporating in designs for some time, I split the clocks for the notes and the velocities, which allows you to have different rates for notes and velocities, as well as different distributions and different mixes of random or ascending values. The note clock is the master clock for generating the MIDI notes, but isn't synched to Live's transport at all, so I should probably call this a 'toolkit' - because it is intended for exploration and experimentation.

From left to right, you have two sections: notes (light purple) and velocities (light grey). Apart from a few minor details, the two sections are very similar. At the top left hand side is the Rate rotary control (shown as BPM and Hz) for the beats. This is not synched to Live's transport clock. Directly underneath is a slider with 'MIX' in the centre. This mixes between a Random source of values and an Ordered source of values (from a rising sawtooth waveform), allowing you to choose between chaos on the left and order on the right, or any mix in between. As guitar pedal manufacturers like to say: We have designed it so that all settings will produce good results!' Underneath the Mix slider is a graphical representation of the past, which fades away into oblivion as it scrolls to the right. 

Most of the section is occupied by seven slider controls. These are arranged as a binary decision tree: the values from the Mix slider are sent to the left or right of the top-most slider (the little white lights show which way the values go...), and then go to one of the two slider underneath that, where they are again sent either left or right depending on their value, and thy finally end up at the lowest set of four sliders, where they are again divided into 8 outputs, an these output s can then be mapped to MIDI Note Numbers (or Velocities) in the number boxes at the lowest edge of the device. So, depending on the value that is produced by the Mix slider, a given value will end up at one of those 8 output boxes. And those 8 boxes can be set to either MIDI Note Numbers (light purple boxes) or MIDI Velocity values (light grey boxes).

The seven sliders are used to set how the values are distributed. If you press the 'Centre' button, then th sliders will be set to their default positions. The top slider will be at 63, which means that a value of 63 or less will go left, whilst any higher value will go right. This is why it is called a 'binary' decision tree: there are only two outputs at each layer, but the three layers results in a total of 8 final outputs. (Two for the first layer, then four for the middle layer, and then eight for the third/final layer). 


Yep, the velocity section is very similar! (But greyer...)

But note that the timing, amount of randomness, and distributions are totally separate for notes and velocity values...  This means that a specific note might have very different velocity values each time it happens (or you could set all the velocities in the 'pool' of values to be the same, but that would be boring!). 

Workflow

You will need to follow MIDIdistPROC with an instrument to make sounds... I used a Collision-based Marimba sound a lot during development. Remember that the 'Centre' button resets the sliders to their mid positions, which is usually a good place to start. You will find that the sliders tend to interact, so the best approach is to start at the top slider and work downwards. Extreme slider positions may give a single output value on one side or the other, or even a single value either way if the slider above is also at an extreme value. The Note 'RateN' rotary control sets the speed at which MIDI notes are generated, whilst the Velocity 'RateV' rotary control sets the speed at which the velocity values are generated, and so changes the volume or timbre of the notes, but not their timing... The rates can be varied between 30 and 300 BPM... (Beats Per Minute, which I show as 'bpm' on the UI because I think it looks cooler! It turns out that both 'BPM' and 'bpm' can be used, although BPM is often used to mean 'Business Process Management', which is very corporate-speak and not very musical...)

This is a toolkit, which means that further processing of the outputs will probably be required, so be prepared to capture the MIDI notes and change their timing. At one stage, I did contemplate including timing distribution as well, but that quickly got very complex and it seemed better to leave it to you - plus I'm not in Plaid's league when it come to amazing uses for unusual time signatures!

Max For Live...

'Slider interactions' probably sounded interesting, so here's how the sliders are interconnected so that the upper ones affect the ones lower down. Only one layer is shown...

The upper slider has a range of 0-127 - the full range of MIDI notes from the Mix slider. The output is 63 when the default position is set by the 'Centre' button. The two sliders in the next layer down have different setups. The one on the left is going to need to have a range from 0 to the output of the upper slider, which is called 'n' in the diagram above. Sending a 'size $1' message to the slider will set its range to '0 to n' (where $1 has the value of 'n'). The slider on the right is slightly more complex. The slider needs to start at 'n' rather than zero (set by the 'min $1' message), and the range needs to be set to 128-n (so that the highest value is 127 on the far right hand side). So the 'size' message just needs to be 'size (!- 128)' to set the range correctly. 

I'm not perfect. The red 'X' shows how I made an error in logic and used the range to set the slider value - not a good idea. I located the problem and fixed it - after I did the screenshot composite shown above. So I ended up editing the M4L and the diagram! (The red cross is NOT a new MaxForLive object, of course!)

 The Asynchronous Clock is pretty straight-forward, and is included here because it shows the conversions to get the BPM and Hz values, which aren't as tricky as you might expect... The 'cycle~' object is very easy to use in this case!


 Using it

The sliders don't necessarily work the way you might expect. The more you move them across to the right, the more values will be sent to the LEFT, and vice-versa. You can watch the white indicator lights to verify this. Now that you know this, you should be okay, but you may find yourself accidentally moving the sliders the wrong way when your conscious brain hands over mousing to your subconscious brain. 

The three 'Preset' buttons for Notes and Velocities provide starting points for setting the 'pools' of output values. Feel free to use your own values! Note that the 'Octaves' preset illustrates very nicely that you do not need to have different values for all of the outputs, which is something that people tend to assume is the case. The presets also show why I didn't include any other 'Ordered' waveforms that the SawUp - you don't need them! You can change the output values to give the equivalent of any source waveform with 8 vertices. (This is more waveform choices than you get with most analogue monosynths (The MiniMoog, for example, has a mere six.) If the concept of waveforms being an emergent property at the end of a processing chain doesn't bother you, then you are in the right place!

I'm going to mention it again, because people are used to M4L sequencers that look a lot like MIDIdistPROC: This is NOT a conventional sequencer! There isn't any of the timing variation you might expect (all the notes are the same length), the notes and velocities aren't linked, and it isn't very good at repeating the same boring sequence over and over again. However, if you are interested in getting inspiration and breaking out of melodic cliches, then you may find it useful. (If you just realised why I have been referring to the output values as a 'pool' of values, then you are ready to exploit this device fully!)

One very useful piece of additional processing is the factory Ableton Live device called 'Scale', which is very good at transposing and constraining the output to a given range or scale. There are commercial plug-ins (like Scaler 2) that do similar things and more... You could also try my scale utility or my 'one control' to process the output of MIDIdistPROC. 

Getting MIDIdistPROC

You can get MIDIdistPROC here:

    https://maxforlive.com/library/device/6829/mididistproc-mr

Here are the instructions for what to do with the .amxd file that you download from MaxforLive.com:

     https://synthesizerwriter.blogspot.co.uk/2017/12/where-do-i-put-downloaded-amxd.html

(In Live 10, you can also just double-click on the .amxd file, but this puts the device in the same folder as all of the factory devices...)

Oh, yes, and sometimes last-minute fixes do get added, which is why sometimes a blog post is behind the version number of MaxForLive.com...

Modular Equivalents

In terms of basic modular equivalents, then implementing MIDIdistPROC seems like it will be quite challenging - there are not many binary tree implementations that I'm aware of, but there are so many modules out there that I could easily have overlooked some. Worse, it may well be a hidden feature of a well-known module, so I may be completely wrong and it is a doddle to implement. 

Alternatively, then there are various utility processing modules that could be used to produce an eight segment transfer function, which would achieve the same end-result. So this might be only 1 or 2 ME. (Revised after I realised that this compresses all the layers into one!)

In reality, I suspect that MIDIdistPROC would probably be implemented in a very different way, by a super smart modular guru, by looking at the requirement from a totally different viewpoint. I would love to hear about it, by the way...

Links

Non-Euclidean, Non-Linear sequencer     - MIDInonU

'one control'                                               - MIDIchronatixONE

'flavours' of randomness                            - MIDIrandomABC

my scale utility                                          - MIDINoteScalery

---

If you find my writing helpful, informative or entertaining, then please consider visiting this link:

Buy me a coffeeBuy me a coffee (Encourage me to write more posts like this one!)


Synthesizerwriter's Store
 (New 'Modular thinking' designs now available!)


No comments:

Post a Comment