Showing posts with label parameter step sequencer. Show all posts
Showing posts with label parameter step sequencer. Show all posts

Friday, 17 April 2020

Different Two - dual channel 'old school' step sequencer for parameter control sinking and sourcing

Sometimes you just don't see the wood for the trees. It happened to me when there was a question on the Facebook Max For Live Users group about a step sequencer. from Johan Wallen The OP wanted to control the slider values in a step sequencer with an external MIDI Controller. As it happens, one of the side effects of having a ready-made maxforlive object that does just about everything you might ever want in a step sequencer means that MaxForLive.com has many, many 'live.step'-based step sequencers available on it. But 'live.step' has limits (everything does!), and the question made me think - could you even do what was being asked for with live.step?

Bait taken. I was quickly in Max and testing out live.step, and it was true - you couldn't Apple/Cntrl-M map a MIDI controller to the sliders that control the pitch, velocity, etc. in live.step. Note that the intended usage for live.step is that you use the mouse to set the sliders, and then map the output to a parameter in another device. This was different - controlling the sliders themselves in live.step with a MIDI Controller. Challenge accepted.

Not using live.step was going to be interesting. Back to first principles...


The result is MIDIdifferentTWO, which is, of course, different to MIDI differentONE! TWO is deliberately 'old-school' in design, with rotary controls and big lights for each step, and is built without using live.step. So there's a classic 'counter' object to generate the steps, the rotary controls are scanned using an 8-way 'gate' object, and the lights are the standard 'blink' / 'bang' buttons. driven by a 'switch 8'object.  To complicate matters, the 'gate' object allows values to pass through it, but you have to send the value, and a rotary control only outputs a value when you change it (or bang it). My attempt at a solution was to use a 'message' object as a buffer between the rotary control and the 'gate' object, and this seems to work quite well, at the cost of quite a bit of wiring up of bangs...


I was wondering if I should use the buffer contents to replace the parameter value of the rotary controls, but decided in the end that this wasn't required. I also rejected the idea of using the buffer as the map target for the Ableton 'remote control' system 'control voltages', so that I could have the rotary controls set as 'hidden', but I'm leaving this as an option depending on feedback. The Ableton M4L Guidelines for hiding objects so that they don't overwhelm the Undo history seems to be incompatible with making controls map targets, so this design has some flexibility in terms of possible mitigations.

The Max For Live code above is simplified, and there's a missing connection! The step clock output from the counter should be connected to the left-hand input of the 'gate 8' object - but you can always look at the real code if you download the amxd from MaxForLive.com.

The initial design was just a rapid response to a Facebook 'Max For Live Users' group query, and so was me trying to see if I could make do without live.step. The result then went through several drafts to the latest release (so far) of 0.06, adding direction to the steps (the counter object makes this easy, shuffling of the order of the steps (via a look-up table), skipping of steps (using the pack object to remove/restore numbers in the look-up table, and adding a second channel synchronised to Live's transport. Having two channels, where one can be free-running (or driven by MIDI events in a clip, which probably counts as user-controlled-sync!) and the other is locked to the DAW transport gives two very different, contrasting sources of 'control voltages', plus it also looks good. For a single channel 8 step, un-synced step sequencer, then I might have been tempted to put the rotary controls in two rows to reduce the width of the device (M4L Guidelines again!), and I might even have thrown away the 'old school' look and used sliders, but two channels means that the width is going to be wide anyway, and stacking two sliders vertically doesn't work for me. 

Implementing the 'Skipping' of steps required additional map targets for each step, and I was thinking of a Novation Launch Control (or XL) when I was doing this, but there are lots of other MIDI Controllers available. The solution was to just use a toggle text object as the map target...  One complication in the Max For Live coding was how to deal with the number of steps when you could skip or un-skip steps, but once again, the 'counter' object makes changing the count maximum easy, and so I just used the look-up table length as the counter maximum, and it was sorted! I'm always intrigued by how some problems loom ahead as being major, maybe insurmountable  challenges, but when you actually start to code them, they kind of shrink and aren't as impossible as you anticipated. There again sometimes apparently simple things can take ages to figure out, so there's no certainties!

The blinking lights proved to be one of the most challenging things to get right... The 'button' object has a parameter called 'blinktime', which controls how long the light stays on once it gets a 'bang' signal. Unfortunately, when the rate at which you scan across the steps changes, then blinktime needs to change as well - ideally so that there is no overlap with other steps so two lights are both lit at once, and without any gaps where no light is lit at all. This turns out to be difficult! Now if the 'button' object would just light up for the whole of the time that a step was active, like an LED or even a bulb, then it would be easy. But initially I didn't want to mess about making a custom graphic object like that, although eventually I decided that I had to, and here's what I did...


I wrote a special object just to decode the step number to drive scrolling lights! As often happens with these things, (and as noted above!) when you sit down to do it, then it isn't as difficult as you expected. It turned out to be nothing more than a set of compares, but instead of using the 'button' object as the indicator, I used the live.toggle object, which shows one colour when you send it a one, and another colour when you send it a zero. So now the steps are shown by an indicator that lights up for the whole of that step, and is off the rest of the time. Neat and much better than my previous default indicator: the 'button' object. Sometimes being forced into a change is good for you...

Notice that this time the missing connection is missing no longer! So what do the comparisons look like inside the scroll_mr package?


As I said, all a bit obvious really. But it works very nicely!

Using MIDIdifferentTWO

For something that started out as about half an hour's coding in response to a Facebook query, the final result (so far) has quite a lot going on! So, as usual, here's a side-to-side detailed descriptoon of all of the controls and what they do:

First, notice that there are two separate step sequencers. The top one can be either free-running (with its own clock running at the 'Rate' speed when the 'Mode' selector is set to '=Not Synced=' (I'm never sure if there should be an 'h' in synced/synched...), or else triggered by one of five different MIDI Events from the clip in Ableton Live: Any MIDI Note, Any change of MIDI Note Number (so repeated notes trigger the step advance the first time, but not after that), Note number 0 (very low frequency!), Note Zero with a MIDI Velocity of zero (the lowest, quietest note in MIDI 1.0!), or any note with a MIDI Velocity of 1 (the quietest note in MIDI 1.0). Because these MIDI Events are in the clip on the track in Ableton Live, then they are synced to Live's transport, but there's nothing to stop you having all sorts of weird timing of those notes, and don't forget the 'ignore repeated note' mode. The lower step sequencer is always synced to Live's transport, but you can choose anything from the step advancing every 8 bars to every quarter beat, which is quite a big range.

Both sequencers have the same controls after the speed/sync section. After the step number and a little count-up indicator, downwards there is the Direction control, which allows selection of left-right (ascending through the numbered steps), right-to-left (descending), and back & forth (palindrome mode, as some say). Underneath are two tiny toggle buttons. '1-8' and 'Skips' forces the full 8 steps when it is showing '1-8', whilst in 'Skips' mode the step numbers can be clicked so that they turn into 'X's, and then that step will not happen (and the length of the sequence will be shorter). Sequences that are one step long are okay, but they aren't very interesting! As you click on the step numbers to change them to the 'X's, then you will see that a row of tiny numbers will change to show the missing number. The 'Shuffle' button changes the order that the sequencer plays the steps - and again the row of tiny numbers will change to reflect the new order. Each time you get the 'Shuffle' button then the order will change. The lowest controls are nudge '+/-' buttons for the sequence length, shown as a small blue number on the left side. The step length automatically changes when you set up skips.

The central section is 'old-school': rotary controls for setting the step values, and big indicators to show which step is playing. The modern twist here is that the step numbers (in the grey squares) can be used to skip steps, but there's another hidden twist - you can control the rotary controls and the skip buttons with Ableton Live's 'remote control' 'control voltage' system. To do this, you either use the Map button in an LFO or other device, and then click on the rotary control of the grey step number square in MIDIdifferentTWO, or you put Ableton Live into MIDI Learn mode (Apple/Control-M to get into the 'blue' mode), then click on a rotary control or a grey step number square and move a slider or press a button on an external MIDI Controller. If you did this is the right order then the rotary control or step number will show an indication of the note number of MIDI controller that you have mapped to that control in a small grey box, and a line will appear in the 'Mapping' table at the upper left of Ableton's screen.

For testing, I used a Novation Launch Control to control the skips:


In the photo above you can see that the four lit buttons on the Novation Launch Control have turned steps 5,6,7, and 8 on the upper sequence into 'X's, and so those steps will be skipped. Also note that the sequence length has changed to 4 steps (the little number on the left). When I took the phot I was just about to map the rotary controls on the Launch Control to the rotary controls for the step values in MIDIdifferentTwo, so that I could control the sequence from the external MIDI Controller. You could, of course, use just about any MIDI Controller to control the sequencers inside MIDIdifferentTWO... Using an external MIDI Controller like this crosses the line from DAWless to 'DAWed', of course, but using a MIDI Controller definitely looks 'DAWless'!

After the eight sets of step  controls, the section on the right hand side deals with the output values of the step sequencers. The large blue numbers are the current output value - there's a label that says so! Underneath this is a 'Normal/Invert' toggle button, which inverts the value (so 127 becomes zero, and zero becomes 127). Next on the right are three rotary controls. 'Offset' adds to the value of each step, and can be used as a way to shift all of the values at once. If you are controlling a filter with the step sequencer, then this would behave just like the cut-off frequency control in the filter, for example. The 'Depth' rotary control scales the step values. At zero it scales the values down to nothing, so you won't hear any effect. At 100% the output is the values shown on the rotary controls. At 200%, the output is scaled to twice the values shown on the rotary controls - which means that the output value may well 'max out' at 127! The final rotary control is the 'Smooth' control, which is like the 'Slew' control on modular synths, and it turns abrupt jumps of value into more gentle slower 'slides' - it 'smoothes' the output!

Finally, there are two 'Map' buttons and their inverses, 'Unmap' buttons. You use these to map the output values of the two step sequences to other instruments, effects, or utilities inside Ableton Live. Controls that are being controlled generally go grey to indicate that they are being controlled from somewhere else (LFO, MIDI Controller, etc.), and their value moves on its own! To unmap and select another control, you use the 'Unmap' button.

Sinking and sourcing?

These are electronics terms for outputs and inputs respectively. In lots of electronic interfaces, an output is a source of current flow (it 'sources' current is the colloquial phrase), and an input is a sink of current flow (it 'sinks' it is the colloquial phrase). So for the MIDIdifferentTWO device, the step rotary controls and the grey step number squares are sinks, and an LFO or MIDI Controller that is controlling it via Ableton's 'remote control' control voltage' system would be a source. At the output of MIDIdifferentTWO, the two big 'Map' buttons are sources, and whatever they control would be sinks. Jargon, that's all.

In use


One thing to try is to change the cut-off frequency of a filter (a well-worn cliche that you can also do with the stock/factory 'Auto Filter' effect), or change the time delay of Delay (there isn't a stock/factory effect that does this!), or change the Depth in the Saturator effect to give an interesting rhythmic 'bite' variation. Basically, whatever your favourite 'control to tweak' is, you can now apply a shimmering, rhythmic version of it automatically, and free up that hand for something else, like pitch bend, or a mod wheel, or mousing, or adjusting knobs on outboard gear, or anything else. Now I know that I already have a device called '3rd Hand' (look it up on MaxForLive.com), but this is a bit like having a third hand!

Getting MIDIdifferentTWO_mr

You can get MIDIdifferentTWO_mr here:

     https://maxforlive.com/library/device/6160/mididifferenttwo

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 MIDIdifferentTWO_mr is just two step sequencers, giving an ME of 2. The ability to control step values and skips may vary with the specific sequencer, but if implemented, then it is just more patch cables. Perhaps MEs should also include some sort of measure for the number of patch cables that are required?

---

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


















Sunday, 27 October 2019

Different every time - changing parameters with M4L in Ableton Live

I've always worked according to the principle of 'Never the same thing twice'. Whilst most important for things like drums, I try to apply it to most sounds - although I also like flams, which kind of goes completely against the principle! Maybe 'Be inconsistent' is a better way of putting it? (Just to be consistent, I have added in the updates made to MIDIdifferentONE version 0.02 into this blog...)

In Ableton Live, there's an obvious way to control the parameters that are one major way of changing sounds on the fly: the 'Clip Envelopes'. The name is slightly misleading, because clip envelopes are just a way to draw parameter values onto the piano roll. Anyway, the clip envelopes are normally hidden by default, and you need to click on the 'E' inside a round button to open up the overlay in the piano roll pane. Selecting a device and a parameter from the two pop-up menus then lets you draw lines and curves either with a rather blocky pencil tool ('Steps') or with a 'lines and breakpoints' ('Ramps') tool. I prefer the 'lines and breakpoints' approach...



One of the 'classic' parameters that is controlled this way is filter cutoff (with an appropriate level of resonance) and I have spent quite a lot of time zooming out from a clip, setting the cutoff frequency for a bar, then clicking to get a new point and dragging it up and leftwards to get a new parameter level for the next bar, and so on. It requires quite a lot of clicking, but once it is complete, then editing each of the levels is quite quick to adjust. However, if you want to change the timing, for instance, to a change every other bar (or an arbitrary length), then it can require more clicks. There's also another non-obvious thing to consider that requires more clicks - you need to have the parameter set before the fist note on in the bar. This is why the orange clip envelope line is shown in the diagram as changing just before the first note in the next bar - if you don't do this then you hear the note start and then the filter cutoff change, which sounds like a mistake.

What this means is that you start off zoomed out, setting the parameter levels for each bar (or other interval), and then you need to zoom in to each of the ends of the bars where the parameter changes, the nudge the parameter change a little bit earlier in time. Then you zoom back out again. For me, there's a point where repeated mouse clicking gets a bit tedious, and I've never found any keyboard shortcuts for some parts of the clip envelope editing. So setting up several clip envelopes for a few parameters, and then changing the timing, starts to exceed my trigger level, and I stop and go looking for alternatives.

LFOs are the obvious alternative, and I've explored all sorts of variations of Slow Oscillators, including quite a lot of my own MaxForLive devices. The trouble with LFOs is intrinsic: they want to change, slowly; whilst for parameter changes I'm really looking for sudden changes followed by long steady fixed values. Lots of LFOs come with various 'Random' or 'S&H' (Sample and Hold') outputs that do give the stepped change, but then the values aren't under my direct control. Okay, so S&H on a filter cutoff can sound cool, especially a quarter note intervals (of which more later), but when you are controlling a build then you want to be able to set the parameter value for each bar. So LFOs are 'almost' the solution, but what would the ideal look like?

My ideal would have a LFO like 'Rate' control, followed by some way of controlling the parameter setting for each time period - from quarter bars up to every 8 bars or so. Which kind of sounds a bit like a weird step sequencer... but one that that enables each bar (or other interval) to have different parameters!

MIDIdifferentONE


MIDIdifferentONE is a deliberately 'different' step sequencer for parameter values that works a bit like an LFO, except that it is always synced to the sequence timing, and it is optimised for setting parameter values and then replaying them at various rates. Best of all, it always changes the parameter value just before the end of the bar, so you don't get the note followed by the parameter change!

It turns out that the requirement for something to happen 'just before' something else is one of those programming tasks that keeps cropping up again and again in electronic music, and I've struggled many times with getting it to work correctly. So this time, I was determined to spend some time solving the problem, and then some time showing how I came up with my solution. As always with these things, there's probably a much better, cleverer, shorter and neater way to do it, but I will leave that to other programmers!

LFO timing and step sequencer design is all standard 'home territory' for MaxForLive, but the requirements for the timing of the parameter change are more interesting - we need the parameter to change 'just before' the end of the bar (or some other interval). 'Just before' might be loosely defined as something like 'after the last beat, and as late before the end of the bar as we can manage without the parameter change happening in the next bar'. I decided to simplify 'as late as' to mean ' the last 16th note tick before the end of the bar, which is probably going to work with most situations - although if you put very short notes right at the very end of a bar then MIDIdifferentONE might start to change the parameter to the value for the next bar as your last note of the bar plays...


For 16th note quantisation, Live's transport outputs bars as numbers, beats as the numbers 1 to 4, and 'ticks' as the numbers 0, 120, 240 an 360. If you don't quantise the timing, then you get tick numbers like 205.74 and the processing is more complex. For MIDIdiffrentONE, making sure that the parameter changed before the end of the bar was the most important thing, so I kept things simple and applied quantisation, but only to the timing for these parameter changes! So MIDIdifferentONE will not affect the quantisation of any other timing in your music.

The definition of 'after the last beat and when the last tick happens' translates to beat=4 and tick=360, so all that is needed is a bit of Boolean logic in MaxForLive... Now the easiest way to do this kind of goes against the 'visual programming' metaphor that MaxForLive uses, and uses the 'if' object and requires some typing! Suddenly MaxForLive is going a little bit 'programmer'y! What you type in the Max object is something like 'If ($i1=4 and $i2=360) then 1 else 0', which means that when input 1 is equal to 4 (beats) and input 2 is equal to 360 (ticks) then output a '1', otherwise output a '0' (zero). Yep, that's a traditional text programming 'if statement' inside a MaxForLive object. Some of you may need to sit down at this point...

That covers how to make something happen at the end of every bar - whenever the beat=4 and tick=360. Other times like every other bar or every quarter bar just require slightly different 'if' statements and additional processing. I hid the end result inside a patcher box to keep things neat and tidy:


So you can see the 'metro' object that provides timing from the master clock source, a 'transport' object that outputs bars, beats and 'ticks' into those three number boxes, and then the 'before_mr' object that contains all of those hidden-away 'if' statements. The 'switch' object selects the desired timing, and after a special 'counter' object, you can see the top of the 'step sequencer' object.

Inside the 'before_mr' patcher? I'm not one to hide stuff away, so here goes:


If you look across the lower part of the patch, then you should find the 'every bar' output, (fourth from the left) and above that a blink object, some tidying up, and then an object with 'if $i1==4 && $12==360 then 1 else 0' inside it. This is the 'just before the end of the bar' requirement turned into an 'if statement' using MaxForLive terminology - so '&&' means 'AND', and '==' means 'is equal to'. You might like to try and work out how the other outputs are generated as well.

There's a trap with this 'just before' approach, and it happens in the very first step. As always, you should consider the 'edge effects', and this is one case where I didn't think enough about the initial step. The 'before_mr' patcher outputs a 'bang' event just before the end of the set time period: from every 8th bar to every quarter beat. So what happens in the first step? If we take the middle case of 'every bar' then the 'bang' event will not happen until just before the end of that first bar. This means that until that happens the counter is in the 'reset' case, which is a count of zero, so the step sequencer stays on whatever step it was before we started Live's transport running. Only when it gets to just before the end of the bar will a bang event occur, and the counter will increment, and step 1 will begin - almost a whole bar late! What actually need to happen is that the counter needs to be set to step 1 at the beginning of the bar, not just before the end. This can be achieved by using a 'timepoint 1 1 0' object, which produces a bang event when Live's transport starts running, and if this resets the counter, then step 1 starts correctly. This means that the first step is slightly less than a bar long in this case...

That's what is happening inside, now let's look at outside.

Using MIDIdifferentONE



The plug-in has has three sections, and from left to right, these control the setup, the step sequencer, and the value output and mapping. On the left hand side, the top shows the beat indicator and count, where the blinker can also be clicked on to reset the sequencer. Underneath that, the pop-up menu allows selection of the step sequencer rate: from every 8th bar, down to every quarter note (slow to fast, with the fast setting being the 'classic' S&H filter modulation effect). The cluster of thirteen buttons are used to fill the step sequencer, and the 'Random' button generates a different pattern each time. The 'Scramble' button jumbles the sequence of the values, and below it is an 'Undo' button that will restore the last edit you made - it isn't very sophisticated and there's only one level at the moment.

The middle section is the step sequencer. Every fourth step is highlighted in white instead of light purple, and the bar at the top can be used to set the length and looping points. The default is 16 steps from 1 to 16, but you can vary it to anything to 2 steps from 1 to 2, to 16 steps from 1 to 6, and back to 2 steps from 15 to 16. When you stop Live, then the step sequencer area can be edited 'live' using the mouse - just hover the mouse near the top of one of the step 'circles' in the middle 'step' section,  and that value will be displayed. Click and you can change the value of the step. If you move the mouse across the step sequencer area then you can 'draw' in the values very quickly. - the background of each step will go grab as the mouse selects that step...

So the workflow for setting the controlled parameter is now very simple: Stop Live playing, and then you can set the step values as you want with the mouse and they will be saved. Note: If you select one of the preset patterns, then you will lose your edits!

The right hand side shows the output value for each step, as well as a vertical bar indicator. The 'Normal'/'Invert' switch inverts the value, so high values become low and vice-verse. The 'Offset' and 'Depth' controls allow the value to be adjusted to suit the target parameter. Finally, the 'Unmap' button undoes any pre-existing mapping of the value to a parameter inside Live, and the 'Map' button allows you to mp the value to any available parameter inside Live.


Here is the 'classic' LFO S&H filter mod setting, except that it repeats, the steps can be edited, and it can be slowed down to as slow as once every 8 bars. This example is set for every other bar, and so the end effect sounds like a different setting (or different preset) every 2 bars. And switching to quarter beat cliche is just a single pop-up menu selection, whereas you would need to edit the timing of every value in a clip envelope.


Here's the output remapped to an instance of Analog inside Live, where the controlled parameter is the octave for Oscillator 1. The Offset control is set so that the centre position is no stave transposition, whilst the depth is set so that the oscillator goes up and down by one octave. LFO modulation of the octave control with an 'S&H' type of waveform would not give you any way to edit the waveform, but MIDIdifferentONE lets you set when the octave transposition happens.


Something that you may not have tried before is to change the filter type. Doing this every half beat is quite extreme, and the sound of a filter jumping from his-pass to band-pass to low-pass quickly is unusual. Remember that unlike an LFO doing Random or S&H waveforms, you can edit every step of the sequencer, so you can get exactly the results you want for each step.

ONE?

After a long run of 'hex' MaxForLive plug-ins, you might not be surprised by the 'ONE' suffix to the name of this device. I can neither confirm nor deny the future existence of any multi-channel versions of this utility...

Getting MIDIdifferentONE

You can get MIDIdifferentONE on  https://www.maxforlive.com/library/device/5805/mididifferentone-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 the blog post is behind the version number of MaxForLive.com...

Modular Equivalents

In terms of basic modular equivalents, then MIDIdifferentONE 0v01 would probably require an LFO plus a step sequencer, and a Utility module to do the scaling, giving a total of about 3 ME (without all the stored patterns, of course).

And here's a link to click on if you find my writing informative: