Showing posts with label MIDI Device. Show all posts
Showing posts with label MIDI Device. Show all posts

Saturday, 30 November 2019

Free Quad Modulated Probability MaxForLive plug-in for Ableton Live

Okay, three closely related releases in a few days is unusual, even for me, but there's a strong family bond between these three siblings:

1. MIDIprobD4 is the basic 4-channel 'set the probability of 4 drum sounds.
2. MIDIoffGRID4 adds flexible control over time delays.
And now:
3. MIDIprob+D4 allows the probability to be modulated with LFOs.



MIDIprob+D4 adds four Sync/Free LFOs (Nothing clever, just the same 'borrowed from Ableton' design that I've included in most of my old 'classic' plug-ins like Comber) - Hey, this might be a good time to revisit them...) so that the probability can be modulated instead of being fixed. This adds variability to the unpredictability, and so you may need to get familiar with using the basic 'skinny' MIDIprobD4 first, and then go for the 'full-fat' version.

The LFO in Comber...
Extrapolators have probably realised at this point that there's room in this unified scheme for:

4. MIDIoffGRID+4 and I can neither confirm nor deny that this is in development.

MIDIprob+D4's four channels make using my sophisticated 'modulation widget' difficult because of limited space. I have used it in some of my 'Hex' series of effects, and it allows easy control of modulation depth and offset in a single 2D X-Y control instead of two rotary controls.

The 'Modulation Widget' in AUDhexPPD...
MIDIprob+D4 is literally 4 LFOs added to MIDIprobD4, so the things you need to know are:

1.If you set the Probability rotary control (with the triangle) to 100%, then the LFO isn't going to be able to modulate it fully - you can pull it down to 50%, but that's all. Similarly, if the Probability rotary control is set to zero% then you won't be able to LFO modulate it above 50%. For full modulation of Probability, you need to set the rotary control to 50% - where there's a triangle to remind you. And yes, the 'modulation widget' would have made this obvious, but changing the size is tricky...

2. The 'Sync' speeds are locked to Live's transport, and most of them are very fast in comparison to the 'change the probability slowly over several bars' that you are likely to expect. But try the slower speeds (1/1, etc.) and see what happens when you are locked to a single bar, and then see what happens at shorter time intervals. They may be more useful than you think!

3. Yes, the first time you use the 'Free/Sync' toggle switch, strange things happen with the enabling of the graphics. I'm working on this...

4. Left for future additions...

As always, MIDIprob+D4 is free!

Getting MIDIprob+D4

You can get MIDIprob+D4 here:

     https://maxforlive.com/library/device/5851/midiprobplusd4

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 MIDIprob+D4 would probably require four LFOs, and four Random Noise Generators plus a quad MIDI Utility module to do the velocity multiplying, giving a total of about 9 ME (without all the stored memories, of course).

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




Friday, 29 November 2019

Off-Grid (as near as I can) extension to MaxForLive Probability MIDI Device

Sometimes a quick comment can trigger something much bigger. When I wrote about the Ableton Live Piano Roll editor for the MIDIprodD4 blog post, I mentioned that the piano roll had a not-so-well-known shortcut (the 'zero' key) for disabling notes...

This got me thinking, and there's another slightly obscure feature in the piano roll editor that got me thinking and then coding... So let's look at the shortcut first. If you have some notes on the piano roll grid, then you can move them backwards and forwards in time (clip limits permitting!) using the left and right arrow keys on the qwerty keyboard. The movement follows the quantisation setting, so if you have the quantisation set to 16th notes, then the notes can be shuttled back and forth in 16th notes.

Moving the snare to the right (time delay) by a 16th note, so that it is no longer aligned with the kick drum.
However, if you turn off the quantisation, then you can shuttle the notes back and forth (left and right) without the jumps being quantised to specific note lengths. This give you very fine control over the timing sloppiness.


But, after having moved a note (or several notes),  if you then put the quantisation back on again, when you use the arrow keys to move the notes left and right, something very interesting happens!


The notes don't do what you expect. Instead, they jump first to the quantisation places for the grid, so they are aligned as you would expect, but the second arrow key press moves the note by the amount that you set when quantisation was off! The next arrow press goes back onto the grid, and the next arrow press goes off it again, so if you had moved by a 128th note then the quantisation was off, when it is back on again, then the arrows move it by one 128th note, then a 16th minus one 128th note, then one 28th note, then a 16th minus one 128th note, etc. Once you know what it is doing, it makes perfect sense and is very useful.

Quantisation set to 16th note, Snare is on grid.

Quantisation set to 16th note, Left arrow key = Snare is off grid by one 128th note

Left arrow key = Snare is back on grid again, one 16th note later...

Left arrow key gain = Snare note is off grid again by one 128th note...

Here's another way of looking at what it is doing. Imagine you move a note by a 128th note when quantisation is off, so each arrow press moves the note by an amount of time that I'm going to call an O (for 128th) time period. Then when you put the quantisation on set to 16th notes, the arrow keys will move the note by S (a 17th note amount of time), then O, then S, then O.

I'm not sure if this is a feature or a bug, but it is very intuitive and very useful, and it got me thinking.. Maybe probability isn't the only thing that could be controlled between the clip piano roll and the Drum Rack?

MIDIoffGRID4


MIDIoffGRID4 is the result of that thinking, plus quite a lot of coding. It takes the basic idea behind MIDIprobD4, and extends it so that you get sophisticated control of the time delay of four specific drum notes (or ordinary notes, if you prefer to try it with synths and samples). The control isn't just fixed as the probabilities are in MIDIprobD4 (Ooh - now there's anther idea! Give me a few days!), instead it is dynamic, so each time a note is delayed it can be different (or the same, if you prefer), or it can be changed using an unusual kind of LFO (That I haven't seen used much either, which is another idea you may see soon - time willing!). Oh, and then at the end, you get control over the probability of the delayed notes happening. If these two devices were simulations, then MIDIprobD4 would be an unreliable drummer, whilst MIDIoffGRID4 would be an unreliable drummer with poor timing. Not that there are any drummers like this, of course!

In short, MIDIoffGRID4 lets you shuffle specific notes to the right (and then back to the left) without needing to open the piano roll and turn the quantisation off and use the arrow keys or dragging the notes sideways. And it lets you automate how much the notes are delayed. And it lets you control the probability of a note happening - which is pretty awkward to do in the piano roll (there are ways, but they can be ugly).


So, delay first. The screenshot above shows a setting of 52 128ths note 'ticks' for the time delay for Note 38 - the Snare drum. The 'Random' rotary control is set to 4 (by accident), but it isn't having any effect on the large white 'Delay Time' number on the right - that shows 52. This is because the 'Delay' rotary control goes straight into the 'Delay Time' display that affects the note timing, whilst all of the other three rotary controls (Random, Count, and Multiply) are affected by the 'Limit' rotary control (of which more in a moment), and this is set to zero. In a future update, I will try to remember to change the colours so that this is more obvious!

Anyway, the Snare has been made slightly late, so it doesn't exactly coincide with the Kick any longer, and so we get a sloppy second beat...


Here's no 'Delay', but the same value set on the 'Random' rotary control. This time the 'Limit' control is set to 52 as well, and so it will 'limit' the value of the previous three rotary controls to a maximum of 52, but it wraps round, so a value of 53 will be 1, 54 will be 2, etc. Technically, it is a modulus limiter. The 52 value for the 'Random' rotary control means that it will output values from 0 to 52, and so the value of 23 that is shown in the large white 'Delay Time' number is just a random value between 0 and 52. If the 'Delay' rotary control had been set to 10, for example, then this would be added in to the 'Random' value, and the 'Delay Time' large white number would show 33 in this case.

So now the Snare is variably late after the Kick! Sometimes it will be in time, and sometimes it will be slightly late, and sometimes it will be very late...


Here's the 'LFO'-type effect in operation. The 'Count' rotary control sets the maximum value of a counter that increments each time a drum note happens in the channel. In this case, the count will start at zero and go up to 104, then it will return to zero and count up again. The 'Multiply' rotary control affects the count as the name suggests: a setting of 1 should mean that the count goes 0, 1, 2, 3, 4, 5... etc. But a programming bug means that it actually goes up in 2s! So it counts 0, 2, 4, 6, 8, etc. A setting of 2 counts up in 4s, 3 counts in 6s, etc. I quite like that it does it wrong! But the 'Limit' is set to 52, so when the counter gets to 54, the delay time that is sow in large white numbers is 2 again. In other words, by setting the Count, Multiply and Limit rotary controls, you can control how the delay time changes, from slow increments of 2 ticks, up to complex repeating patterns caused y the modulus limiter.

In this case, the Snare gradually lags further and further behind the Kick, until eventually it resets and is in time again, but then it starts to lag behind again.

The 'Count' 'LFO-type effect is not easy as first to get your head around, but if you treat it like a synth and just noodle with the controls until you get a good sound, then you are following a process that has served generations of synth players very well for decades!

Oh, yes, and the 'Quantise' control lets you quantise the 'Delay Time' for each channel, although this isn't shown in the display... The default setting of 128th note 'ticks' is as unquantised as I could make it using the standard Max 'pipe' object - but see below for more thoughts on this.

Assigning channels to drums is up to you. You might want to not change the Kick drum timing, or there again, you might want to! For synths, then you could adjust the timing of four separate notes using a single instance of MIDIoffGRID4, whilst an Effect rack with multiple instances could give you control over many notes. Strums are one obvious application, but I'm sure you have wilder imaginations than that! Especially on Black Friday!

MIDIoffGRID4 gives you four channels of drums that can be time delayed in various ways, plus the final probability control. I'm hoping that this will result in some very interestingly time-varying and unpredictable drum tracks!

Oh, yes, and a liitle glitch during development means that some of the screenshots have this device shown as MIDIprob4, instead of MIDIoffGRID4. Sorry - I'm not a very disciplined programmer these days! 

Inside...

The Max / MaxForLive code inside MIDIoffGRID4 uses the same redundant Note On/Off 'Velocity of zero' approach as MIDIprobD4, but the way that I have delayed the MIDI notes and velocities is slightly left-field... Here's the essential bits of the code:

The left hand side has the MIDI note selection, which is done with a 'routepass' object that just routes the specific note to one output, and all other notes to another output. (Note that the split of MIDI note events into a stream of note numbers and a stream of velocities happens before this - outside of this code snippet.) The 'specific MIDI note' is set by a MIDI note number from the 'Selected MIDI Note' input - just a rotary control with a range of 0-127. I did debate as to whether I should restrict the range to something more appropriate to the conventional GM MIDI drum note number range, but decided to leave the range at its full extent so that non-drum events could be processed. I haven't explored the possibilities with synths and samples very much yet, and as with my Drum Flammer, I suspect that repeats and time delays on individual notes may be a bit unexplored, unpopular, unfashionable - which sounds like fertile territory to me...

The middle section contains two 'pipe' objects to delay the note stream and the velocity stream. The Help file and Reference for 'pipe' show the Cycling '74 thinking on how to use it - you send the packed stream of note and velocities thru the 'pipe' object. But I was thinking that it might be interesting to put different delays on the two streams, and so I split the 'pipe' into two, so there's a chance that a forthcoming MIDIoffGRIDpro might explore this in more depth.

The 'quantize' message to 'pipe' is interesting. There isn't a 'quantize off' message, and so the smallest time interval that you can set the pipe quantisation to is one 128th note. So this sets the 'tick' of MIDIoffGRID4's processing. I might try playing with a sample-rate version of 'pipe' in Gen to see if there's scope for shorter notes, but in order to work out if that is worthwhile then we need to consider the 'not-talked-about-very-often' MIDI transmission rate limit - oh dear, it looks like I'm talking about it...

MIDI Transmission Rate Limit

MIDI's serial connection is at 31.25 kbaud per second ('bits per second' in this context), and a minimalistic MIDI Note On and Off message takes 4 MIDI 'bytes' (2 for On and 2 for Off) when Running Status is active, so that's 31, 250 divided by 8 (to get it into 'bytes', and then divided by 4 to end up with messages, which gives an absolute maximum rate of 976.5625 messages per second. Now with serial communications, then limits like 'absolute maximum rate' are not something you want to be too close to...especially since a real-world MIDI data stream will probably have more than just MIDI Note On and Off messages in it ((MIDI Clock, Active Sensing, Controllers, etc.). For more typical 'in-stream' three byte MIDI Note On and Off messages then that second division is by 6, which gives  651.04166... messages per second.

To put these numbers in context, they need to be expressed relative to tempo and note lengths. I'm a 120 bpm sort of person, so 120 beats in a minute is 120 beats in 60 seconds, which is 2 beats per second, or 1 one beat every half second. For 4/4, then 4 beats per bar, so a quarter note is going to last half a second. From the previous calculations, we know that in that half second we could have just slightly over 651 MIDI note messages - which seems like quite a lot, and reflects the sort of engineering thinking that the original MIDI designers must have considered carefully. So a quarter note is one out of those 651 possible MIDI note messages, and so an 8th note would be one out of just over 325 MIDI note messages. A 16th note would be one out of just over 162 note messages, a 32nd note would be one out of just over 81 note messages, a 64th note would be one out of just over 40 note messages, and a 128th note would be one out of just over 20 note messages (and takes 1/64th of a second, which is 15 milliseconds). Now, depending on your medical source, 10 milliseconds seems to be somewhere near the middle of the measured range of the perception limit of human timing, and we are at similar amount of time with 128th note quantisation...

Gen into the pipeline?

So the calculations suggest that it might be worth looking into a Gen version of 'pipe' to see if using one 256th note quantisation (or finer) can be perceived, but only just. So I'm going to add this to the pipeline, but not with a huge urgency, and when I have a spare moment... Until then, I would be interested, as always, in any feedback from users of MIDIoffGRID4 about the timing resolution of one 128th note for the quantisation.

Getting MIDIoffGRID4

You can get MIDIoffGRID4 here (it is free!):

     https://maxforlive.com/library/device/5846/midioffgrid4

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 MIDIoffGRID4 would probably require four delays, four LFOs, eight Random Noise Generators and four Utility modules to do the Limit modulus function, plus a quad MIDI Utility module to do the velocity multiplying, giving a total of about 24 ME (without all the stored memories, of course).

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



Tuesday, 26 November 2019

Redundant MIDI Note On Messages Used to Set the Probability of a Drum Event

The Ableton Live piano roll display for MIDI Events is interesting, in many ways. As someone who has been using hardware sequencers since the 1970s (ARP's model 1601 Sequencer, for example, or the Roland...,), and software sequencers since the 1980s (The UMI-2B/4M on the BBC B, for example... http://www.muzines.co.uk/articles/umi-4m-midi-composition-system/3975 from September 1988, or Dr.T's on the Atari...), then I have seen and used a lot of ways of representing and controlling musical data. Ableton's piano roll is quick and easy for some tasks, but I have always liked a list-based view for adding things like program changes, or tweaking the order of 'simultaneous' events that are serialised by MIDI transmission.
(Picture from Reverb.com, where you may be lucky enough to find and purchase classic devices like this one!)

However, most seriously of all, it has always been my exposure to Intelligent Music's RealTime sequencer that has had the most profound effect on me (with John Hollis's Trackman just behind it...). RealTime was arguably one of the first sequencers that showed the road away from tape recorder emulations and towards modern DAWs (When I reviewed it, I didn't return it: I bought it! http://www.muzines.co.uk/articles/realtime-intelligent-sequencer/5624 ). And one of the killer features for me was the randomisation control - a little toggle box with a random pattern inside it that turned boring hi-hat lines into much more interesting decoration, and which sounded much less like a robot playing. Some things get under your skin and into your head, and you may have noticed that many of my MaxForLive devices (and more) have a significant bias towards using probability as a control source.


Which is where Ableton's piano roll comes in. Power users probably already know about the 'select a note, press the '0' (zero) button' shortcut that disables or enables notes (it is in the pop-up menu for the piano roll), but I've always wanted a Modifier key version (Shift-Zero, or Control-Zero, or something else, that doesn't disable a note, but sets the probability of it happening. Having 'greyed out' disabled notes is okay, but I would like more!


Now, it is possible to make a MIDI Effect Rack that extracts a single MIDI note and uses MIDI velocity processing or the Arpeggiator to provide control over the probability of a note, but it is pretty awkward, and not very elegant. All of which sounds like a cue for a simple, neat MaxForLive MIDI Effect that lets you control the probability of notes happening.


MIDIprobD4 does exactly that - for four notes simultaneously (It is a 'quad' or four-channel device...). The D indicates that its primary intended use is for drum sounds - you put it just in front of the Drum Rack. I use it to make hi-hats less robotic, to make snares unpredictable... You get the idea. If I'm bored, then I assign all four channels to kick, snare, closed and open hi-hat, and fill the Clip piano Roll with drum notes, and it produces oodles of random drum patterns. In a world currently overflowing with Black Friday deals (and what are the from/to dates for that?) then the deal is my standard one - it is FREE and will remain so (unless something extraordinary happens!).

Redundant MIDI Note Offs

MIDI has some interesting back alleys. In the classic reference specification, Complete_MIDI_96-1-3.pdf', on Page 10. In the 'Note-Off' section, it says that a Note On message with a zero velocity is roughly equivalent to a Note Off message.

( For more MIDI documentation, please visit: https://www.midi.org/specifications ) 

Now for any MIDI device that is velocity sensitive, a velocity value of 1 (one up from zero) is going to tend to be quite low in volume - maybe only fractionally just above no sound at all. The opposite value, 127, is maximum volume, of course, and so in many cases, zero and 1 sound pretty similar - one is totally quiet, the other is as quiet as it can be without not playing at all. There's one other interesting feature of drums - they are almost always velocity-sensitive. Further, on page A-4 in the 'Assignment of Note On/Off Commands' section, it says that 'Since there is no harm or negative side effect in sending redundant Note Off messages then this is the recommended practice' when talking about ensuring that Note Ons and Note Offs are always paired together, eventually.

The 'Velocity of zero is a Note Off' feature and the 'Redundant Note Offs are ok' feature are the mechanisms that I exploited to control the probability of MIDI note events in MIDIprobD4. Yes, I could have produced a complex device that keeps track of Note On messages and waits for the corresponding Note Off messages, and controls the probability of a note happening by removing the complete pair of messages, but it is far easier to just change the velocity of a Note On message to zero - which changes it to a Note Off, and redundant Note Offs are ok. So the MIDI processing is vry simple - just a multiplier for the velocity value of zero or 1. With a multiplier of 1, then the velocity of the note is unchanged: 1 x any value from 1 to 127 is the value. But with a multiplier of zero, then any value from 1 to 127 is changed to zero, which is the equivalent of a Note Off message, and it is okay to send redundant Note Off messages!



The Max code is shown above. This is inside a patcher that handles the velocity, and so outside this is more code that separates the MIDI messages into Note Number and Velocity streams, and so this is just the velocity stream processing. The yellow number box is a buffer so that the time it takes for the 'Random' object to generate a random number doesn't affect the processing time of this patcher - the previous value is available immediately from the number box. The output of the '<=' object is either zero or 1, and this drives the multiplier. The Probability control is a 0-100 rotary percentage control. I have to confess that whilst this approach follows the MIDI Specification, the actual device isn't perfect (but then, many of my devices have quirks...) and so sometimes it shows a note with a high probability that doesn't actually make any sound. I have spent quite a while trying to find out what the problem is, but haven't been able to discover the cause. Perhaps a reader of this blog may be able to enlighten me?


Anyway, MIDIprobD4 has simple controls. From left to right the first rotary control in each of the four channels is the MIDI note selector (0-127, although most drum notes are typically going to be 36-60ish), then some memory slots/squares (shift-click to save, click to recall), then an indicator blinker to show that a note event has been received, then the rotary Probability Percentage control, and finally a second indicator blinker to show that an note event has been transmitted to the output. Minimalistic, although I'm sure it could be made even smaller...

And that's it. Put MIDIprobD4 just before your Drum Rack and you have control over the probability of four of the drum sounds. Enjoy!

Links from this blog post:

UMI-2B/4M on the BBC B (from muzines.co.uk)
ARP model 1601 Sequencer from Reverb.com
RealTime sequencer review (from muzines.co.uk)
MIDI Documentation

And a special mention for a wonderful repository of music magazines from what now seems to have been a 'golden age':

Mu:zines - an amazing resource!

Getting MIDIprobD4

You can get MIDIprobD4 here:

     https://maxforlive.com/library/device/5844/midiprobd4

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 MIDIprobD4 would probably require four Random Noise Generators plus a quad MIDI Utility module to do the velocity multiplying, giving a total of about 5 ME (without all the stored memories, of course).

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




Saturday, 24 November 2018

Doubling the levels in a Quantiser in Max For Live device for Ableton Live - User Interface considerations

When I added four extra levels to MIDI ccQuant so that it had 7 levels instead of 3, I already knew that the user interface was going to be a challenge. The original design for MIDIccQuant had three levels because the available vertical space in a MaxForLive device is fixed: there are 170 pixels to play with... For live.dial this means you can have 4, 3 or 2 stacked vertically...


Now I'm not the greatest fan of the 'tiny' live.dial rotary controls (or the rather sparse live.slider when used at this size), and the 'panel' dials are often mistaken for the Macro Controls, which leaves the three standard 'vertical' sized live.dial rotary controls. Which means that most of Max For Live devices have at most three horizontal rows of controls - and those that have 4 (the <x>_Freez series, for example) don't use live.dial rotary controls.

MIDIccQuant used the standard 'vertical' live.dial rotary control, which meant that choosing the number of levels of quantisation was easy: 3. That way I could have three dials for setting the main parameters for the quantisation. Unfortunately, this also meant that there would be four output settings, and so I compromised to the live.dial mode that I really, really don't like: the 'bare' view:


In the 'bare' view, you turn off all of the labels and numbers (you can have labels or numbers at the top or bottom, but it looks weird) and you put the number next to the dial, as you can see above (and below). It is possible to have 5 dials squashed into the vertical space, but it isn't pretty, and it can get worse...


For the 8 output levels that I needed in MIDIccQuant8, I rejected the use of eight 'tiny' dials without labels and numbers, and instead I went for live.sliders, which normally I avoid because they are very plain and don't have the characteristic 'Ableton' look that the live.dial has. I also oriented the sliders so that they match the two parameters: horizontal for the levels, and vertically for the outputs. Finally, I colour-coded the sliders so that they matched the lines in the display:


Hopefully it should now be more obvious that you move the orange sliders from side to side to influence the horizontal spacing of the orange lines, but you move the light purple sliders up and down to move the purple line segments vertically. It worked for me, and I did consider going back and reworking MIDIccQuant so that it had the same metaphor.

Whilst I was doing all of this user interface consideration, a crazy though did pop into my mind, and I wondered about taking the quantisation to the limit, with 127 levels and 128 outputs - which stops being quantisation and becomes a transfer function, or a mapping. So watch MaxForLive.com for another device...

Getting MIDIccQuant8_mr_0v03

You can download MIDIccQuant8_mr for free from MaxForLive.com.




Friday, 23 November 2018

Quantiser bug fixing in two Max For Live devices for Ableton Live...

"It worked absolutely fine...right up until I tested this..."

I have heard those words so many times, but it was quite a surprise when it was me doing the talking. Somehow, in the development of MIDIccQuant, and it's bigger sibling, MIDIccQuant8, an avoidable problem found its way into the quantiser, and a user found it a few days ago. In response, my testing and debugging was just a little intense - and eventually I found the problem.

I had broken one of my own rules, and now it was biting me. Badly.

What was happening was that both quantisers would occasionally output a MIDI Controller message with zero as the value, even though that wasn't what was supposed to happen, and especially because a quantiser shouldn't be able to output anything other than the allowed values. But the zeroes were there when you looked for them. Time for a diagram:


So what did I do wrong?

It's simple really, in the quantiser itself (yep, the core of the devices!) I had two things happening simultaneously, and as a result, in certain circumstances, the quantiser stopped being a quantiser. Rather than bore you with Max code, I'm going to use an analogy to give you an impression of what was happening, an suffice to say, the replacement code (a more or less complete re-write of the quantiser) doesn't have the problem any longer.

So, here's a scenario for you to think about. Imagine if inside the quantiser there were two switches and an output. Switch 1 connects to the value 80, whilst Switch 2 connects to the value 10. Both switches meet and produce the output at point A.


Obviously, if Switch 1 is closed and Switch 2 is open, then output A has the value 80. Similarly, if Switch2 is closed and Switch 1 is open, then output A has the value 10. Traditionally, logic designers would summarise this behaviour in a 'truth table':


However, this isn't the full story. There are two switches, and so there should be four different ways of setting them, so let's extend the table:


Aha! There are now two interesting additional settings of the switches, and they don't give useful results. When both switches are closed, then both 80 and 10 are connected to point A, which might produce an output of 90... When both switches are open, then nothing is connected to point A, and so it is difficult to know what the output value might be... Zero, perhaps? 

In my original quantiser design, each of the levels had its own detection 'circuit', and so when the input crossed from one level to another, two separate 'circuits' did two things to change the output from one level to another. If those two weren't exactly in sync, then you got an output (zero, in the case in question), and actually, keeping two things exactly in sync is pretty difficult. 

In the revised design, there is only one switch changing at any time, and only one value available at any time. The switch is either open or closed, and so you get either the value, or you don't get anything. If you want a different value, then another switch gives you that, and only one switch can be active at any time. In the quantiser, this means that now you only get the quantised output values that you are expecting, and getting anything else is kind of 'designed out'. And yes, this is how I should have designed it in the first place, but in my defence, there was quite a lot going on, and it was very difficult to spot what I had done wrong. 

Just in case you think this is an isolated example, and that 'real world' examples of 'two things not needing to happen at the same time' are difficult to find, think about the 'shift' key on a computer keyboard. What happens when you press down on the 'shift' key? Does anything happen when you press the shift key? Or does something only happen when you keep holding the shift key down and press another key, and then release that other key and then finally release the 'shift' key. The shift key gets pressed before the other key, and only gets released after the other key has already been released.   There are lots of other things where what at first sight appears to be two things happening at the same time is actually one event happening and a second event happening inside that first event. And don't try releasing the shift key whilst you are holding another key! 

Whilst I was rewriting the quantiser code, I also had another look at the user interface, and so the 'fixed' versions (0.03) now have more colour coding for controls, so the 'levels' are now in orange, and the quantised outputs are in light purple. After a lot of devices that only use various shades of light purple, this is a big change! Here's the revised look in one of my deliberately eye-catching ads:


As usual, you can get all of my Max For Live devices from maxforlive.com. 

Getting MIDIccQuant_mr_0v03

You can download MIDIccQuant_mr for free from MaxForLive.com.

Getting MIDIccQuant8_mr_0v03

You can download MIDIccQuant8_mr for free from MaxForLive.com.