Ableton Live MIDI Remote Script / Control Surface

I am testing out the latest beta firmware 3.0.12
I also pulled the latest commits from git.
It seems more responsive but still crashes:

I am selecting some tracks one by one. It shows the SSL plugin.
Then I select the master track and the E.one crashed.
I do have dumps enabled as I want to make templates.
The mixer was only visible at start.

Ableton logs

2023-01-25T12:18:38.827601: info: RemoteScriptMessage: E1 (debug): - Uploading device PluginDevice
2023-01-25T12:18:38.827612: info: RemoteScriptMessage: E1 (debug): -- Getting preset for PluginDevice.
2023-01-25T12:18:38.827620: info: RemoteScriptMessage: E1 (debug): -- Constructing preset on the fly...
2023-01-25T12:18:38.827648: info: RemoteScriptMessage: E1 (debug): -- Dumper for device PluginDevice loaded.
2023-01-25T12:18:38.827934: info: RemoteScriptMessage: E1 (debug): -- Filter and order parameters
2023-01-25T12:18:38.828001: info: RemoteScriptMessage: E1 (debug): -- Construct CC map
2023-01-25T12:18:38.828497: info: RemoteScriptMessage: E1 (debug): -- Construct JSON
2023-01-25T12:18:38.830317: info: RemoteScriptMessage: E1 (debug): -- dumping device: PluginDevice in C:\Users\Tim Bos/ElectraOne/dumps/PluginDevice.epr.
2023-01-25T12:18:38.831129: info: RemoteScriptMessage: E1 (debug): ** Upload thread starting...
2023-01-25T12:18:40.022203: info: RemoteScriptMessage: E1 (debug): ** Upload thread requesting MIDI map to be rebuilt.
2023-01-25T12:18:40.022238: info: RemoteScriptMessage: E1 (debug): ** Upload thread done.
2023-01-25T12:18:40.065512: info: RemoteScriptMessage: E1 (debug): - Main build midi map called.
2023-01-25T12:18:40.065530: info: RemoteScriptMessage: E1 (debug): - EffCont building effect MIDI map.
2023-01-25T12:18:40.065801: info: RemoteScriptMessage: E1 (debug): - EffCont effect MIDI map built.
2023-01-25T12:18:40.065818: info: RemoteScriptMessage: E1 (debug): - EffCont refreshing state.
2023-01-25T12:18:40.450383: info: RemoteScriptMessage: E1 (debug): - EffCont state refreshed.
2023-01-25T12:18:40.450416: info: RemoteScriptMessage: E1 (debug): - MixCont building mixer MIDI map.
2023-01-25T12:18:40.450432: info: RemoteScriptMessage: E1 (debug): -- Building transport MIDI map.
2023-01-25T12:18:40.450448: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track Master.
2023-01-25T12:18:40.450499: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track A-Reverb.
2023-01-25T12:18:40.450523: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track B-headpones.
2023-01-25T12:18:40.450543: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track 1-MIDI.
2023-01-25T12:18:40.450603: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track 2-Audio.
2023-01-25T12:18:40.450648: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track 3-Audio.
2023-01-25T12:18:40.450690: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track 4-Audio.
2023-01-25T12:18:40.450732: info: RemoteScriptMessage: E1 (debug): -- Building MIDI map of track 5-Audio.
2023-01-25T12:18:40.450773: info: RemoteScriptMessage: E1 (debug): - MixCont mixer MIDI map built.
2023-01-25T12:18:40.450781: info: RemoteScriptMessage: E1 (debug): - MixCont not refreshing state (mixer not visible).
2023-01-25T12:18:44.644099: info: RemoteScriptMessage: E1 (debug): - Assigning an empty device.

Device template

PluginDevice.epr (18.5 KB)

After reconnecting the usb cable the e.one came back to live/life :slight_smile:
Then I wasn’t able to replicate the crash.

The other issue is with vst3’s. sorry to bring it up.
But it seems on windows work differently.
Adding a vst3 to an Audio Rack and save it under the name “SSL” does not create a template name “SSL” but “ProxyAudioEffectDevice”.
So it is not possible to make presets for other devices as it creates the same issue like when its creates “PluginDevice.epr” for vst’s.

It it is much better to use the real device name on Windows.
Because in the current state we can have only 1 vst …
Like that we can have at least a default template for each vst.

Anyhow I will try to look deeper into this to find a sollutions.
There must be a way.
Below are 4 different prestets selected. On my Ableton Push I see the same name which is the actual plugins name not the preset names…

So you have the SSL device on every track, including the master, and then the E1 crashes when selecting the master track? Do you see any uploading happening? (P.S. setting DEBUG=5 will give more log messages and therefore more context).

Regarding the ‘names’ of plugins, racks, and Max devices: yes there must be a way because Ableton itself knows which names to use when browsing the plugins, racks and max devices. But so far I have not found the correct function in the Live API that I can call to reliably retrieve it. If you (or anybody else) finds it, please let me know and I’ll incorporate it in the script!

1 Like

Hi Jaap,

I have the ssl on each audio channel only not on the master.
I will put it on debug 5 for more info.
After reconnecting the e.one I was not able to replicate it.
But some other issue appeared. The mixer was visible and devices their templates shown when selecting channels but I couldn’t open any other device templates on the e.one.

I want to open a editor for a hardware synth and then use Ableton to route the midi messages.

Cheers

Tim

I’m not sure I understand what you mean. Do you mean that when using the remote script, you cannot select a different preset (unrelated to the remote script, ie not in slot (6,1) or (6,2)) by pressing the MENU button(bottom right) together with the SNAPSHOT button (middle right)?

Yes, and now I started Ableton and again the display shows garbage.

Have to recover my unit again… :frowning:

    def get_device_name(self, device):
        """Return the (fixed) name of the device (i.e. not the name of the preset)
           - device: the device; Live.Device.Device
           - result: device name; str
        """
        # TODO: adapt to also get an appropriate name for MaxForLive devices
        # and for plugins
        # (device.name equals the name of the selected preset;
        # device.class_display_name is just a pretyy-printed version of class_name)
        self.debug(5,f'Returning class_name { device.class_name } as device name. Aka name: { device.name } and class_display_name: { device.class_display_name }')
        self.debug(5,f'(has type { type(device)}.) ')
        #return device.class_name
        #Tim edit name
        return device.name
    def __init__(self, c_instance, device): 
        """Construct an Electra One JSON preset and a corresponding
           dictionary for the mapping to MIDI CC values, for the given device.
           Use get_preset() for the contructed object to obtain the result.
           Inclusion and order of parameters is controlled by the
           ORDER parameter
           - c_instance: controller instance parameter as passed by Live
           - device: device whose parameters must be dumped; Live.Device.Device
        """
        # initialise a StrinIO object to incrementally construct the preset
        # string in; this is more efficient than appending string constants
        io.StringIO.__init__(self)
        # ElectraOneBase instance used to have access to the log file for debugging.
        ElectraOneBase.__init__(self, c_instance)
        #device_name = self.get_device_name(device)
        # Tim Edit
        device_name = device.name
        self.debug(2,f'Dumper for device { device_name } loaded.')
        self.debug(4,'Dumper found the following parameters and their range:')
        for p in device.parameters:
            min_value_as_str = p.str_for_value(p.min)
            max_value_as_str = p.str_for_value(p.max)
            self.debug(4,f'{p.original_name}: {min_value_as_str} .. {max_value_as_str}.')
        parameters = self._filter_and_order_parameters(device_name, device.parameters)
        self._cc_map = self._construct_ccmap(parameters)
        # this modifes cc_map to set the control indices for parameters that
        # need to use Ableton generated value strings.
        self._preset_json = self._construct_json_preset(device_name, parameters, self._cc_map)
        self._lua_script = ''

I have changed the remote script to get the displayed Device.name and tested presets and Max4Live devices and it works as should.
I can even select different presets but the names of the dumps do not change.
So it looks that your issue is on Mac and not on Windows.

Here I selected a max4live device preset.
And in the previous screenshot you can see the dump is still named “Shephard Tones.epr” so not the preset name.

image

When I open a preset dump in the web editor it looks like this:

If I want to make changes it doesn’t work. I select a control and pick the red clour this happens.
When I look to the json it looks ok.

I am not able to edit the actual control.
Change its type, min max values etc.

Second thing is

The Q does not work. ( there are 2 of such controls )
The pot just jumps to min or max

The range is 3.0 - 0.5 and 1.5 is the default.

This is in the cc map

‘EQ High Mid Gain’: (-1,11,True,24)

bx_console SSL 4000 E.epr (17.1 KB)

Also the pots still jump. Much less but they do jump and these jumps are also visible in the plugin your controlling.

1 Like

I see this too. This used to work just fine. @Martin can you explain?

If you drag a max effect (like Shephard Tones) to a track, indeed its device_name is ‘Shephard Tones’. However, if I drag a specific preset (like ‘Guarded Optimism’) to a track, the device_name becomes the preset name, i.e. ‘Guarded Optimism’. This also happens when hot-swapping a preset. At least on the Mac.

Could this perhaps be because the .epr import function does something with the bounds specified in the .epr file? Their values changed when you added full rectangles for groups as an option and hence all control bounds needed to be shifted

1 Like

Yes this does not happen on Windows.
The device name does not change even if I choose the preset.
setting device name to device.name
So I would like to test making custom presets and see how it works.

Maybe you can find a hint howto access the device name by studying the push (v1)script?
Althought push truncates the name and a portable way that works for windows and mac is of course what we want.

I am now playing with Ableton and the templates switches properly and had no crashes.

2 Likes

I am going to review it now. I just imported the preset and got the same thing.

1 Like
    {
      "id": 28,
      "type": "fader",
      "visible": true,
      "variant": "thin",
      "name": "EQ HIGH MID Q",
      "color": "FFFFFF",
      "bounds": [
        515,
        366,
        158,
        16
      ],
      "pageId": 1,
      "controlSetId": 3,
      "inputs": [
        {
          "potId": 10,
          "valueId": "value"
        }
      ],
      "values": [
        {
          "message": {
            "type": "cc14",
            "lsbFirst": false,
            "parameterNumber": 26,
            "deviceId": 1,
            "min": 0,
            "max": 16383
          },
          "min": 300,
          "max": 50,
          "formatter": "formatFloat",
          "id": "value"
        }
      ]
    },

The filter Q (bandwith) does not work. ( there are 2 of such controls )
The pot just jumps to min or max.
Above code is for “EQ HIGH MID Q”

The range is Min 3.0, max 0.5 and 1.5 is the default.

This is in the cc map

‘EQ High Mid Gain’: (-1,11,True,24)

Can it be the “formatFloat” has issues with inversed values where the max is actually the lowest?

I looked into the preset file, in the webeditor and in the repo to find the lua for formatFloat but did not find it.

Any hints or suggestions how I can tackle this?

I have to say yesterday I recorded something in Ableton and played around and the experience with the e.one and Ableton is just great.
If you have a vst and you edit the visible controls you can move them around.
If you reopen the device you get a new preset which has the controls in the new order.
Also after my last recovery I did not have any crashes.

I also played around with the mixer and I like it.

So its starting to look good on Windows now. :slight_smile:

@jhh what does -1 in ‘EQ High Mid Gain’: (-1,11,True,24) mean ?
I saw a commit to fix the Q on eq8 where all -1 where changed.

On Device name, this documentation seems up to date as Ableton 11 is included.

If I read it correctly

class_display_name

Description

Get the original name of the device (e.g. Operator, Auto Filter).

This is the one we want to use.

I am now using:

name

Description

This is the string shown in the title bar of the device.

Will try it out if this works for all devices and report back.

On MacOS that doesn’t work either: class_display_name = “Max Audio Device” for example :wink:

For debugging i created in the dumper the code below and did some tests.
Maybe you can do the same and then we can think about the best approach that will work on both platforms:

It looks Ableton 11 on windows only honors preset names of internal devices.
I think on Mac this also includes vst’s / au’s.
But if device.class_display_name will give the actual name of a vst on the mac could’t it be solved with some boolean switches?

So different conditions for the different classes?
If its a PluginDevice we use x if its a Max device we use y if its a internal device we use…

        """Construct an Electra One JSON preset and a corresponding
           dictionary for the mapping to MIDI CC values, for the given device.
           Use get_preset() for the contructed object to obtain the result.
           Inclusion and order of parameters is controlled by the
           ORDER parameter
           - c_instance: controller instance parameter as passed by Live
           - device: device whose parameters must be dumped; Live.Device.Device
        """
        # initialise a StrinIO object to incrementally construct the preset
        # string in; this is more efficient than appending string constants
        io.StringIO.__init__(self)
        # ElectraOneBase instance used to have access to the log file for debugging.
        ElectraOneBase.__init__(self, c_instance)
        #device_name = self.get_device_name(device)
        # Tim Edit
        device_name = device.name
        
        self.debug(2,f'Dumper for device device.name { device_name } loaded.')
        
        device_name = device.class_name

        self.debug(2,f'Dumper for device device.class_name { device_name } loaded.')
        
        device_name = device.class_display_name
        
        self.debug(2,f'Dumper for device device.class_display_name { device_name } loaded.')
        

        self.debug(4,'Dumper found the following parameters and their range:')
        for p in device.parameters:
            min_value_as_str = p.str_for_value(p.min)
            max_value_as_str = p.str_for_value(p.max)
            self.debug(4,f'{p.original_name}: {min_value_as_str} .. {max_value_as_str}.')
        parameters = self._filter_and_order_parameters(device_name, device.parameters)
        self._cc_map = self._construct_ccmap(parameters)
        # this modifes cc_map to set the control indices for parameters that
        # need to use Ableton generated value strings.
        self._preset_json = self._construct_json_preset(device_name, parameters, self._cc_map)
        self._lua_script = ''
  1. We open a vst3 not a preset

2023-01-26T13:45:26.640539: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name bx_console SSL 4000 E loaded.
2023-01-26T13:45:26.640545: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name PluginDevice loaded.
2023-01-26T13:45:26.640550: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name bx_console SSL 4000 E loaded.

  1. we open a vst3 preset for the same device, Called 01 Male vocal

2023-01-26T13:50:37.462404: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name bx_console SSL 4000 E loaded.
2023-01-26T13:50:37.462411: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name PluginDevice loaded.
2023-01-26T13:50:37.462416: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name bx_console SSL 4000 E loaded.

  1. we open a max4live device not a preset called Poli

2023-01-26T13:54:49.791531: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name Poli loaded.
2023-01-26T13:54:49.791537: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name MxDeviceInstrument loaded.
2023-01-26T13:54:49.791543: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name Max Instrument loaded.

  1. we open a max4live device a preset on Poli called Tam

… hmmm nothing in the logs … lets try switching devices and back to Tam

4.5 now we get:

2023-01-26T14:00:13.443148: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name Tam loaded.
2023-01-26T14:00:13.443154: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name MxDeviceInstrument loaded.
2023-01-26T14:00:13.443160: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name Max Instrument loaded.

Hmm interesting, Tam is just a preset Poli is the device name

  1. we open a Ableton Device called Analog, we get

2023-01-26T14:02:48.445297: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name Analog loaded.
2023-01-26T14:02:48.445303: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name UltraAnalog loaded.
2023-01-26T14:02:48.445309: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name Analog loaded.

??? Ultra … what ???

  1. we open a Analog preset called ¨Accordion Unisono Pad¨

2023-01-26T14:05:21.093476: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name Accordion Unisono Pad loaded.
2023-01-26T14:05:21.093482: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name UltraAnalog loaded.
2023-01-26T14:05:21.093487: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name Analog loaded.

  1. we save a vst3 bx_console SSL 4000 E¨ under ¨save presetvst3¨

2023-01-26T14:07:53.949401: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.name bx_console SSL 4000 E loaded.
2023-01-26T14:07:53.949407: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_name PluginDevice loaded.
2023-01-26T14:07:53.949413: info: RemoteScriptMessage: E1 (debug): – Dumper for device device.class_display_name bx_console SSL 4000 E loaded.

class_name: the class name of the device, Max device, Plugin device…
class_display_name: the name of the device as seen on the top bar of the device
name: should include the preset name

[
TYLER MAZAIKA](https://cycling74.com/author/56633f3fd78f77af5a3857c8)

DEC 12 2017 | 4:31 PM

I don't know offhand of such a device, but this is possible. Check out the LiveAPI for "Device". You'd want to use "get class_name" to see if the device is an AU or VST, and then "get class_display_name" for the name of the plugin.

1 Like

Note that the remote script already contains debugging code to track these different versions of the name in ElectraOneBase:

    def get_device_name(self, device):
        """Return the (fixed) name of the device (i.e. not the name of the preset)
           - device: the device; Live.Device.Device
           - result: device name; str
        """
        # TODO: adapt to also get an appropriate name for MaxForLive devices
        # and for plugins
        # (device.name equals the name of the selected preset;
        # device.class_display_name is just a pretyy-printed version of class_name)
        self.debug(5,f'Returning class_name { device.class_name } as device name. Aka name: { device.name } and class_display_name: { device.class_display_name }')
        self.debug(5,f'(has type { type(device)}.) ')
        return device.class_name

I will do some more testing later, but what I have observed so far on MacOs is the following output:

Returning class_name ChannelEq as device name. Aka name: Channel EQ and class_display_name: Channel EQ
Returning class_name Tuner as device name. Aka name: Tuner and class_display_name: Tuner
Returning class_name Looper as device name. Aka name: 1 Bar Phrase and class_display_name: Looper
Returning class_name UltraAnalog as device name. Aka name: 5ths Vocoder Pad and class_display_name: Analog
Returning class_name LoungeLizard as device name. Aka name: Electric and class_display_name: Electric
Returning class_name StringStudio as device name. Aka name: Tension and class_display_name: Tension
Returning class_name MxDeviceAudioEffect as device name. Aka name: CV LFO and class_display_name: Max Audio Effect
Returning class_name MxDeviceInstrument as device name. Aka name: Emit and class_display_name: Max Instrument

As you can see on MacOs class_display_name is just the normal readable version of the class: Max Instrument or Max Audio Effect.

2 Likes

See

The value -1 means that the string value to display on the E1 is completely determined by the E1: only a MIDI CC value update needs to be sent. The patch was to remove this and instead set it to the control_id of the control in the E1, so that the remote script can send the value as a the string as reported by Ableton (which is necessary for complex value ranges like the Q (and the frequency) in Eq8

1 Like

@Martin I tested this, and even without the “formatFloat” code the fader jumps from min to max without anything in between. Definitely a bug :wink:

1 Like

I have not tested yet. I can see, however, that the min is greater than max. It is something I still need to implement. It would be handy for “reverting” action of controls. I think setting to -300 and -50 / unipolar could be a workaround for now.

1 Like

Ok. Will not do that for presets generated on the fly, as it can be fixed when curating presets and adding them to Devices.py

1 Like