Showing posts with label Experimental. Show all posts
Showing posts with label Experimental. Show all posts

Wednesday, 8 July 2020

Note Count Processor in Max For Live for Ableton Live

After I described the 'Triple Transposing Delay' with three different ways of connecting the delays together, as 'experimental', people seemed to like that, so my latest release is 'extremely experimental'!

Although it isn't a reliable guide, I've not seen anything like MIDIoneOF before, although, of course, you could do some of it using clip envelopes. In fact, I reckon that you can do almost anything by using clip envelopes, and I'm sure that those people who produce YouTube videos with apparently click-attracting titles like: 'Powerful Advanced Generative Techniques For Ableton Live', in huge white block capitals will be busy making yet more of those videos as I type, although they don't seem to use clip envelopes... When I did release a YouTube video on using Clip Envelopes, it got a wonderful review (Thanks, Darwin!) and over a hundred views, so maybe I should make some more...

MIDIoneOF


MIDIoneOF is the first of a series, because people seem to like it when there is more than one of something, and actually that's part of where the name comes from. I wanted to called it 'n of m' because it is based on permutations and modulo arithmetic, but mathematical notation like 'n of m' isn't very good for naming Max For Live plug-ins, and 'Nofm' sounds like onomatopoeia for eating food, rather than a cool M4L device. So 'One of' got the most votes, and may well be followed by 'Two of' when I have time to finish it. (I have no idea what the third might be called...) Me? Busy? I've been doing several major projects over the last few months (the TR-505 was just one of them) and I can't talk about some of them, but they might even see the light of day at some time. Over the years, I've become rather used to doing stuff that never has the media spotlight turned onto it, and I'd probably be surprised now if a glimmer of limelight ever appeared on any of my stuff. But hey, It means that sometimes I can hint abut something rare and unusual!

(*) MIDIoneOF counts notes as they arrive at the input, and then processes those notes in various ways. The main process is muting: you can set notes to be muted depending on two criteria: the note count length (from 2 to 16 notes), and the 'Mute Pattern' which you can set in the 16 light purple boxes (although you can only set ones which are within the note count length!).

The Mute buttons mute the note if they are grey, but let the note through if they are light purple, by the way.... 

So if the note count is set to 7 notes, then you can set mutes for note counts between 1 and 7 notes. There are 'Speedup' buttons to set all the mutes on ('AllOn') or off ('AllOff'), as well as a random selection.

The muting affects the notes as they pass through the device, and all of the timing is derived from those notes... Despite appearances, the mute buttons are only indirectly connected to the timing transport of Ableton Live - and if you don't quantise your notes, then there's no real connection at all. So what may look like a simplistic rhythmic accenting utility isn't quite that at all... It may look like a step sequencer, but the steps are the notes, not the transport timing. It's kind of a step sequencer turned inside out...

This is probably a good time to revisit the start of a previous paragraph (*). When I say: 'as they arrive', I mean that if you have a clip with 8 notes in it, then MIDIoneOF will get those 8 notes, and will process them in the order in which they arrive. So if the note count length is set to 7, then the first 7 notes will be processed (and muted or not, depending on the settings of the numbered buttons in the Mute Pattern. The eighth note will then be processed as the first note of the second set of 7 notes, and MIDIoneOF will continue processing in groups of 7 notes, until you stop Ableton Live.

The clip (or live playing) can include single staccato notes, legato notes, or chords, although there are limits to the speed and quantity of notes which it can deal with! Remember that I did say: 'Extremely experimental!'. Note also that this behaviour isn't what you probably associate with a step sequencer, but as I said, this isn't...

The second bit of processing is the 'AutoRandom' button, which saves you from the effort of clickng on the Mute buttons. You set a number (between 2 and 16 - a motif in this series) and after that number of multiples of note counts (so every n x 7 notes in the example I have used so far), the Mute buttons will be randomised. Properly random, and not one of those 'tailored randoms to make random more suited to human beings', so you can have everything muted, nothing muted, and these can repeat several times. Real random is like that, although in a lot of modern software it has been 'tailored' to suit people's expectation - the classic example is iTunes, where the Shuffle function does not play the same track twice, even though a random selection might play it twice, or even thrice, or even... It seems that people report it as a problem if a random shuffle plays the same thing twice... So you set the number of multiples of the note count length, and click on the 'AutoRandom' button, and off it goes. Setting the multiple to 4, 8 or 16 sounds kind of musical, because too much exposure to popular music seems to have convinced many people that everything happens every 4, 8 or 16 bars at 120 bpm in 4/4 time. Since the example so far has been every 7 notes, then try 7 as the multiple and you will find that it might feel slightly early.

The second processing is MIDI velocity. Since the note count and Mute Pattern know which number each note is, then we can do interesting things to the velocity value of the notes. The clue is the 'Rise/Fall' button, and this has an Offset rotary control on the left side, and a Scaling rotary control on the right hand side. Rise increases the velocity value as the note count increases, whilst Fall decreases the velocity value as the note count increases. This means that, as with lots of stuff that I do, velocity matters! You should try MIDIoneOF with an Instrument that is velocity sensitive... The important thing to remember is that the velocity processing happens depending on the note count length, so with the 7 note example and a Fall button setting, then the first note will have the largest velocity value, then the velocity will drop over the next 6 notes to the 7th note, which will be the quietest (lowest MIDI velocity value), and finally, the 8th note will then be loud again, after which it will drop for th next 6 notes, and so on. The 7 note cycle will repeat until you change it.

Note that all of the processing happens based on just the notes themselves. MIDIoneOF takes all of its timing from thosee notes, not from the bars and beats within Live. So if your clip has notes in a complex rhythm, then MIDIoneOF will process the notes in that same complex rhythm. As I said, you can feed your own playing through MIDIoneOF if you wish... And I'm not going to mention Olafur Arnalds here...

The final processing is Probability, which is independent of the note count length! One thing that I have realised is that 100% is not enough, and I'm looking at this to see if there is anything I can do, but adding in extra notes is quite tricky in real time...

There's also the slightly red '!' "All Notes/Sounds Off" button in case you need to stop errant hanging notes. This may well signpost this as an 'experimental' device regardless of how I tag it in MaxForLive.com...

And that's the MIDIoneOF device. Hopefully you haven't seen anything quite like it before... because I much prefer not to repeat things that other people have already done. There have been a lot of Max For Live devices recently which are just people re-making a device which is already on Max For Live. I think that time is too short to waste it re-coding something which is already available!

Inside

I won't bore you with a counter, and I won't bother explaining why the count is from 2 to 16 and not 1 to 16 (1 is the obvious minimum, but it is really boring using a count of one!). Instead, this is probably a good place to do another in the occasional series of 'Things that Max doesn't have a pre-made object for...'

In this case, it's those 'Mute Buttons' that are the source of the problem. To mute the MIDI note when any of the mute buttons are highlighted requires what I call a 'wide' OR function - a 16-input OR gate. This isn't standard in Max...which is not hugely surprising... Now I know that you can use Boolean logic to transform the gate, but as far as I can see,  this doesn't really do anything other than mean that a different 'wide' gate and extra inversions are needed. So what did I do? I made a 16-input OR gate using a tree hierarchy of 2-input OR gates. Yep, I resorted to 'brute force and ignorance' to save time and effort. Sorry.


Two things are probably notable in this sub-patcher. First, there's the left-most input, which sets all of the outputs to zero. I've had all sorts of 'difficult to track down' problems caused by the gswitch object when there's no input on one of the two inputs (This would be a 'floating input' if this was hardware, which it isn't...), and so this ensures that that won't happen. Second, there's my standard 'use a blink to make both inputs trigger the output' approach, which enables the ORs to ripple downwards from either side. I'm sure there's a better way to do this whole 'Wide OR' functionality, but I have't had a flash of inspiration yet... It works well enough for my purposes.

Links

YouTube video on using Clip Envelopes - Features Clip Envelopes - in a video!
All Things Modular - Inspired by Modular - Darwin's blog has some interesting posts in it! Including this one where it refers to the above video on clip envelopes.

Getting MIDIoneOF

You can get MIDIoneOF here:

     https://maxforlive.com/library/device/6436/midioneof

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... and pictures may not always be the current version... but Schrodinger's cat's status is permanently uncertain...

Modular Equivalents

In terms of basic modular equivalents, then implementing MIDIoneOF in a modular synth is just a step sequencer (or a ring counter in old parlance) driven by gates or triggers instead of a clock, some toggle switches for selecting the steps, and some velocity processing in a CV utility. About 5 modules by my count, giving an ME of 5. I hope that this blog post makes more people think about pulling out that patch cable from the clock input of the step sequencer and connecting it to a gate instead of an LFO or a Clock Generator. Modulars synths have cliches too! 

---

If you find my writing helpful, informative or entertaining, then please consider visiting these links:


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




















   


Monday, 23 March 2020

Swapping MIDI Note Number and Velocity Value in a Max For Live plug-in for Ableton Live

When I produced the MIDI Note Filter recently, I realised that the internal processing would allow some other interesting MIDI processing functions to be carried out. One thing that I have always wanted to experiment with spans across two different topic areas: music and steganography (hiding data in other data), and it builds on my recent explorations of Note On and Off messages, as well as a recent twitter message that talked about security.

(I have also been busy producing material for Christian Henson's 'Pianobook Pianoday 2020' collaborative 'systems music' project due to be released on the 28th March 2020 as 'Music by 300 Strangers'. Search for '#pianobookpianoday2020' on YouTube to see some of the contributions... This has put me in a more experimental and explorative mode than my usual analytical one, so what follows is not my usual type of Max For Live plug-in... but this is a good thing!)



MIDIswapNVmr01 is a Max For Live plug-in that swaps the note number and the velocity value in MIDI Note On messages that pass through it, and it works with the implied Note Off messages that occur when the velocity value is zero. A button is provided that toggles between 'Swap' mode and 'Thru' mode, and the usual '!' panic button is also there to stop hanging notes (I have called it 'ANO' here because it flushes out hanging notes, but note that it does not send a MIDI 'All Notes Off' message - Ableton Live does that when you press 'Stop', which is why the dark blue ANO is shown by the monitor...). Yep, a minimal user interface!

One thing which I hadn't thought about until I created the MIDIfilterNOTEmr plug-in was what happens when you turn off a Max For Live plug-in using the 'Power' button in the top left hand corner. It turns out that if you turn a M4L plug-in off, then it is bypassed, so you can use the power button as a kind of secondary 'Thru' button. So I have included this in the screenshots!

Screenshots


The screenshot above shows the plug-in swapping note numbers and velocities. I have put two MIDI Monitor utilites before (on the left side) and after (on the right side) so that you can see what is happening. Looking at the very last note (just before the dark blue 'All Notes Off' ANO MIDI message), then you can see a Note On (shown as 'NON' in the Monitor utility) for E3 with a velocity of 65 goes through the plug-in and comes out as a Note On for F3 with a velocity of 64. You won't be surprised if I reveal that F3 is the note that corresponds to note number 65, so the incoming velocity of 65 has been converted to a note number (F3) as intended. The E3 incoming note is note number 64, and so this turns into the velocity of the outgoing note as 64.

Let's pause for a moment here whilst you get your head around this. The incoming note is E3 (65) with a velocity of 65. The outgoing note from the plug-in is F3 (64) with a velocity of 64. So the note number and the velocity value have been swapped.

A quick note about note offs. As I've mentioned several times recently, a MIDI Note On message with zero velocity is treated as if it is a Note Off message. So in MIDIswapNVmr01, a Note Number of 0 (C-2) turns into a velocity of zero, which means that whatever the value of the velocity of an incoming note, if the note number is zero (C-2), then the output will appear to be a Note Off message. As it happens, the 'hanging note' suppression mechanism that I use ignores Note Off messages that haven't ever had a preceding Note On, and so nothing comes out of the plug-in!


I wasn't sure how to capture 'nothing' happening, so for the screenshot above I played several C-2s and then an A-2, and then C-2 again. As you can see, the only output from the plug-in is an E6 with a velocity of 9, which is because the incoming note's A-2 is note number 9, and the incoming note's velocity of 100 maps to  E6 when it gets turned into a note number. The C-2 notes thus turn into pairs of 'Note Ons messages with zero velocity acting as Note Off messages', which are then stripped away by the hanging note protection, and so never even make it out of the plug-in.

So there's a caveat / warning / note for this plug-in:

If you input a C-2 into this plug-in, it will never get out!


The screenshot above shows the inputs and outputs in the 'Thru' mode - so the MIDI messages pass through with no changes.


And the 'Power Off' mode, where the power button in the top left hand corner is clicked to turn off the plug-in. This gives the same result as the 'Thru': the MIDI messages are not affected.

As an interesting extra, here's what happened when I tried the MIDI Monitor from the Max for Cats 'Gratis Hits' bundle pack of free Max For Live devices:


As you can see, the MIDIswapNVmr01 plug-in is disabled (powered off) and so the MIDI messages are unchanged, but the Monitor utility on the right has added an octave to each note number: C3 becomes C4, C4 becomes C5, and C5 becomes C6. I'm very used to seeing different octave numbers in MIDI software because there are various interpretations of the standard, and I tend to use whatever the software uses, which in the case of Ableton Live and Max is C3=60, so this has probably been fixed in an update, and I just don't have that update! One area that I steer well away from are any discussions about Middle C and MIDI.

Because this post has talked a lot about MIDI Note Numbers, then this seems like a good place to share two charts that I use a lot when I'm playing/programming. The first is a classic that you have probably seen in various forms before:


So the table above has notes along the top, and caves up and down, and lets you find the note number of any of the 128 MIDI notes. You can also use it in reverse - look up a number in the grid, and then read the note and octave from the two axes.

The second is more unusual...


This is a kind of 'inverted' version of the first table. It has decades (10s (tens)) on the vertical axis, and units (1s (ones)) on the horizontal axis. So to look up 65 (note F3 from earlier) you go down to the row that starts with 60, and then go across that row until you are in the column with 5 at the top. For 65 you get F 3 in the two boxes (note/octave). What is interesting about this are the patterns that you get when you take the usual '2 and 3' pattern of accidentals that you see on a normal music keyboard and wrap it around decimal numbers. The columns have either 3 and 3, or 2 and 4 patterns of notes, and the diagonals have more patterns: 3 and 4 and 2 and 3. if you are into patterns, then the last row of blocks of 2 always repeat the octave in the cell underneath, whilst blocks of 4 repeat the octave value of the cell above the first row. Block of 3 do different things depending on if they contain accidentals or not! If you are familiar with chess, then 'Knight's moves' on this table give you the cycle of fifths...

If you have ever seen one of my Tweets about cryptography, then my fascination with patterns now probably makes more sense. Music and cryptography both contain a lot of maths underneath, and so patterns are not unexpected!

Controllers and control

Swapping the note number for the velocity value renders makes it very difficult to play keyboards and MIDI controllers because the velocity value is often difficult to control with the same amount of precision as you would find on a keyboard where each key produces a specific note number. Velocity is determined by the rate at which the key is pressed down, and so is based on a time measurement. By swapping these two values, keyboards and MIDI controllers gain precise control over velocity (what used to be pitch control is now velocity control!), but lose the precision of pitch control.

Steganography


Steganography is all about hiding information in places where it is not visible. One example is in JPEG picture files, where it is possible to hide data inside them by spreading it across the whole picture in ways that are not obvious. So there might be slight and gradual changes to brightness, colours, levels of noise or other parameters, that are not visible o the human eye, but that can be detected.

In this case, MIDIswapNVmr01 increases the precision with which changes can be made to the velocity value, but the pitch becomes less precise - in fact, trying to control pitch by how quickly you press a key spreads out pitch control into a very imprecise form! In graphical form, this might be represented by the amount of blurring (as a metaphor for the spreading out of data):

So a conventional music keyboard has precise control over pitch, so the word 'Pitch' is in focus, whilst the velocity control is less precise, and so the word 'Velocity' is blurred.


What MIDIswapNVmr01 does is swap the blurring - so now the word 'Pitch' is blurred, whilst 'the word 'Velocity' is in focus.


At Synthfest UK 2019, I spoke to Paul Ward about some of the FM sounds that I had programmed anonymously for the UK DX Owners' Club (many of which are widely available in various Public Domain collections - one set of my sounds have distinctive titles like : '-=[V]=- 1', for example), where there was a high amount of velocity sensitivity built into many of them. Controlling them can be tricky for fast runs of notes, and so Paul said that he preferred to use controllers like Mod Wheels to give more precise control.


What MIDIswapNVmr01 provides is precise velocity control from a keyboard, but sacrifices pitch control. With a fixed velocity from a keyboard, then MIDIswapNVmr01 only outputs one pitch, but you have precise control over velocity - and in fact, even a 88-note keyboard is going to give you access to only part of the full 1-127 velocity range (in exactly the same ways as it only normally lets you play 88 of the 0-127 range of MIDI note numbers!).

Which is why I said right at the start that this was for experimental purposes. I'm not expecting a sudden change in workflow so that people enter pitches very precisely (as usual!) and then use MIDIswapNVmr01 to enable them to add precise velocity as well. But my thinking is that given recent developments with MPE, and with sophisticated controllers like the Roli Seaboard, Haken Continuum and Expressive E Osmose or Expressive E Touche (others are available!)  then it might make people think more about additional control other than the pitch, timing and a very imprecise velocity value that you get from a traditional music keyboard.

Real-world instruments often have a lot of ways that the timbre can be influenced in real-time, and their players know how to exploit this - so I reckon that electronic musical instruments should be controllable in multiple dimensions as well. One very interesting illustration of this is in sample libraries of sounds produced using FM synthesis - what you get are very nicely sampled 'snapshots' of specific timbres, but you lose a lot of the subtle velocity control that programmers like myself put into sounds, and so the timbral variation is missing. I always remember when the first mass-market sampled pianos came out in the 1980s (Technics et al) that they were described by many players as sounding like:

'A very good recording of a piano, but not a piano.' 

Inside

As I mentioned, this plug-in is based on the MIDI processing core of the MIDIfilterNOTEmr utility, so let's see how it works:


As usual, I have tidied my normally untidy code in the screenshot above. The right hand side is very similar to the MIDIfilterNOTEmr code, with the 'select' object switching between two values depending on the incoming value. But here the 'swap' object at the top is used to change the note number and velocity over (as well as changing their 'right=-to-left' processing order), and so the velocity value does the same switching depending on 'Note On' or 'Note Off', but now switches the note number value because that is what will end up in the middle 'velocity' input of the 'note out' object.

On the left hand side, the 'select' object is again doing switching, but this time it is actually making sure that the velocity value is stored. The velocity value that comes out of the 'swap' object contains two values, the velocity value from the incoming notes, or zeroes from the Note Off messages. So the left hand side is all about capturing the non-zero velocity value, and making sure that it is stored when the zero velocity is output by the 'swap' object. So the two grey message boxes are just two stores in series, and the trigger for the storing is produced by the 'select' object when it detects a Note On or Note Off message. Finally, that captured and stored velocity value is fed into the left hand 'Note number' input of the 'note out' object. 

This approach could be extended to longer serial chains, and might open up additional possibilities for doing more complex MIDI processing. Because some previous posts have talked about Max's sample-level lower-level programming, then the message box approach used here could be thought of as being kind of half-way between ordinary Max and Gen: MIDI-event-level, perhaps? 

Fun!

One unintentional side effect of MIDIswapNVmr01 is that it makes playing a music keyboard in the conventional way almost impossible... So if you are every visited by a highly skilled concert pianist, and they want to play one of your keyboards, then using MIDIswapNVmr (to swap the MIDI note number and the velocity value of their playing) will considerably impede them...

Alternatively, sometimes, changing a familiar constraint (like pitch control from a keyboard and changing it to being controlled by velocity) can break you out of creative road-blocks... Inverted keyboards are another way to do this, and I have produced a Max For Live plug-in that does 'proper' inverted MIDI keyboard mappings and lots more!), but just using a Scale utility over an octave can achieve a similar 'writer's block' mitigation.

Actually, combining the ideas in the previous paragraph - adding a Scale utility after MIDIswapNVmr01 so that the MIDI notes are constrained to a specific scale - is a very practical and useful way of using many of my weirder plug-ins (like my MIDI note range expander/compressor and offset utility). What the Scale utility is doing is constraining the variability from the velocity measurement, which takes us to the several variations of 'constrained randomness' in another of my plug-ins.

I'm wondering if I can find time to do a 'how to use my plug-ins in combination' tutorial...

Getting MIDIswapNVmr01

You can get MIDIswapNVmr01 here:

     https://maxforlive.com/library/device/6081/midiswapnvmr

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 MIDIswapNVmr01 depends on your MIDI/keyboard interface. If that produces CV outputs for Note Number (Pitch) and Velocity, then a couple of patch cables crossed over and connected to the output (with a gate cable as well) will do this directly, giving an ME of 1! This is the lowest modular equivalent so far, if my memory serves me correctly...

Links from this post:


Roll Seaboard (Company web-site)

Haken Continuum (Company web-site)

Expressive E Osmose (Company web-site)

Expressive E Touche (Company web-site)

MIDIfilterNOTE (MaxForLive.com)

MIDIfilterNOTE (Blog post)

Christian Henson (YouTube channel)

#pianobookpianoday2020 (YouTube search)

---

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











Tuesday, 3 January 2017

MIDI Interfaces and Modulation Wheel Messages

Sometimes, without any warning, an apparently trivial and simple task can suddenly explode into a major problem. Of these, the most interesting problems are the ones that can't be solved by merely researching the topic on the Interweb.

Modulation Wheel -> MIDI Controller Messages

So there I was, working on a new Max For Live (M4L) plug-in, and I needed to control a parameter from an external MIDI keyboard. Rather than force users to map a MIDI Controller to the parameter inside Live, I thought it would be easier to provide a dedicated pre-mapped controller inside the plug-in itself. But it didn't work in the way that I expected.


I was using the Modulation Wheel on one of my synths to provide the MIDI Controller messages, and these were supposed to be controlling a parameter in the plug-in with 32 values - displayed as several rows of buttons.  Inside Max, I scaled the range of the controller value to 32, and then moved the Mod Wheel, expecting the buttons to highlight in sequence. Instead, I found that the highlighting jerked around, and even when moving the Mod Wheel slowly and carefully, I couldn't select some of the buttons. Suspecting that the Mod Wheel value needed smoothing, I used Max's 'slide' object to provide some low-pass filtering, but the jerkiness and quantisation were still present. It was at this point that the 'This is interesting' light lit up in my head, and I started to gather more detailed information about what was happening. Here's what I expected:


There should be a linear mapping between the input values from the Mod Wheel, and the output values that are driving the button selection. Because I was using integer numbers to do the selection, then the making of 128 MIDI Controller Values to the 32 M4L buttons should be a four-to-one reduction. The graph on the right hand side shows the details of this. Input values of 0 or 1 (from the Mod Wheel) will produce an output value of 0, whilst values of 2, 3, 4 or 5 will produce an output of 1, and anything from 6 to 9 will produce an output of 2, and so on. 


So the nice straight line in the left hand diagram is a simplification - actually it is made up of lots of little flat segments that map 0 and 1 to 0, 2 o 5 to 1, and so on. This table shows the ends of the complete map - notice that 126 and 127 produce an output of 32.

Now, normally, when you use a Modulation Wheel, you are not looking for precision, and so I expected to have to smooth the values a little bit. But this was much worse than that. The jerkiness was stopping me selecting specific buttons, and that's exactly what I needed to be able to do. What was needed were a few tools, and that's what I wrote next.

Simulation and Analysis Tools

The first tool was a MIDI Continuous Controller simulator - a replacement for the Mod Wheel created using M4L. (To avoid putting MIDI Continuous Controller every time, I will use the shorthand of 'MIDI Controller' here - I could have used 'CC', but that's used in the tool-name!) Because I might use it again for something else, I made it reasonably general purpose, and so it allows the setting of any MIDI Controller Number, plus it has quick access to specific Control Change values.


As the screen-shot shows, the middle slider is the main controller, and it simulates a Mod Wheel with forwards and back (or typically up and down on the screen) mouse movements controlling the output values. The grid to the right is actually a 2-axis controller, so more a joy-stick than a Mod Wheel - you move the mouse over the array of dots, and the appropriate MIDI Control Change values are sent for the selected MIDI Controller Numbers. In the screen-shot, the horizontal axis (left-right mouse movements) are set to MIDI Controller Number 1 (Mod Wheel), whilst the vertical axis (up and down mouse movements) are set to MIDI Controller Number 16 (a general purpose controller). The buttons on the right hand side allow specific Control Change values to be sent (0, 31, 63, 95 or 127) covering the whole of the available 7-bit range. Now it is possible to use 14-bits to provide extra fine detail, but in this case, with only 32 buttons to control, I didn't need it. For user-defined special values, then the second row of buttons allows you to set your own values - in the screen-shot, I obviously wanted to have five different ways to output zero!

The second tool allows analysis of the values produced by the Controller simulator, and has lots of scrolling displays that provide plots of values over time. These are the same type of display as I used in the Mode Audio VeloView MIDI Velocity viewer that I've included on the right hand side of the screen-shot.


The main scrolling display allows the selection of the MIDI Continuous Controller Number, whilst there are separate scrolling displays for Data Entry (Controller Number 6) and Number 16. At the far right hand side, I have copied in the 32 buttons and the scaling and offset controls. Unlike the MIDIcc utility, this is much more a draft tool for my own use, and it isn't intended for casual users.

The Setup

Using the MIDIcc Continuous Controller simulator, the 32 buttons were easy to select with mouse movements, and substituting the Mod Wheel again produced jerkiness and difficulty in selecting a specific button. This meant that it wasn't my M4L processing that was causing the problem, but something else. Tracing back from the Plug-in, the MIDI signals went through Live, then through a USB cable to a MIDI Interface, and then to the synthesiser. The simulation worked okay, so Live was not the problem, which left the USB cable and the MIDI Interface... Changing the USB cable made no difference at all, and so that left: the MIDI Interface, or the synthesizer. Changing the synthesizer made very little difference, so it seems that the MIDI Interface is the major contributor.

I'm going to split MIDI Interfaces into three types, and use these to avoid naming any brand names in what follows. The three types are:

1. Low-cost, simple,  in-cable interfaces. These typically have a MIDI In and Out cable, a plastic 'blob' in the middle, and a USB cable.

2. Mid-range, robust, stand-alone interfaces. These typically have MIDI sockets for In and Out (sometimes a Thru as well), and a USB socket. Some USB audio interfaces also have this type of MIDI interface included as well.

3. High-end, professional, multi-MIDI-cable interfaces. These have 2, 4 or 8 MIDI I/O sockets, are often rack-mountable, are almost always rugged designs with metal enclosures, and often have time sync facilities.

Inside a MIDI Interface

Inside a MIDI Interface, there are two sections: one grabs incoming MIDI messages from the MIDI In and sends them to the computer via USB; the other receives outgoing information via USB and sends them out via the MIDI Out. Here's the route from the MIDI In to USB:


The UART is a device that converts the serial data for the MIDI device into data in a format that the Main Processing Unit (or microprocessor) can work with by stripping off the start and stop bits and buffering the MIDI data. AT the output, another UART converts the MIDI data into the right format for USB. The MPU loops around, grabbing incoming MIDI messages, and sending them out to USB continually.

Interestingly, inside the microprocessor chip itself there are additional conversions going on:


Most modern microprocessors have serial interfaces externally, but internally, it is much faster to have data in parallel, and so there are more UARTs to convert to and from serial and parallel.  

For MIDI Output, things just work in reverse in the other section. This time the MPU grabs outgoing USB data and converts it to MIDI data, with a UART formatting it correctly for MIDI transmission.

Inside a synthesiser

Just for reference, here's how the Mod Wheel typically works inside most synthesisers.


The left-most part is the Mod Wheel, which is just a modified rotary control where you move the edge of the knob, and this produces an output voltage. This is smoothed by the RC low-pass filter (just a resistor and a capacitor) and then converted into digital form by an Analogue-to-Digital Converter (ADC). Once in digital form, the processing is very similar to the MIDI interface: the MPU loops continuously, grabbing the Wheel position from the ADC, then converting it into a MIDI Control Change Message, and then outputting it to the MIDI Output with a UART.

Testing

I tried examples of each type of MIDI Interface to see if it made any difference to the controllability of he 32 buttons.

Unexpectedly, the type of MIDI Interface made a huge difference!

At this point, I should explain how the scrolling displays in the analysis tool work. Each time a new MIDI Control Change value arrives, it moves the display to the left, and draws a vertical line representing the new value. The result is that the display scrolls leftwards as new values as received by the tool. This removes any dependence on timing, and gives a pure mapping between the incoming values and the display. Just as with the diagram at the start of this blog entry, the output should be linear for rising controller values, and linear for falling controller values. Any missing values will appear as a vertical jump, any repeated values will appear as horizontal flat segments, and any zero values will appear as gaps.


A perfect MIDI Interface would produce neat straight-sided triangles as the Mod Wheel is moved up and down (and the MIDIcc tool produces perfect triangles (as above), of course!)

 
Low cost, type 1 MIDI interfaces give different slopes each time, with missing values. The low cost probably means that a slow MPU with just enough processing power is used, and this is fine for most of the time, but runs into trouble when lots of messages are received all at once - as with sending lots of MIDI Control Change messages when using a Mod Wheel! (One other time that processing bandwidth is important is when using System Exclusive messages, and so they may also cause problems for this type of interface... I didn't test this.) The warped triangles explain why the Mod Wheel was so difficult to use to select buttons!


Mid-range, type 2, MIDI Interfaces give very good results, with only a few missing values. In this type of design, the internal microprocessor is probably better specified to cope with demanding situations, and the result is a pretty linear triangle.


High-end, type 3, MIDI Interfaces give good results, but not quite as good as the Mid-range, and this might reflect the higher processing demands of multiple MIDI sockets and time synchronisation.

Here's a summary of the three types:


 For each type, the left hand column shows the biggest jumps between Control Change values (higher is worse), and then the right hand column shows how many different values were transmitted by the MIDI Interface. So the Low-cost type 1 only sent 25 messages with the largest gap of 13 when movie the Mod Wheel upwards, and only 32 messages when moving the Mod Wheel back to the resting position. In contrast, the Mid-range, type 2, MIDI Interface produced nearly three times as many messages (72) and had the smallest gaps (6).

The 'Min' and 'Max' values are interesting because they show the highest and lowest values sent in the Control Change messages. A Mod Wheel should produce a value of zero when it is in the resting position, but the low-cost interface only ever sent 3 as its smallest value. In my M4L application, this means that the first button could never be selected! (I cured this by adding an offset so that the Mod Wheel has 'dead'-zones as the two ends of its travel.

Conclusion

Choosing a MIDI Interface may affect your performance in ways that you don't expect!

MaxForLive Tools - downloads

The MIDIcc simulator utility and the CC Analysis tool are now available via MaxForLive.com.


In the course of developing the Analysis tool, I realised that the 'All MIDI Data' display was very useful, and so I have extended this into a separate stand-alone utility called MIDIview, where each type of MIDI data has a different colour.  This is also now available on MaxForLive.com.




Sunday, 20 November 2016

MIDI Processing - MIDI f(x)_mr

MIDI Experimentation

My latest Max For Live MIDI device for Ableton Live is several MIDI processing functions in one! (some of them unusual and/or experimental)
  • Filtering                       (ok, so not very experimental), 
  • Note transpose             (er, just a bit ordinary...), 
  • Velocity shift               (quite unusual, and very useful), 
  • Note Invert                  (very unusual), 
  • Velocity invert             (experimental, and pretty unusual), and 
  • a deterministic pitch mapping utility that is based on pitch multiplication and modulo arithmetic             (very experimental). 
The name 'MIDIf(x)_mr' is intended to let people know that this is a unusual and different MIDI device.

Use at your own risk. (Putting 'Scale' or one of those other 'MIDI scale'-adjusting M4L devices after MIDIf(x)_mr (with appropriate settings in 'Scale'!) is recommended for those people who don't like too many accidentals infesting their music...) And have fun! (Oh, and if you get 'stuck' notes, then click on the '!' button to flush things clean again.)

MIDI f(x)_mr

Here are some details of the processing:

MIDI Filtering

The MIDI Filtering allows rapid removal of notes, continuous controllers, after-touch(channel pressure) or pitch-bend, and I often have it set so that it just lets notes through an filters everything else out.

Note transpose

Note transpose just transposes the incoming MIDI, and is included here because it is useful to have in a multi-purpose utility, but also because it was very useful during the development process! The rotary control is labelled "Offset' because that's what it is doing: adding an offset to the MIDI note numbers.

Velocity shift

Velocity shift (just rotate the 'Offset' control) is useful to compensate for keyboards the require playing hard to get decent amounts of velocity, or for sound modules that require high velocity inputs to produce a sound at a decent volume. The rotary control is labelled 'Offset' because it is adding an offset to the MIDI velocity value for Note On messages.

Note Invert

Note Invert is one of those 'fun' utilities that is usable once with someone who has never seen a reversed keyboard, where the high notes are on the left, and the low notes are on the right. Actually, it can also be used to create interesting bass notes that don't just predictably track the root. The 'Offset' rotary control can be used to set the keyboard so that any key you choose is the same on the inverted keyboard. I tend to use middle C (=60 sometimes) as my reference, but you may find it interesting to choose other values and see what happens.

Velocity invert

Velocity invert is another 'fun' function that upsets people who expect sounds to be louder when you play harder. But it is also very useful for creating 'velocity layering in layered sounds - use inverted velocity on one of the layers and you can control the two sounds just by playing harder or softer. Once again, the 'Offset' control is merely adding to the MIDI velocity value, and this time can be used to compensate for the bias of your keyboard's velocity calibration, or any bias in your sound generation modules. Also see this blog entry: Inverted MIDI Velocity

Pitch Mapping...

And finally, there's that weird-sounding deterministic pitch mapping utility that you were going to ignore... As it happens, not exploring it would be a pity because there's lots of scope for exploration here. You get two stages of 'pitch scaling, followed by wrapping round of the notes', which is achieved by multiplying the incoming pitch, and then applying modulo arithmetic to the result - and then doing it all again. Some people will tell you that multiplying MIDI note numbers does not produce useful results, whilst other people will tell you that you need to constrain the resulting interval madness with processing that wraps the result into manageable lumps. I'm with the 'others'.

So the 'Range' control lets you adjust from the usual '1 octave in = 1 octave out' scaling, to 1 octave in = 3.55 octaves out' super broad scaling where the two stages let you do this twice, resulting in a single octave spanning 7 octaves (and also meaning that a lot of notes are missing!).

The 'Limit' control can be used to bring that huge span under some sort of control. If you set the limit to 1, then you only get a single note out. if you set it to 12, the you get 12 notes out, and any input you put in just wraps round and round those 12, so the same 12 notes repeat themselves all across the keyboard range. If you set it to 128, then it is the same as if it was not there at all, of course!

The best way to learn how to use it is not to set the Range of one section to 1.10, leave the other Range at 1.00, and set both Limits to 128 - this gives a keyboard which is almost right (emphasis on 'almost'). Much better is to create an 8th note looped sequence (a rising scale is fine), and then to explore just one of the two processing sections. The 1.1 Range with a Limit of 12 is a good stating point - you will need to adjust the Offset control to get the output into a sensible range (watch the left and right numbers to either side of the 'MIDIf(x)_mr' title - I use middle C (=60 sometimes) and tweak the Offset to get 60 at the output). Listen to what happens with the looped sequence, and then try adjusting the Range or the Limit. Just hopping back and forth between a few range settings is pretty cool for starters...

Memories

The small white boxes are the usual 'memory' buttons that M4L provides. You shift-click in a box to save a setting, and just click on a box to recall the stored settings. Empty boxes are white in colour, whilst boxes containing saved settings ae orange. The current setting is bright orange.








Scaling

The output of MIDIf(x)_mr is scaled in pitch, and so can contain all sorts of note numbers. Using something to constrain the notes to a scale is a good idea in many applications. You can use Ableton's own 'Scale' utility for this, or search 'Max for Live.com' for 'midi scale' devices, and se what comes up - when I searched there were several different possibilities to try out.

Enjoy!

As usual, this is experimental stuff that I'm more than happy for you to play about with, and it may or may not do what you want, or even what I intended it to do. Let me know if you have any problems, and I may be able to find the time to fix it or even improve it...

I have added a new blog entry that explains some of what is happening inside the 'Warp' processing part of MIDIf(x)_mr. More information can also be found in this blog entry on one of the tools used to develop MIDIf(x)_mr.

Also see: Inverted MIDI Velocity