Scorpio - bespoke unit - available for download now!

@anon83620728 and I have been collaborating on a middle layer project. I hope it’s not bad form to tease/demo it before making it available. But I’m sort of excited about it, and there are still a few things we want to do before posting the unit. So here’s a glimpse.


Very cool. Looking forward to seeing more about it.

1 Like

Nice! I love vocoded sounds. I presume you could use live audio sources for the carrier and modulator in your custom unit rather than samples?

It looks like you have a shapeshifter in your rack. The vocoder in that module is lovely.

Looking forward to trying out your custom unit.

1 Like

Yes, you’ll be able to use anything you want as a modulator or carrier including sources from the physical inputs, chains you build in the ER-301, sampler players, etc. I think that will be part of what makes Scorpio special.

And yes, I’ve been A/B testing with the Shapeshifter’s vocoder. It is indeed probably the highest resolution vocoder I’ve ever used. :slight_smile: Scorpio may seem a little “old-skool” if using Shapey as the yardstick.


Looking great, Joe!

On vocoders:
What would it take to effectively separate voiced and unvoiced parts of a modulator*? Maybe just an envelope follower on a high-pass filtered copy of the signal; driving a cross-fader? I’d like to try mixing some dry signal or noise in for plosives and sibilants.

1 Like

We’ve been going back and forth on whether to include that as a built-in option, and I think we’ve settled on including it. Yes, essentially a HPF’d version of the modulator mixed into the output. Not sure we’d considered cross-fading though. That is probably worth some investigation.


:raised_hands: :raised_hands: :raised_hands:


I wondered how long it would take for someone to get the Scorpio reference - good work @freqout :wink:

We’re getting close, here’s another teaser:

We’re almost done, @Joe has done loads of work on this, it’s awesome!!

We will be sending to @odevices with a polite request for a review and hopefully a seal of approval, and to perhaps tweak a little more, before we unleash this monster!!

p.s.the sample I used for this short example is this one:

And all I added was a little bit of reverb outside the ER-301.


Ok, here comes an incredibly noobish question, but I gotta ask it once to understand the terminology:

Is a costum unit basically a preset in the sense that it is a combination of available units? Or is it a newly programmed unit by users (instead of OD)?

Sorry :slight_smile:

I think we have pretty much decided that

A custom-unit is a collection of units built inside the Custom Unit container.

A new unit programmed by users, as Scorpio is (coming very soon now!) is a bespoke-unit.

I should change the tag on this thread actually!

1 Like

Great. Thanks a lot for clearing that up.

1 Like

Another little teaser… :smiley:



Joe approached me a few weeks ago with the idea of creating a vocoder for the ER-301, I must admit while I was super happy to be working with @Joe on another project (which is always good!), I was thinking I am way behind on learning the middle layer and in all honesty not entirely sure how vocoders actually work - although I had a fairly reasonable idea of the principles - I was also kinda sceptical we could make it work. But hey, don’t know unless you try right?

As we have worked this way before Joe took the driving seat and wrote the code and I criticised, debugged and generally made myself as much of a pain in the ass as possible (all in good nature of course :slight_smile: ) and 2 weeks and over 400 messages later - yes 400! After another period of refinement and testing we are very proud to present version 1.0 of Scorpio a 10 band vocoder for the ER-301!

If you just want to download and get stuck in here is the unit, simply place the folder in your ER-301/libs directory and it will appear in the usual unit selection screen.

Just a quick heads up so there are no surprises, CPU usage is fairly heavy at around 60% on the 48KHz firmware and it won’t work on the 96KHz firmware.

The super simple startup instruction is to feed the modulator (a vocal sample perhaps) into the left of the unit, and put a rich waveform into the carrier subchain. It should just work. (3.9 KB)

If you want to know a bit more about the unit, how it was developed and how to use it, read on:

There are no less than 131 ‘units’, or to be more precise ‘objects’, and 238 connections in this patch.

Making all these connections was a pretty onerous task, initially @Joe was manually typing out each one, which with 4 bands wasn’t too bad, but looking at the code I could see it was screaming out for loops, it was just solid blocks of code with really small differences in each line. There are two good reasons to do this, first of all to make it a bit more readable and secondly to make it easier to experiment with different numbers of bands. Working out how to dynamically create objects was an interesting challenge, but as Lua is so well balanced in terms of data structures it turned out to be really straightforward, here’s an example of how to create multiple instances of the same set of units:

    -- Create the objects that require one per band.  This is done in a nested loop for convenience and shorter code
    local localVars = {}

    -- define the different objects to be mass created
    local objectList = {
      lpI = { "StereoLadderFilter" },
      hpI = { "StereoLadderHPF" },
      lpO = { "StereoLadderFilter" },
      hpO = { "StereoLadderHPF" },
      ef  = { "EnvelopeFollower" },
      bpf0 = { "GainBias" },
      bpf0Range = { "MinMax" },
      fShiftSumLP = { "Sum" },
      fShiftSumHP  =  { "Sum" },
      ogain = { "Multiply" },
      omix = { "Sum" },

     -- create numBands # instances of each object in objectList
     -- loop throuhgh the Key - Value pairs in the objectList array
    for k, v in pairs(objectList) do
      -- set i to be equal to 1 and loop intil i reaches the number of bands - numBands - in this case 10
      for i = 1, numBands do
        -- create the object name by concatenating the key value and i e.g. lpI .. 1, lpI .. 2
        local dynamicVar = k .. i
        -- create the dsp unit name, because objectList is a multidimentional array access the first element
        local dynamicDSPUnit = v[1]
        -- create a table to store the new objects and create the object using the values created
        localVars[dynamicVar] = self:createObject(dynamicDSPUnit,dynamicVar)

As you can see each band is made up of 11 objects and the loop iterates through the objectList array and creates them all. A similar approach was taken to make the connections and create the UI too.

We also realised that we could provide both a condensed view with some carefully chosen default frequencies for the bands, and an extended view to enable editing of all the individual band frequencies and a couple of other appropriate parameters like Q, and the high passed modulator filter mix-in cutoff frequency. You can switch into extended view in the unit menu. The default settings are good enough, but you will probably find that fine tuning your vocoder settings will give you even better results.

We were really close and pretty satisfied with the results, but we knew that @odevices would be able to make some suggestions, so we asked for his feed back - as always the insights and observations were spot on and when we implemented the last few tweaks (mostly adding Q control for the filters) the difference was night and day, it was pretty good before, but now it really does sound good!

Here is a before/after recording, same setup, same samples, the first half is before optimisation, the second half after optimisation:


Joe has written up a complete list of all the controls and their intended functionality on the Wiki:

As always we are very keen to hear any feedback you may have, especially if you can think of any improvements that could be made, and will be very excited to hear what you do with this monster unit!

I don’t think either of us could have done this on our own, and certainly not as good as it is now. Thank you @Joe a pleasure and an honour as always!!

Enjoy!! :smiley:


Thanks @anon83620728 and @joe Have a day off tomorrow, with some time to take it for a spin.

Appreciate your generosities!


Thank you @sixnon :slight_smile:

We do these things primarily out of curiosity and the pleasure of overcoming the challenge, it’s really good fun and we’re only too happy to share the fruits of our labour. The hope is that it is inspiring for others to try and build their own bespoke-units.

There’s a bit of a leap to make the transition from the front UI to the Lua layer, but it’s worth the effort. As @Joe mentioned elsewhere there are certain things you can do in Lua that you can’t do in the UI.

I think we would like to encourage folk to really take a good look at the source code and try and figure out how it works, of course we’re more than happy to answer questions.

Two outcomes we would love to see created by other folk:

Some music made using this unit

Some more bespoke units

Please do share your creations, be curious, ask questions etc…

I think there is a natural progression from using the UI, to programming in Lua to eventually programming in C++ and creating c-code-units - one day! I think it’s a very good thing that the development is progressing at the pace it is, as it gives everyone chance to get to grips with each release and the possibilities therein. I think if we got everything at once it would be quite chaotic :stuck_out_tongue_closed_eyes:

1 Like

Exciting! Can’t wait to give it a shot. Thanks for this, guys!


Looks great, and thanks for giving some insight into streamlining the creation process!


lovely! hoping to give it a shot later tonight!
it’s definitely time to learn LUA anyway

1 Like

Not to split hairs but doesn’t the current middle layer just expose building blocks versus built units? What you are programming (scripting) is really just how those modules all work together. There will be some dsp there, but it is not the same as rolling a completely original module, right? You are bound to using the building blocks already there are you not? If for example an object is not there and you are unable to devise a workaround then you can’t do it. (nevermind that getting a square block to fit in a round hole is usually very inefficient.)

I apologize if this is a distinction no one here cares about. Just want to make sure I’m not missing anything.