Ableton Live MIDI Remote Script / Control Surface

It looks the latest firmware does not work with the remote script.
I think its due to the version number minor field.
Current v3.1 is a major. Should this has been v3.10

RemoteScriptError: not enough values to unpack

    def set_version(self, versionstr):
        """Set the E1 firmware version.
           - versionstr: version string as returned by request response; str
        """
        # see https://docs.electra.one/developers/midiimplementation.html#get-an-electra-info
        # format "v<major>.<minor>.<sub>"
        try:
            (majorstr,minorstr,substr) = versionstr[1:].split('.')
            ElectraOneBase.E1_version = (int(majorstr),int(minorstr),int(substr))
        except ValueError:
            self.debug(f'Failed to parse version string { versionstr }.')
            ElectraOneBase.E1_version = (0,0,0)
        self.debug(2,f'E1 version { ElectraOneBase.E1_version }.')
ElectraOneBase.py", line 277, in set_version

2023-01-28T13:08:04.998054: error: RemoteScriptError:     
2023-01-28T13:08:04.998086: error: RemoteScriptError: (majorstr,minorstr,substr) = versionstr[1:].split('.')
2023-01-28T13:08:04.998109: error: RemoteScriptError: 

2023-01-28T13:08:04.998133: error: RemoteScriptError: ValueError
2023-01-28T13:08:04.998156: error: RemoteScriptError: : 
2023-01-28T13:08:04.998179: error: RemoteScriptError: not enough values to unpack (expected 3, got 2)
2023-01-28T13:08:04.998201: error: RemoteScriptError: 

Ah. Thanks. Will fix tomorrow when back behind my computer.

Great thanks! I tried but failed :slight_smile:

Should be fixed now. I also changed the logic for waiting for confirmation (ACK/NACK) from the E1. This should be more reliable now.

2 Likes

Hi Jaap,

I have another issue running the latest commit.
This looks to be a type error.

def _is_symmetric_dB(p):
    (min_number_part, min_type) = _get_par_value_info(p,p.min)
    (max_number_part, max_type) = _get_par_value_info(p,p.max)    
    return min_type == 'dB' and (-float(min_number_part) == float(max_number_part))

Other plugins do not have this issue.
This is the SSL4000 channel strip. That used to work except the Q control.

could not convert string to float: '-oo'

Here is the offending parameter.

Here the logs.

2023-01-29T17:50:12.583050: info: RemoteScriptMessage: E1 (debug): - Uploading device PluginDevice
2023-01-29T17:50:12.583078: info: RemoteScriptMessage: E1 (debug): -- Getting preset for PluginDevice.
2023-01-29T17:50:12.583086: info: RemoteScriptMessage: E1 (debug): -- Constructing preset on the fly...
2023-01-29T17:50:12.583102: info: RemoteScriptMessage: E1 (debug): -- Dumper for device PluginDevice loaded.
2023-01-29T17:50:12.583381: info: RemoteScriptMessage: E1 (debug): -- Filter and order parameters
2023-01-29T17:50:12.583461: info: RemoteScriptMessage: E1 (debug): -- Construct CC map
2023-01-29T17:50:12.584074: info: RemoteScriptMessage: E1 (debug): -- Construct JSON
2023-01-29T17:50:12.589664: error: RemoteScriptError: Traceback (most recent call last):

2023-01-29T17:50:12.589707: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOne.py", line 368, in update_display

2023-01-29T17:50:12.589885: error: RemoteScriptError:     
2023-01-29T17:50:12.589916: error: RemoteScriptError: self._effect_controller.update_display()
2023-01-29T17:50:12.589942: error: RemoteScriptError: 

2023-01-29T17:50:12.589969: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\EffectController.py", line 174, in update_display

2023-01-29T17:50:12.590078: error: RemoteScriptError:     
2023-01-29T17:50:12.590107: error: RemoteScriptError: self._upload_assigned_device_if_possible_and_needed()
2023-01-29T17:50:12.590132: error: RemoteScriptError: 

2023-01-29T17:50:12.590159: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\EffectController.py", line 296, in _upload_assigned_device_if_possible_and_needed

2023-01-29T17:50:12.590284: error: RemoteScriptError:     
2023-01-29T17:50:12.590313: error: RemoteScriptError: self._upload_assigned_device()
2023-01-29T17:50:12.590337: error: RemoteScriptError: 

2023-01-29T17:50:12.590363: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\EffectController.py", line 283, in _upload_assigned_device

2023-01-29T17:50:12.590532: error: RemoteScriptError:     
2023-01-29T17:50:12.590560: error: RemoteScriptError: preset_info = self._get_preset_info(device)
2023-01-29T17:50:12.590584: error: RemoteScriptError: 

2023-01-29T17:50:12.590611: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\EffectController.py", line 212, in _get_preset_info

2023-01-29T17:50:12.590714: error: RemoteScriptError:     
2023-01-29T17:50:12.590742: error: RemoteScriptError: dumper = ElectraOneDumper(self.get_c_instance(), device)
2023-01-29T17:50:12.590766: error: RemoteScriptError: 

2023-01-29T17:50:12.590792: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOneDumper.py", line 834, in __init__

2023-01-29T17:50:12.591011: error: RemoteScriptError:     
2023-01-29T17:50:12.591042: error: RemoteScriptError: self._preset_json = self._construct_json_preset(device_name, parameters, self._cc_map)
2023-01-29T17:50:12.591072: error: RemoteScriptError: 

2023-01-29T17:50:12.591101: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOneDumper.py", line 700, in _construct_json_preset

2023-01-29T17:50:12.591294: error: RemoteScriptError:     
2023-01-29T17:50:12.591322: error: RemoteScriptError: self._append_json_controls(parameters,cc_map)
2023-01-29T17:50:12.591346: error: RemoteScriptError: 

2023-01-29T17:50:12.591374: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOneDumper.py", line 668, in _append_json_controls

2023-01-29T17:50:12.591594: error: RemoteScriptError:     
2023-01-29T17:50:12.591622: error: RemoteScriptError: self._append_json_control(id,p,cc_info)
2023-01-29T17:50:12.591646: error: RemoteScriptError: 

2023-01-29T17:50:12.591672: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOneDumper.py", line 644, in _append_json_control

2023-01-29T17:50:12.591852: error: RemoteScriptError:     
2023-01-29T17:50:12.591894: error: RemoteScriptError: self._append_json_fader(id,parameter,cc_info)
2023-01-29T17:50:12.591940: error: RemoteScriptError: 

2023-01-29T17:50:12.591979: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOneDumper.py", line 600, in _append_json_fader

2023-01-29T17:50:12.592231: error: RemoteScriptError:     
2023-01-29T17:50:12.592262: error: RemoteScriptError: elif _is_symmetric_dB(parameter):
2023-01-29T17:50:12.592286: error: RemoteScriptError: 

2023-01-29T17:50:12.592312: error: RemoteScriptError:   File "E:\Ableton User Lib\User Library\Remote Scripts\ElectraOne\ElectraOneDumper.py", line 247, in _is_symmetric_dB

2023-01-29T17:50:12.592487: error: RemoteScriptError:     
2023-01-29T17:50:12.592517: error: RemoteScriptError: return min_type == 'dB' and (-float(min_number_part) == float(max_number_part))
2023-01-29T17:50:12.592542: error: RemoteScriptError: 

2023-01-29T17:50:12.592568: error: RemoteScriptError: ValueError
2023-01-29T17:50:12.592592: error: RemoteScriptError: : 
2023-01-29T17:50:12.592616: error: RemoteScriptError: could not convert string to float: '-oo'
2023-01-29T17:50:12.592639: error: RemoteScriptError:

I asume this has todo with the fix for the Q values that have min / max presented the other way around.

Tried to enable debug (5) but did not see the difference. and didn’t see the actual full value which python uses.
The template does not load for this specific device.

Regarding the device.name class name issue I have not found a way to get the max4live name when using a preset. But the following works for all Ableton devices, Plugins and max4live devices when not using a preset.
I have not yet made device templates so that needs to be tested.

ElectraoneDumper.py

    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)
        device_name = device.class_name
        if device_name in ('PluginDevice', 'MxDeviceMidiEffect', 'MxDeviceInstrument', 'MxDeviceAudioEffect'):
            device_name = device.name
            self.debug(2,f'Using Device.name as: { device_name }')
        else:
            self.debug(2,f'Dumper for device device.class_name { device_name } loaded.')
        
        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} ({p.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 = ''

ElectraOneBase.py

    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
        """
        device_name = device.class_name
        # 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)
        if device_name in ('PluginDevice', 'MxDeviceMidiEffect', 'MxDeviceInstrument', 'MxDeviceAudioEffect'):
            device_name = device.name
            self.debug(5,f'Returning name { device.name }')
            self.debug(5,f'(has type { type(device)}.) ')
        else:
            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_name

Ok now I am just trying ideas and so on.

What I do not understand I you look here:

And here on children

Was hoping that somehow MaxDevice would get access to the proper name.

  Return const access to the name of the device's class name as displayed in Live's browser and device chain
Live.MaxDevice.MaxDevice.class_nameProperty
  Return const access to the name of the device's class.
Live.MaxDevice.MaxDevice.nameProperty
  Return access to the name of the device.

As you can see I haven’t ate any kaas from this.
Just hoping to bring some ideas to the table.

Cheers

Tim

1 Like

Thanks for spotting this, that was a silly mistake. The string “-oo” is used by Live to denote minus infinity, but of course that is not a valid float string :wink: Should be fixed now.

Yeah, that’s exactly what I found: device_name is the actual device name, unless when a preset is selected. I’ll try to dig in some other remote scripts to see how the reliably get the device name

1 Like

Hi Jaap,

Great thanks a lot. the experience is getting quite smooth.

Curious if you find anything on device naming.
I can ask some questions for hints on the cycling74, Ableton and synthforum if that helps.

As said my Push MK1 doesn’t show the original max4live device name neither.
But PluginDevice works at least on windows.
So If at some point we find out it is not possible we could figure of some meganism where you first load the original max4live or Plugin device (on Mac) and that you can switch to a max4live or vst Plugin preset after and make that the eone does not load another preset.

#Brainstorm
I like the idea of on the fly generated templates.
As you can order the parameters for PluginDevices in Ableton.
Only thing is that switches are always created as a fader.
It would be nice to have a list where you can add the parameters to be created as a switch.
If there would be an additional list where you can add colours you could generate everything always dynamically.
The whole remote script could also be stateless.
Where it will only send one page to the eone.
This page has to only stay in memory which I think is the case already.
That single page could have some navigation buttons to trigger: fetching previous or next page and fetch next or previous device in the chain.
I think this will give a performance boost and also improves the workflow.

Is there anyone who has a controller that shows the original max4live device name on its display? Not the preset name?

Cheers

Tim

2 Likes

just installed 3.1 FW and latest Script. Now the problem is again that the “plugin device preset” is not created at Bank6, P2.

1 Like

Hey @phoneaak I think that the preset isn’t stored at all.
Which not needed anyhow.
Only the Mixer is stored.

Do you see a generated preset for the Plugin Device?

1 Like

the “plugin device preset” is created next to the mixer preset (bank6,p2) if a plugin is “appointed”.
that is, it was like this until now, I saw the “au plugin” preset.
now if I click on a plugin, of course the Script is activated with the upper right button, I see the names of the Ableton tracks, then if I press the upper right button again, it switches to bank 6, p2, but the plugin device preset is not created there .

1 Like

Ah I seem to see something similar.
When I select a track no “preset” is assigned.
Only when I click on the plugin is the Ableton Device Chain.
And it is then seen on preset 2 bank 6.

Edit: I touched the preset page and now it work…

Wow this is so sick. I now got a SSL channel strip.
It just loads and you don’t have to think much. Jaap uhhh the script takes care of all the values. So in Ableton you see HZ, DB etc.

1 Like

I tried all night, unfortunately it doesn’t work for me

can enable debug = 5?
there might be hints what the issue is.

what are you trying todo that does not work?

what platform? win, mac

1 Like

macos Monterey (last).
Ableton last

The plugins device not works

It appears that somehow uploading of the preset fails or does not happen. Is a preset uploaded if you explicitly select (click on) a device in Live?

For debugging, set DEBUG=5 in config.py and restart Ableton and send the log.

i try it afternoon Thanks

where can i find the log?

See the instructions in the documentation GitHub - xot/ElectraOne: Ableton Live MIDI Remote Script for the Electra One

hello,
well done again ! I am very impressed by the update ! I wanted to know if the .ccmap file must be created manually or if the! I’m starting to understand how it works on windows. I wanted to know if the .ccmap file must be created manually or if there is an automation of creation?
Otherwise I can’t import the preloaded ableton device presets created by @jhh into the electra webeditor. Are they protected?

Salutation
Bob mo

2 Likes