Thursday 9 May 2019

Ping Pong Delay re-imagined for Live 10.1 in M4L...

I'm sure that we are about to be swamped by lots of 'homage', 'retro' and 'for compatibility' versions of the classic Ableton Live 'Ping Pong Delay' plug-in effect so that anyone who likes the simple 'about to be deprecated' effect can continue to use it. But rather than just recreate it, why not take the opportunity to re-imagine it, and try to produce something that reflects what it would be like it it was a brand new device made today? Well, I took the re-imagination route, and as usual, the story isn't completely straight-forward...

Let's start with the classic 'Ping Pong Delay' audio effect:


With the input filtering at the top, then the quick 16th note delay time selector buttons, then the Sync, Freeze and 'Adjust' boxes, and finally the Feedback and Dry/Wet rotary controls, it manages to squash a lot into a small space. I've clicked on the '3' and '5' buttons and used the '% tweak' Adjust box more times than I care to think about, and that tiny little 'F' Freeze button is often overlooked as a creative performance tool... (and not to mention the often overlooked 'Control (M)/Right (W)-Click' in the name bar to reveal the 'hidden' context menu with 'Repitch, Fade and Jump' modes - and probably a standard Ableton question to people who think they know Live...)

Ableton Live 10.1 includes the new version that combines Simple Delay and Ping Pong Delay not one device:


(screenshot from live-101-user-wavetables-new-devices-and-workflow-upgrades  https://www.ableton.com/en/blog/live-101-user-wavetables-new-devices-and-workflow-upgrades/ )

There's a lot of interesting additions in the new version: separate delay time buttons for each stereo channel, plus %tweaks, the filter is now 'bypass'able, and the 'F' Freeze button is now made lots more obvious by being labelled as 'Infinite feedback', which I'm sure is going to attract lots more explorative clicks!  All-in-all, it looks cool, and I'm looking forward to it.

Before re-imagining

Back to the classic Ping Pong Delay... What would a modern 'revisited' version include? How about note value based time buttons? How about freezing based on separate stereo channels instead of just the mixed output? How about a 'bypass' for the filters?

First off, I need to look at the structure of just about all of the stereo delay devices that I have programmed in MaxForLive. My preference has always been for stereo in and stereo out, probably because I was raised in an era when not everything that was 'stereo' was actually stereo (and with two flavours of quadraphonic sound fighting it out when I first started reading electronics magazines), and so there's a bit of a common theme (and there's a partial collection from way back in history here, if you are interested...):


This is definitely a 'stereo in, stereo out' delay/echo device, and I have shown only what I tend to call 'Cross feedback', which is feedback that goes to the other channel. So, if you imagine a drum sound on just the left channel input, then assuming that the Dry/Wet mix control is set mid-way and there is some feedback, the output will be the drum sound from the left channel, then the delayed drum sound from the left channel, then the delayed drum sound (double-delayed) from the right channel, then the triple-delayed drum sound from the left channel, followed by the quadruple-delayed drum sound from the right channel, and so on. Each new delayed drum sound bounces back and forth from left to right, and if there's another bit of audio in the right channel, then that will be output (delayed) from the right channel first, then the left, and so on.

I have to say that I'm tempted to go back into some of my older devices and tweak them so that the 'first delay output channel' is selectable. Now that I have been working on ping-pong delays, I'm wondering if being able to decide if a drum that starts on the left should have the first echo from the right, not the left as shown here... It might be interesting to revise those old devices...

Anyway, if you have been following my recent devices you might be thinking that the 'basic' delay shown above is simplified from what I'm currently doing, and you would be right. Here's a more representative delay device - reminiscent of parts of the recent 'hex' series:


In this example, there are two feedback loops: one for the same channel, and one ('cross') for the other channel, which lets you decide if you want the repeat echoes to be in the same stereo channel or to bounce back and forth between the two channels with each successive repeat. The output panning is also controlled by an LFO driving a panner, so the actual stereo field can be animated as well.

What I hadn't done in any depth when I first started was examine the original Ableton Live 'Ping Pong Delay' device. If you are going to 're-imagine' something, then knowing too much about it is going to affect what you do and restrict your creativity, so I just took my usual delay and gave it a UI skin that was strongly influenced by the original device. It turns out that the Ableton device is rather different...


Let's go back to that drum sound on the left channel input - there's a screenshot of the text setup above - I just set the drum sound on the left or right channels using the Utility device, and then used the Dry/Wet mix rotary controls to look at the input and output of the two devices. You need to make sure that you only enable one device at a time, otherwise all those echoes can be very confusing!


If you send the 'left channel' drum sound to the original Ableton Live 'Ping Pong Delay' device, then you get the dry signal first in the left channel, then the delayed version in the left channel,


then a double-delayed version in the right channel, and so on. So far, it behaves just like mine.


But if you then try a drum sound in the right channel input, then you get the delayed version from the left channel first, then the double-elated version from the right channel, and now it is behaving VERY differently from my version.


So, based on this, it seems like the original Ableton 'Ping Pong Delay' device internal structure looks like this:


So the left and right channels are mixed together into a 'mono' single,and this is then delayed and output to the left channel, then that is delayed and output to the right channel, and the feedback goes round both delays. This is why a drum sound on the right channel appears at the left output for the first echo, then the right channel for the second echo, and so on, back and forth between the two channels. Note that with this structure, the first and second echoes are at the same volume in the left and right channels, whereas in my echo devices, the volume of the second echo depends on the 'Feedback' rotary control.

So now I knew the difference between the Ableton device and mine!

Frozen echoes

Let's look at freezing the echo, where the output of the delay is connected directly and solely to the input. Here's what it looks like for the Ableton device:


As you can see, the output will just 'ping-pong' back and forth between the left and right channels with each subsequent echo.

For my device, then there are several ways to do the freezing, and here's one of them:


This behaves in exactly the same way as the Ableton one: the output bounces back and forth from left to right with each successive echo. I have not included the Dry/Wet mix in this diagram because it was originally drawn for the AUDpiPOdePLUS device, where the Dry/Wet mix is inactive when the echoes are frozen.

Anyway, the end result of all of this investigation and looking at how echo devices work is two MaxForLive devices:

1. AUDpiPOde - the first Ping-Pong Delay device that appeared on MaxForLive.com, and which uses my preferred stereo delay to give stereo echoes that bounce back and forth between the left and right channels. This is not a faithful emulation of the original Ableton 'Ping Pong Delay' device - and so the word: 're-imagining' is very apt - this is how I would program a Ping Pong Delay device now.

2. AUDpiPOde_A - which is the second Ping-Pong Delay device that I will post on MaxForLive, and this uses a single tapped delay to give a different ping-pong effect - where the signal that bounces is a mix of both input channels. This is a closer emulation of the original Ableton Ping Pong Delay device in pre 10.1 Ableton Live.

This gives you both double value (which is her to measure for devices that are free!) and a choice: you can have 're-imagined' or 'close'. I hope that you find both variants useful, and don't forget that all of the re-imagining also produced another device: AUDpiPOdePLUS, which (despite the name) is actually a performance-oriented delay device which extends the 'frozen echo' feature into something rather different.

Re-imagining

Anyway, on with the re-imagined delay device:

Here is AUDpiPOde (from the first two characters of ping, pong and delay). I worked on the note value time delay buttons first. I replaced the 1,2,3,4,5... with note values, using the internal M4L time notation: 16d, 16, 16t for dotted 16th, 16th and 16th triplet, etc. I also added more buttons, from 128th note to 1 note (15.62 ms to 2000 ms at 120 bpm).

I also used the '% tweak' Adjust box to automatically switch between 'Sync' and 'Not in Sync'. So when you click a note value button then the delays are in sync, but if you use the '% tweak' Adjust box (with the triangle) then the time delays are not in sync with Live's timing.

Trying to keep the buttons as large as possible, whilst still keeping a small but neat rectangle of buttons meant that the obvious 'three values' of dotted, note and triplet organisation was awkward, and so I opted for a more free-form set where 2, 4, 8 and 16 are on a diagonal, and 32 and 64 have their own tiny diagonal. It isn't perfect, but it keeps the button grid small and neat.






For the freezing, then I added two extra buttons. The 'F' button is as before, and loops the output of the delay back to the input, thus giving the infinite delay that the new 10.1 makes much more explicit. Note that when the delay is frozen, then the feedback rotary control has no effect.










The new 'P' button loops around the stereo channel reversed audio signal, so if the input is just in the left hand channel, then the first delayed repeat will be in the right hand channel, then the second delayed repeat will be in the left hand channel again. being able to ping-pong in a frozen loop is very cool!









The final freeze button is labelled 'P+F' and combines the two previous buttons into one. For this delay, where both channels have the same delay time, then it makes no difference, but if this was available in the 10.1 delay, where each channel can have different delay times, then some very interesting results would be available. Now although you can do exactly the same effect in my AUDhexECHO effect with appropriate settings of the controls, this seemed like something for a 'Plus' version of this effect, and so expect exactly that very soon!





The filters were a challenge. Max For Live provides a lot of filters, and some very sophisticated tools to help you design specific special-purpose filters, but there are two problems. Firstly, the Ping Pong Delay filter is a band-pass filter - the two controls that are provided are the centre frequency and the bandwidth. But for a wide bandwidth, then a combination of a high-pass and a low-pass is easier to make, but then the controls are more complicated - you need to send the centre frequency to both filters, and then add or subtract half of the bandwidth setting. To complicate things even more, the frequency axis is logarithmic, where the frequency goes up by 10 times for each 'decade' block as you move across from left to right (you can see this in the spacing of the lines in each 'decade' block).


In the filter response plot for a band-pass filter shown above, the major lines at the end of each 'decade' block are 100 Hz, 1 kHz, an 10kHz - so the final vertical line on the right hand side is 20kHz, and zero Hertz is way off the the left somewhere. So the band-pass filter shown has a pass-band between just under 100 Hz to just over 3kHz.

The display in Ping Pong Delay is much smaller, of course:


But notice that each of the decade blocks have the same pattern as the first plot, where the vertical lines get closer and closer together as the frequency goes up, and (by implication) the far right edge is 20 kHz. The yellow dot is kind of centred on 1 kHz, and the centre frequency is 949 Hz, with a Q or resonance of 6.17 (which controls the bandwidth of the filter). Now, having the centre of the display at 1 kHz may not be what  you expected, but look at the right hand side - the narrow vertical strip from 10 kHz to 20 kHz is the same frequency range as the whole of the left hand side of the graph, from the 10 kHz vertical line leftwards.

So if we are going to use a simple x/y controller object from Max to control a band-pass filter, with centre frequency on the horizontal axis, then a pictslider output goes from 0 to 127 horizontally. If 0 represents 0 Hz, and 127 represents 20 kHz, then 1 kHz is going to be a value of about 63 or so, and 10 kHz is going to be at about 110 or so. To convert a linear controller value into a logarithmic value requires that we use an exponentiation function: using the 'pow' object in Max. Using the 'pow' object can be quite tricky, because small changes of input values can have large effects on the outputs. My usual technique is to transform the 'pow' into a 'domain' where figuring out what is happening is easier, and then to transform back once the settings are known. Here are two examples which illustrate this:


Box 1 shows a simple way to use 'pow', whilst Box 2 shows the 'transform' method. At first sight, Box 2 seems to add complexity, so we need to look at the inputs and outputs of the two boxes.

Box 1 first:


When n = 0.5, the output only goes to 11, and so the integer 'multislider' object that I'm using to do the plots quantises the outputs, but you can see that the curve goes from 0,0 to 127,11 and is gradually tailing off (just imagine a smooth curve!). When n=1, then the output is a straight diagonal line from 0,0 to 127,127.


When n=1.5 then the curve looks like a classic exponential, and goes up to 127,1431. When n=2 ('y=x squared' is how you would say it) then the max is 127,16129 (127 squared, of course).


  For n=2.5, then the rightist point is 127,181754, and for n cubed (n=3), then it is 127, 2048383.

In order to use these curves, then you would need to scale the maximum output, but this changes for each value of n:

n       maximum output
0.5             11
1.0           127
1.5         1431
2.0       16129
2.5     181754
3.0   2048383

You can auto scale by dividing by 127 to the power n, but this means that we are doing two 'pow' operations every time, which seems inefficient.

Alternatively, the 'transform' method adds scaling (divide by 127) around the 'pow' function so that it always has inputs between 0,0 and 1,1, and then multiply it by 127 to get the same output as the original UI object. The graphs now look like this:


The 'pow' object is now getting floating point inputs, and so we can see what the actual curve looks like without the accidental quantisation! Notice that each curve goes from 0,0 to 127,127.


And again for n=1.5 and n=2, the output is from 0,0 to 127,127.


And finally, exactly the same output range again!

Putting a transformed 'pow' object inside my filter testing gave this max patch:


This time, Box 1 contains a transformed pow function (I was testing out n=3 in this screenshot), and Box 2 contains the max objects to try and turn the horizontal movement in the pictslider into the correct centre frequency for the band-pass filter, and for vertical movement in the pictslider to control the Q, resonance or bandwidth of the filter - which I implemented as a plain butterworth type. Unfortunately, I couldn't get the mouse interface with the pictslider to feel anything like the Ping Pong Delay original, and having a 'difficult to use' filter section in a re-imagining f a classic Ableton Live device seemed like a bad move. So I reverted to two simple filters instead:


So, in this version, there are two pictsliders: one for the high-pass filter, and one for the low-pass filter. in both of them, horizontal movement controls the centre frequency, whilst vertical movement controls the Q, resonance or bandwidth of the band-pass filter. This simplicity felt much better than the previous complexity, and this is what is implemented in the current device.

Note that the high-pass filters are made from low-pass filters by subtracting the original input from the low-pass filter output. This turns a 'lores' object into a kind of 'hires' object. (although there isn't a 'hires' object in Max, of course!)

The filters can be bypassed by using the Filter/Thru button, and this is important because one of the disadvantages of using the 'lores' filter object is that it has a maximum frequency of the sampling rate divided by 4, and so for the usual 44.1 kHz sampling rate in Ableton Live, this means that the highest cut-off frequency for the two filters is 11 kHz.  I'm also cautious about putting filters inside feedback loops, and so the filtering is only on the input, so you don't get the classic 'tape echo' low-pass filtering that gets more and more noticeable with each repeat.

All of this is different to the original Ping Pong Delay device, and means that I should probably persist in trying to get the UI to feel right for the next version.



Commentary

I need to make it clear that I'm really looking forward to using the new '10.1' Delay effect in Ableton Live. It looks like it combines a lot of functionality in a single device, although I do wonder if the 'minimal UI and size' design approach that was used in the older devices has kind of been abandoned and we now have a more 'designed' expansive look. But in these days of larger and higher resolution screens where effects plug-ins (and most VSTs) are one of the last bastions of skeuomorphic design in UI design (as per the iPhone's iOS before it went 'flat'), then maybe some loosening of the stark minimalism of the older Ableton Live is timely. Personally, removing that minimalism and replacing it with pseudo-realism would negate one of the defining differences between Ableton Live/M4L and other DAWs/Reaktor. (And apart from a few notable inverted examples, and one stand-out (the Studiologic Sledge Black Edition), then I'm still waiting for brightly coloured keyboards to become fashionable instead of custom 'stage' specials...)


Another investigation


blortblort reported in the blog comments that the Feedback control was not working correctly. It turned out that I had made a mistake and had cross-connected the two delays, and got the 'freeze's witching wiring wrong. All of this makes AUpiPOde 0v02 a bit weird, and not the re-imagining that I intended. So I went back through the design, fixing things, re-assessing things, and what came out at the other end was AUDpiPOde 0v03, which should fix the reported problems (I also realised that I should do something less re-imagining and more 'homage' to the original, so that's what the AUDpiPOde-A 0v04 device is all about!



AUDpiPOde 0v03 removes the filters, adds the 'Left First' or 'Right First' LD selection button (as in the -A variant), and provides a 'panic' clear button - the red circle. If the echo starts runaway feedback, then the red button clears the contents of the delay. My recommendation is that you should delete version 0v02, and should only use version 0v03.

And onwards...

It seems that 0v03 had problems as well, although I did lots of testing. So I have visited it again, checked the signal routing, and added the 'f' freeze button from the 'A' version. This is version 0v04.

Getting  AUDpiPOde 0v04

You can download AUDpiPOde 0v0for free from MaxForLive.com.

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

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

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

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

Modular Equivalents

In terms of basic modular equivalents, then AUDpiPOde would require two band-pass filters, two delays, some utility switches, and two mixers, giving a total of about 5 ME.




7 comments:

  1. elegant device!
    Thanks for the inclusion of all the sync values and the tidy way to nudge them ;]
    ... but unless I am doing something wrong, I get no "ping pong" ...just mono delay. there is no wet signal bouncing from L to R ...
    also, not sure how the dry/wet is supposed to work since once one turns up the feedback knob from its most CCW position, wet signal comes thru even if the dry/wet knob is in full CCW position
    am I missing something?

    ReplyDelete
  2. Interesting. I'm investigating...

    ReplyDelete
  3. blortblort: Thanks for the catch. My initial analysis of the Ableton Live Ping Pong Delay was wrong, so I will revise the text, and the device, although I quite like what it does, and I did set out to 're-imagine' it...

    I was intrigued by your report of the Dry/Wet control, but I have now discovered that I misinterpreted how an object worked, and again I will revise the device to fix it...

    Thanks for reporting the problems. Much appreciated!

    ReplyDelete
  4. blortblort: I have updated the blog post, and will publish a revised (version 'A') device to MaxForLive.com soon.
    I have now found the problem with the feedback control, and I am fixing it!

    ReplyDelete
  5. Thanks for the work you've done, Synthesizerwriter! ...all feedback issues are fixed, but version 03 does not output "ping-ponged" signal...and version 04 DOES output "ping-ponged" signal...but only ONE feedback repetition no matter where the feedback knob is set...

    ReplyDelete
  6. OK. Version 0.04 is now on MaxForLive. It works fine for me in 10.0.6 (I have not updated yet to 10.1...)

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete