Tuesday, 7 April 2020

Max For Live 'Control Voltage' Smoothing device for Ableton Live...

I admit here and now that I don't know what to call the signals that go from an LFO to a mapped parameter in Ableton Live. If they weren't inside a Digital Audio Workstation (DAW) but were transferred by patch cables in a modular synth, then I would call them 'control voltages'. Ableton call the process 'remote control', but they don't seem to say what the signals are called. So in the absence of any authoritative guidance, I'm going to call them 'control voltages' but in quotes - that way I'm trying to indicate that they aren't voltages, but that I'm hijacking the phrase because I don't know what they should really be called...


But I do know the name of the subject of this blog post: MIDIsmoothR! A combination 'control voltage' smoothing / slew rate limiter, plus a random 'control voltage' source. Here's the story of how it came to be:

The story



When I published MIDIrandomA and MIDIrandomABC, they were intended to be interesting alternatives to the LFOs that are often used as sources for 'remote control' of parameters in Ableton Live. Particularly the 'random' 'noise' waveforms that old-school synthesists like me call 'Sample & Hold' or 'S&H', even though there's a whole unspoken abbreviation in there - we mean: 'the jerky segmented waveform that you get when you apply a Sample & Hold device to a Noise generator' and the source of the resonant filter cut-off sound cliche.

In a world where there seems to be an assumption that noise comes in only three flavours: 'white', 'pink' and 'coloured' (The terminology is derived from the same spectrum-based descriptions as for light. So 'white' light contains all of the visible wavelengths, just as white noise has the same intensity at every audible frequency. Pink light contains more lower wavelengths (at the 'red' end of the spectrum) and so pink noise contains more lower frequencies.) Anyway, just as there are lots of different colours of light, so there are many, many different types of noise - from rumbles to hisses, with wind and 'waves breaking onto the sand' somewhere in there as well.

MIDI effect devices with names containing 'LFO' almost always provide a 'Random' waveform. Sometimes there are two different versions: a pure noise waveform, plus a flat segmented 'Sample & Hold' version. The problem is that having just a single jerky segmented 'Sample & Hold' waveform assumes that the distribution of values is right for your application, and it might be that you do not want each possible level to happen with the same probability. Which is where MIDIrandomA and MIDIrandomABC's remit comes from - lots of different varieties of random, noisy 'control voltages'.


But sometimes that S&H waveform is too jerky, and you need something more rounded, which is where MIDIsmoothR is used. It allows the 'control voltage' 'remote control' of any LFO or other MaxForLive device to be smoothed with a three different processing options. Just map the LFO or other device so that it is 'remote controlling' the 'CV in' rotary control in MIDIsmoothR, and set the 'input/Random' selector switch to 'Input' so that the 'control voltage' will be processed inside MIDIsmoothR.

The 3 processing channels? A allows waveform quantisation and power-law distortion. B allows separate smoothing to be applied to the rising and falling parts of the incoming waveform (plus global smoothing as well). C allows you to remove rapid changes (below the limit set by the 'Delta' rotary control), and then allows that to be smoothed. You can choose which of these smoothing/processing options is sent to the output with the A/B/C switch, and then offset or scale the value that is sent to the parameter which has been selected by the 'Map' button. (Click on 'map' and then click on the parameter that you want to control...).

If you switch the 'Input/Random' selector to 'Random', then MIDIsmoothR behaves very similarly to MIDIrandomA, although the A, B and C channel processing/smoothing is slightly different. As the name suggests, MIDIsmoothR is designed for smoothing!

The big selection box on the upper left hand side chooses how the input is sampled. The 'Not synced' top option uses the LFO clock set by the 'Rate' control to grab the input value. The other options on this selector allow various MIDI messages to trigger the sampling:

- Any MIDI Note,
- Any change of MIDI Note number (so repeated notes will not trigger the sampling),
- MIDI note number 0 (the lowest MIDI note),
- MIDI note number 0 with a velocity of 1 (the lowest note and the quietest velocity value), or
- Any MIDI note with  velocity of one (the quietest velocity).

Three in One

It isn't immediately obvious when you first look at MIDIsmoothR, but it actually allows you to do three different things:

- Process 'remote control' 'control voltages' in various ways, including smoothing (sometimes called 'slew rate limiting' on modular synths)
- Generate random 'control voltages' and map them to controls in other devices (Ignoring the 'CV in' rotary control)
- Sample & Hold 'control voltages' from other devices (LFOs, MIDI Controllers, etc.) using MIDI event triggers and use that to control other devices

If I can think of anything else that I can squeeze in there, it will be in a future update... And on that topic:

Version 0.01 had a bug in channel B, which caused a fixed value to be output. This is fixed in version 0.02.

'Remote control' processing...

MIDIsmoothR is quite unusual - there aren't many 'remote control' 'control voltage' processing devices written in MaxForLive for Ableton Live (or indeed, native devices from Ableton!). Normally, you use the 'Map' button to send 'control voltages' over the 'remote control' system from a device that produces 'control voltages' (like an LFO, or MIDIrandomA!) to a control parameter in a device that you want to control (just about any parameter (rotary controls, sliders, buttons... in just about any device). But MIDIsmoothR goes in-between those two devices, modifying/processing the 'control voltages'. (For a while, I did wonder if I should call it PROCsmoothR...)


Above is a diagram of a 'remote control' connection from an LFO to a Delay device. The LFO 'Map' button would show that it was controlling (for example) the time delay buttons in the Delay device.

Adding MIDIsmoothR to process the 'control voltage' looks like this in Ableton Live:


On the left side, the LFO 'Map' button shows that it is controlling the 'CV in' rotary control in MIDIsmoothR (and note that the input selector in MIDIsmoothR is set to 'Input'). On the right side, the MIDIsmoothR 'Map' button shows that it is controlling the time buttons in the Delay device.

(The 'L' is because this is where the mapping was set up - to the Left channel time delay buttons in Delay. But the 'sync' button is active in Delay, and so the right time delays are the same as the left buttons. You can see two channels of random 'control voltages' mapped to the left and right time delay buttons separately (sync is off) in the blog post about MIDIrandomABC... and you can hear the effect in this SoundCloud demo...) 

So the 'remote control' connections diagram now looks like this:


The LFO controls the CV In rotary control of MIDIsmoothR, which processes the LFO waveform and then controls the time delay buttons in the Delay device. Although you can't see the connections explicitly in Ableton Live, the text that replaces the 'Map' in the 'Map' button gives slightly cryptic clues...

In use

You could apply different random delay times to different notes in a sequence, which sounds really unusual.

Or you can randomise the detune of a two oscillator synth...

Or you can use a smoothed 'control voltage' to change the Size or Decay Time parameters of a Reverb, which can sound a bit like granular synthesis. Randomly changing the 'Diffuse' parameter in a Reverb sounds like a more sophisticated version of the classic 1980s 'gated reverb' effect...

Getting MIDIsmoothR_mr02

You can get MIDIsmoothR_mr02 here:

     https://maxforlive.com/library/device/6116/midismoothr

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 MIDIsmoothR_mr02 requires some quite sophisticated processing of a random noise source, so it probably isn't straightforward to do from off-the-shelf analogue modules, and is probably easier to do digitally. Assuming that a maths/data processing module can do the required computation, then there's one noise generator, one processing module, some triggering logic, an LFO for the free-running version, and a sequencer for parameter storage, giving an ME of 4 or 5!

---

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








Sunday, 5 April 2020

Three Mappable outputs of controllable Random-ness in Max For Live for Ableton Live

Comments are always interesting - once you've filtered the spam and adverts out, of course! So when blog reader hems reminded me in a comment that having just one mappable output in RandomA was quite limiting, it nudged me into a new variant of MIDIrandomA...


MIDIrandomABC has three separate mappable outputs that can each be assigned to any of the three built-in types of randomness: called A, B, and C for brevity. So you can now control three parameters in Ableton Live with the same value, or an inverted version, or a scaled and offset version, etc. This enables lots more control over what you randomise and how!


One application that I've been playing with (I've watched too much Ricky Tinez videos on YouTube) is to control the delay time for left and right channels separately in the stock Ableton Live 'Delay' plug-in (other delays are available) as well as the feedback amount. Using the 'Any Note' mode, then the random vlues change for each note event in a clip, and so you get 'per note' changes to delay times and feedback. This sounds really rather nice - the sort of variability that tends to be more associated with modulars than DAWs... I can see that I will have to do a SoundCloud track and YouTube video when I have a moment...

Getting MIDIrandomABCmr02

You can get MIDIrandomABCmr02 here:

     https://maxforlive.com/library/device/6110/midirandomabcmr02

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 MIDIrandomABCmr02 requires some quite sophisticated processing of a random noise source, so it probably isn't straightforward to do from off-the-shelf analogue modules, and is probably easier to do digitally. Assuming that a couple of maths/data processing modules can do the required computation, then there's one noise generator, two processing modules, some triggering logic, an LFO for the free-running version, and a sequencer for parameter storage, giving an ME of 6 or 7!

---

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





Saturday, 28 March 2020

Music By 300 Strangers = 380 plus me

Every so often, I contribute to a project, safe and secure in the knowledge that no-one will ever hear of it, or hear it. Well, it may be that this time it might be different...

Over the last few weeks, a lot of musicians, who normally contribute virtual instruments, demos, and information to the pianobook.co.uk web-site and forum, have been working on a collaborative 'systems music' project set off by Spitfire Audio's amazing Christian Henson (his Twitter picture should be on the left...) for Pianoday 2020 - the 88th day of 2020 (88 keys!). And, yes, I was a contributor...

Here's the original 'call to arms' from the end of February 2020...







Here's the splash screen from just before the YouTube video of the World Premiere, which was at 17:00 on Saturday the 28th March 2020 (the 88th day, of course):


Christian explains a lot about how the music was made here.

My contribution...


For my contributions I used my MaxForLive chord device, ProbablyChord, to automate the chord sequence provided by Christian, and used the constrained random controls to produce random inversions of the chords. The sounds that I used were produced by the 'Synthesizerwriter's 29 Bagpipes' virtual instrument that is available free on pianobook.co.uk.


Here's the bit in the main 'Music by 300 Strangers' where you can see my screenshot:


...and in the credits...




 ...there I am. My name in lights! Wow!

Links:


Pianoday 2020.   The official web-page for Pianoday 2020

Yamaha's Piano Day page.  Yamaha's page on Pianoday 2020

pianobook.co.uk. The Pianobook page

The collaboration project   Christian's 'call to arms'

systems music. What is 'systems music'?

ProbablyChord.   My MaxForLive device that I used to make my contribution

Synthesizerwriter's 29 Bagpipes.  The source of the sounds that I used in my contribution

YouTube video of the World Premiere.    The World Premiere YouTube video...


---


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




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:











Thursday, 19 March 2020

The Allegorist - musical stories available now on Soundcloud, iTunes and other digital streaming services...

I may have mentioned this before...but in case I haven't...

I was at Ableton Loop 2017 in Berlin, at the Funkhaus. In one of the studio sessions, Mandy Parnell gave her opinion on the submitted tracks from a mastering perspective... But one track submission got a totally different reaction: stunned silence! After the session, I provided links for various routes forward (because I was very impressed)...

So here we are three years and two albums later, and it seems like a good time to remind people that there are musicians out there who produce amazing innovative music that is light-years away from all of the usual 'sounds-the-same' stuff that you keep hearing everywhere.

The artist that I'm talking about here that tells stories with music is called The Allegorist.

Link to website:

https://www.theallegoristmusic.com/


Links to releases:

https://soundcloud.com/the-allegorist/levitating-forms

https://music.apple.com/gb/album/hybrid-dimension-i/1410330170

https://music.apple.com/gb/album/botanical-utopia/1121509558


Links to live performances:

https://soundcloud.com/the-allegorist/live-at-suicide-circus

https://soundcloud.com/the-allegorist/live-at-ctm-festival-2020

https://soundcloud.com/the-allegorist/noods-radio-liar-bird-live-exploration-007-w-the-allegorist-04022020

https://soundcloud.com/the-allegorist/live-at-elektron-studios-berlin







Friday, 28 February 2020

Low-latency MIDI Note Filter (& Monitor) in Max For Live for Ableton Live...

I can't remember where I saw the question.

But, anyway, here's the answer. A Max For Live plug-in that does MIDI Note filtering (maybe sieving is a better word), polyphonically, with quite low-latency (in the MIDI path, there's a single look-up table, no multiplies, and definitely no modulus or division operations.) and it even monitors the incoming MIDI notes so you can see what notes you might then want to filter. It might be possible to speed things up more using Gen, but that's for another day or two...


(What usually happens with these things is that despite me diligently searching around, I won't have found any examples of this type of utility... But the moment that I publish one, I then discover that there are zillions of them already out there, normally with one standard 'classic' that 'Everyone' uses. So I will apologise in advance, now, up front, for releasing Yet Another MIDI Note Filtering Utility. (YAMNFU) I think of this as a 'discoverabilty' paradox, and I nearly got a patent based on something related, but that's another story, and this isn't that type of blog...)

MIDIfilterNOTEmr


The screenshot above shows MIDIfilterNOTEmr actively filtering C3 and D#3 out of a MIDI stream. Here's a conceptual diagram of what it does:


Imagine all the notes being sorted and separated into separate flows, and then going through tubes: one tube per note. Unfortunately, the C2 and D#2 tubes are sealed up with rubber bungs, and so no C2 or D#2 notes will get through. MIDIfilterNOTEmr is like a 'sieve', really.

So those two highlighted light purple notes mean: 'remove these note from the MIDI stream.'


Here's a diagram that shows the filtering or sieving process happening with piano rolls:


And in detail for MIDIphiles... (One thing does intrigue me about the timestamps in the screenshot below - the time delay through MIDIfilterNOTEmr seem to be negative. I would love to know what is happening!):


Finally, a screenshot of what you would see in Ableton Live during debugging or testing:


The MIDI flow is from left to right, so the first MIDI Monitor shows the six notes that are coming from the clip. These then pass into INSTfilterNOTEmr, where the D, D# and E are highlighted, and finally, the MIDI flows into the right hand MIDI Monitor plug-in, which  shows that the highlighted notes have been removed.

(I changed the highlighted notes because the MIDI Monitor plug-in starts at C, and I wanted a gap in the block of notes!)

Walkthrough



Probably the first thing to do with INSTfilterNOTEmr is put it in Monitor mode, so that you can see the notes which are passing through it (When it isn't Monitoring, it is Filtering or Thru'ing). Notes that are detected are highlighted in what I will call light purple - the phrase 'light blue with a hint of purple' is too long.

Based on those notes, you then select the ones that you want to pass through, and you press the 'Run' button. So whilst it technically is a 'filter', a better description might be to call it a 'sieve' - because you can set individual notes to be removed. The notes you have selected (one note is fine, too!) will be shown as light purple in colour, and they will then be removed from (filtered out of) the MIDI stream that is passing through the plug-in - actually, if you look at the MIDI stream, then you will find lots of MIDI Note Off messages, which is something that I previously exploited in the MIDIprob devices. Basically, if you set the velocity in a MIDI Note On message to zero, it becomes a Note Off message. To stop the filtering, then you press the 'Clear' button, and all notes will then pass Thru the plug-in, unimpeded.


If you want to add or remove notes, then click on them in the keyboard graphics so that they are no longer light purple, and then click on the 'Run' button again to update the filter.

If you want to turn off the filtering then you can just use the 'Power' button in the top left hand corner. If you click on the 'Clear' button then that does indeed put the device into 'Thru' mode, but it also clears the notes! I did wonder about adding another button called 'Thru/Filter' that doesn't clear the highlighted notes, but the 'Power' button does this already!

(Because I'm using Max For Live and Ableton Live here, then I'm using the 'C3=60' MIDI Note numbering convention. I know there are other conventions, and the whole 'MIDI and Middle C' topic is one that I steer well away from.)


In Monitor mode, incoming notes are shown as light purple.

In Run / Filtering... mode, notes that will be filtered out are shown as light purple.

In Clear / Thru... mode, all notes should be white or black as usual.

The '!' button is a  panic button that should stop any stuck MIDI notes. My usual 'borax-object-based 'held notes' prevention stuff is built-in, so hopefully you should never need to press this button.

The block of squares are 18 preset memories. Shift-click to store a filter. Click to recall a filter. Shift + (option/alt) to delete. MIDI Program Change messages (0-17) can be used to recall presets (1-18).

The presets are stored with the plug-in when you save a Set in Ableton Live.

MIDIfilterNOTEmr01 does something that I'm not very keen on with its user interface. Instead of being modeless, there are several different 'states' that it can be in. Now I know this is bad design, but in this case the alternative would be real coding, and Max For Live is quite tricky enough for me.

Using it.


Please. Try it on the output of arpeggiators, on the output of drum clips (to save muting with those little buttons), or on the output of clips that have too many notes! You can thin out pads or melodies, or even create motifs from blocks of notes that are too dense and unstructured to be usable conventionally. You can bring order to chaos by restricting the output to just a few notes, even though the input is lots of notes (so perhaps in installations and performance...).

You could even use it as a huge version of the factory Scale plug-in that isn't restricted to a single repeated octave - with MFNMR the entire MIDI Note range is available to you. (Ah, and that's an important consideration - one way of doing a similar type of filtering/sieving is just to transpose the notes that you don't want to note number zero, or note number 127, and to rely on most synths not being able to make a noise that low or that high. MFNMR allows you to create music for whales and for bats, and anything in between, with no restrictions.)

So, nothing much in the way of applications then... I'm kind of intrigued that there isn't something like this in the Ableton factory set of MIDI plug-ins - and I know that you can do this by using a MIDI Effect Rack and having 128 Velocity plug-ins in it, and 128 rows (one per note), and a lot of time and effort, and you get a 'less than perfect' user interface for your time and trouble. But you can do it - I just prefer something a little neater. (but don't look inside: I'm not noted for my tidy M4L coding...

Inside

Oh, and here we are inside.

The Max For Live code to do this 'sieve' or 'filtering' process is quite simple:


1. Clicking on the keyboard graphic object highlights the notes in light purple, and these are sent to a 'list'. The 'list' is the contents of the grey box full of 127 '1's: one per MIDI note number. Highlighted notes would replace the 1 with a zero in the list. In the case shown, there are no highlighted notes, so there are no zeroes in the list - but imagine that there are one or two!

2. MIDI arrive at the input of the device.

3. Only MIDI note and program change messages are needed for processing in this device, so the 'midiselect' object extracts those from the MIDI stream and sends the remaining MIDI messages to the 'idiot' object, which acts as a MIDI 'Thru' to the next device in the chain in Ableton Live.

4. The MIDI Note messages are decoded into 'note number' (the left hand output) and 'velocity' values (the right hand output).

5. This section processes the MIDI velocity value. The 'zl lookup' object takes the 'list' and treats it as a look-up table: it 'looks up' each MIDI note number and sees what value is stored in the list at that position, and then outputs that number. So if MIDI note number 0 had been highlighted, then the first number in the list would be a zero. The output of the 'zl lookup' object goes to the 'select 0' object, which does one of two things: if the input is a zero, then the left hand output activates, and that little grey box will output its contents: a zero. if the input is a 1, then the right hand output will be activated, and this time the little grey box will output the value of the velocity from the 'unpack' object. So when there is a zero in the list, the velocity is going to be zero, but when there is a 1 in th list, the velocity is going to be left unchanged. So when there is a zero in the list, whatever the velocity value was is replaced with a zero, and a zero velocity value means a Note Off, so the Note On is changed to a Note Off, and the note has effectively been removed, filtered, sieved...

(Those little grey boxes are very useful. Notice how one of them is just a store for the value zero (which never changes), whilst the other is a store for the velocity (which changes all the time). So the same little grey box does two different things!)

6. The MIDI note number and the processed velocity value are turned into a MIDI Note message and sent to the MIDI output, thus going to the next device in the chain in Ableton Live.

Getting MIDIfilterNOTEmr

You can get MIDIfilterNOTEmr here:

  https://maxforlive.com/library/device/6023/midifilternotemr

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 MIDIfilterNOTEmr is tricky. I'm not aware of a MIDI processor utility module or CV processor module that does this type of filtering for more than one note at once, and so we enter the awkward territory of needing 128 pretty-sophisticated utility modules, plus loads of parameter storage, and an ME of over 150-ish. Using programmable utility modules then you might be able to customise something, but that tends to be at the 'specialised skills' end of the modular user spectrum. Of course, someone is now bound to let me know about a new bit of 'under the counter' custom firmware for the OxyProceyBlue75 module that makes this sort of thing a complete doddle...


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







Tuesday, 25 February 2020

256 oscillators (I mis-counted) plus Detune control...in a Max For Live plug-in.

My excuse is that I was distracted. On Twitter I under-stated the number of oscillators in my INSTframeOSCmr Max For Live plug-in for Ableton Live 10. There are actually 256: 64 per frame, but there are two parallel pairs of frames, and if you select the 'Stereo' button, then there are two separate oscillator banks per channel, so what you hear is 256 oscillators in total.


But whilst I was looking at the design, I saw a better way of doing the stereo routing, and so I added that. I also figured out a way to solve one of the biggest problems that I had with the user interface - drawing lines in the Frequency grid. The result is INSTframeOSCmr02, as usual a free upgrade from maxforlive.com.

I also realised that the frequency grids aren't easy to understand, so here's a guide to using them, plus details of the new 'Detune' control.

First we need to see how the frequency grid and the spectrum plots align...

Spectrum plots and frequency grids


1. Single low frequency

Here's a spectrum of the basic frequency grid setting - a horizontal line. This gives a single frequency at the output. (Note that the 'Detune' rotary control is set to zero.)



One way to think of how this is working is to just take the frequency grid and rotate it clock-wise - that horizontal row of orange blocks turns into a vertical line, which is the single frequency shown in the spectrum (Okay, so spectrum analysis always turns frequencies into these weird spikes that are narrow at the top and wider at the bottom, but that is just the way that the maths works). Now that the frequency grid is rotated, low frequencies are on the left, and high frequencies are on the right - just as in the spectrum:



2. Single high frequency

If we re-draw the orange blocks at the top of the frequency grid, then we get a single frequency 'spike' at a high frequency in the spectrum:


And if we rotate the frequency grid, then you can probably see how the two line up...:



3. Two frequencies: Low and High

If we draw low and high frequency horizontal lines in the frequency grid, then we get two lines in the spectrum. (Notice that the oscillator index doesn't matter to the spectrum - you can try it yourself by drawing the two horizontal lines with different positions, and the spectrum will stay the same):


And the rotated frequency grid now looks like this (the blue cursor just happens to be where the two orange lines change frequency - this isn't significant!):



4. Three frequencies

So what about three frequencies? Well, we just draw three horizontal lines in the frequency grid:


And the rotated version looks like:


At which point you may notice that the spacing of the three frequencies in the frequency grid and the spectrum are different! This is because the frequency grid horizontal axis is 'linear', where the frequency goes up in equal steps, whilst the spectrum's horizontal axis is 'logarithmic' where the frequency goes up in steps that keep doubling. This is exactly the same way that notes double in frequency when you transpose them by an octave. So a C2 at 110 Hz, becomes C3 at 220 Hz, and a C4 is 440 Hz, whilst a C5 is 880 Hz. So the spectrum's 'logarithmic' horizontal axis is a good way of showing musical intervals: a C2, C3, C4 and C5 would all have the same horizontal spacing. Unfortunately, the Max 'multi slider' object that I'm using for the frequency grid does not have a logarithmic axis option.


5. Detune

You can see how the logarithmic horizontal axis works by adding 'Detune' to the 'Two frequency' example. Notice how the low frequency (the right-hand orange horizontal set of blocks in the frequency grid) gives a wide band of frequencies in the spectrum, but the high frequency (the left-hand orange horizontal set of blocks in the frequency grid) gives a much narrower band of frequencies. The detune values that are applied are the same in both cases - the frequencies that are added or subtracted are the same, but the way that the spectrum shows the resulting band of frequencies is different. Actually, to sound correct musically, then the detune values should be larger for higher frequencies, but that's not how I programmed it...


Okay, that completes the tutorial on the alignment between the frequency grids and the spectrum plots.

How to use the frequency grid...

1. Single frequency

Now that you have a better idea of what is happening on the frequency grid and the spectrum, let's look at that single frequency example again. When you look at the frequency grid and spectrum now, then you should see that the horizontal orange set of blocks in the frequency grid corresponds to the single 'spike' in the spectrum plot:



2. Rising ramp

And next, the plot that seems to confuse people. A rising ramp on the frequency grid... Remember that the horizontal axis is the oscillator index, so what the rising orange line means is that the frequency goes up as the oscillator index goes up - each oscillator will produce a different frequency. So this will produce a block of frequencies:




3. Chords

Next, some horizontal lines drawn by dragging the mouse horizontal across the grid. This gives four different frequencies (a chord!), because all of the oscillators along the horizontal axis are set to the same vertical frequency:




4. Wobbly lines give bands of frequencies

And now to that problem I mentioned. If you aren't good at drawing horizontal lines with the mouse, then you actually don't get single frequencies, but you get broader 'bands' of frequencies. if you look, you can see that the lines are not horizontal, they are 'wobbly' in the vertical direction, and this produces the bands of frequencies in the output:



5. Detune...

Now for Detune. Here's that first 'single frequency' setup, but with the 'Detune' rotary control turned up past half-way, it is as if that horizontal line was very wobbly up and down vertically. So now you don't need to try to wobble the lines, you just turn up the 'Detune' rotary control. What you get is bands of frequencies instead of single ones:



6. Detuned chords

Finally, a nice neat horizontal 'chord' grid, but with quite a lot of 'Detune' - so you get several bands of frequencies all mushed together (The screenshot doesn't capture the dynamism of the spectrum that you get here - it is going up and down all over the place!):


The Detune rotary control saves you the hassle of trying to draw wobbly horizontal lines - and most importantly: you can quickly adjust the control, instead of having to redraw wobbly horizontal lines with more or less wobble.

Detune?

The 'Detune' rotary control applies little frequency offsets to the oscillators. It does this with different values for each grid - each grid has a captured list of random values that it uses to apply the detuning to the oscillators. Which brings me to this post's 'Max' content, and it concerns the 'vexpr' object.

Vexpr works on lists. Give it a list like (1,2,3,4) and it will process the 1, then the 2, then the 3, and finally the 4. So one object in Max allows you to change four values at once. So in INSTframeOSCmr I use it to process the frequency grid, which is a list. I'm going to use a single diagram with numbered 'points of interest':



1. This is a 'bang' event that indicates that a frame has been activated, and that the oscillators should load new values for their frequency and amplitude.

2. The frequency grid outputs a list of 64 frequency values.

3. This message box contains a list of 64 different randomly-generated 'Detune' values.

4. The 'Detune' rotary control controls how much detune is going to be applied to the frequency grid output values (which is a list of 64 frequency values).

5. This is the first of two 'Vexpr' objects. This one has 'Scalar Mode 1' set, and so it multiplies every value in the list of detune values by the single value from the Detune control. In this case, the Detune is set to zero, so the output of this Vexer object will be a list of 64 zeroes.

6. This is the other 'Vexpr' object. This one does not have Scalar Mode 1 set, and so it works on two lists. It adds the list of frequency values from the frequency grid (2) with the list of Detune values, so if you imagine that the 'Detune' rotary control was set to something other than zero, then the list of detune values would be 64 different randomly-generated values, and they would be added, one by one, to the 64 frequency values from the frequency grid output. If lists were not used here, then there would need to be a lot of * and + objects in this Max For Live Patch! (As a quick aside, what would happen if this '+' object was a '*' (multiply) object instead? Would this affect how the detune is applied to the frequency values?)

7. I have cheated here by pasting in a message box containing the 64 frequency values that would have been output if the Detune control was higher than zero!

8. The 'detuned' list of frequency values eventually gets to the 'ioscbank~' object, which contains the 64 oscillators for this frame.

Note that the two different versions of Vexpr do very different things.

  • The Scale Mode 1 version takes a list and processes every item in the list with a single value (from the Detune rotary control in this example).
  • The other version (without the Scale Mode 1) takes two lists, and processes every item in one list with the same item in the other list. 

Getting INSTframeOSCmr

You can get the updated version of  INSTframeOSCmr here:

     https://maxforlive.com/library/device/6012/instframeoscmr

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 INSTframeOSCmr would require two LFOs, and 256 VCOs, a lot of stored parameters (blocks of 16?) to do the frame loads, a mixer and a Ring Modulator, giving a total of well over 260 ME, which is the biggest count so far, I think. You might want to use some specialist additive oscillators instead of brute-force VCOs!

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