Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Twitter

modifying remote scripts

edited January 2014 in Software Discussion

I'm trying to avoid hammering this forum with questions but after reading through relevant sections on the wiki I haven't found the droids I'm looking for.

I would like to modify assignments for the main script (non stepper) for the CNTRLR.

For example how would I go about changing the 4 assignments set to pan to say a third set of sends for the 4 channels?
How would I change the second set of faders to a 4th set of sends instead of return/return/prehearvol/mastervol?

I'd also like to change the assignments for bottom 32 buttons as well.

Any help much appreciated.  I've played with the editor but don't understand its purpose.  I can't find the correlation between Ableton's functions and the assignment values in the editor.  I also checked out the script which looks promising, but I again cannot wrap my chimp brain around what the values mean and where to get definitions for the one's I want to swap.

It would be great if a section was added to the wiki about this.  Perhaps I missed it?

Many thanks.  This gear is so damn cool it hurts!  I want to put it to good use melting faces!


  • I can say that you've not missed any documentation that I know of. The remote scripts can be modified, but there is no documentation for it.

    Hopefully this will give your post a bump.

  • Hey there jsalmont, 

    There used to be a bunch of posts dealing with exactly this sort of thing but most of them got lost when we moved the forums last year :(

    I'm glad to help you out with this, but as Mark stated, there aren't any docs for this sort of thing as Ableton has never officially supported user-end modifications to the Remote Scripts.

    The CNTRLR script is a little messy, I'm afraid, but you can find the main assignments that you want to change inside the CNTRLR.assign_live_controls() method.  I'm afraid a little bit of Python coding familiarity is really necessary to do this sort of thing, but I'm glad to help you with any questions you have if you choose to undertake it.

    The file is basic assignments that are used by the script.  You CAN make a lot of changes in it, but not the changes you are talking about.  It defines the CC/NOTE values for each of the script objects, as well as the colors displayed by the controls when in certain modes.  

    The CNTRLR script is fairly well commented internally (an exception to the rule with most of my scripts, I'm afraid).  Most of what you want can happen with some creative copying and pasting.

    Example for Pan:  

    It's assignment happens on line 1041, 

    self._mixer.channel_strip(track).set_pan_control(self._dial_left[track + 8]) #now we set the pan control to the bottom 

    So, we comment that line by adding a # to the beginning of it:

    #self._mixer.channel_strip(track).set_pan_control(self._dial_left[track + 8]) #now we set the pan control to the bottom 

    Now, we need to find the assignments for sends.  Turns out they are on line 1037:

    channel_strip_send_controls = []
    for control in range(2):
    channel_strip_send_controls.append(self._dial_left[track + (control * 4)])

    These lines set up an array, then recursively add two controls to the array.  All we need to do in order to add another control is change one number:

    for control in range(3):

    However, if you were to run this, it wouldn't work.  The reason is that back early in the script, the MixerComponent is only set up to handle two sends per channel.  So there is at least one more number we need to change back in the _setup_mixer_control() method on line 778:

    self._mixer = MixerComponent(4, 3, True, False) #These values represent the (Number_of_tracks, Number_of_returns, EQ_component, Filter_component)

    In addition, there are places in the script where things are deassigned so that they can be reassigned for different modes.  You will have to make sure th

  • ose are changed, although in this case I think its not an issue since those particular knobs remain static.  

    Hope that helps, let me know if you have some questions or need further direction about this stuff.

  • Amounra,

    I took a closer look at the code. Documentation was super helpful.

    Applied suggestions successfully.

    For anyone interested:

    I figured out the Editor allows for easy swaps of note values.  So any of the 32 bottom buttons can be simply moved around.  With this graphic for reference:

    Swap em in any order you want.  Make sure that no matter the order, every number is represented in the ID range of 16-47.  Send to device then permasave.

    I wasn't able to get the 32 buttons moved predictably in the file.

    Few things have been rough on me:

    How to add incremental tempo to two buttons in my case for buttons 20 (up +1 bpm) and 36 (down -1 bpm).  I found this tutorial but I wasn't able to get it working right with the editor.

    In the editor I see an OUTPUT value but not cc.  The article above suggests that the same cc be assigned to both buttons followed by two values 0 and 127.  Can't figure this out in the editor any tips?

    I'm also looking to assign pitch +1 and -1 to two buttons based on what clip is selected.  Seems like the method above should do the same for pitch?  

    I also commented out the code associated with resetting returns in the main script to free up those 4 buttons for tempo and pitch.  Hope I didn't miss anything.

    #self._send_reset.set_buttons(tuple(self._button[index + 8] for index in range(4)))

    Tricky part for me is getting led on/off behavior in the script for both pitch and tempo buttons.

    Any help much appreciated.


  • Gentlemen,

    Any tips? 

    How to add incremental tempo to two buttons in my case for buttons 20 (up +1 bpm) and 36 (down -1 bpm).  I found this tutorial but I wasn't able to get it working right with the editor.


  • Since you can't set a static value for a CC in our editor, that method won't work.

    If you want to add this to the remote script, it's a relatively minor ordeal (ish).  

    You'll need to make sure to import subject_slot (as it's probably not in the CNTRLR script already):

    from _Framework.SubjectSlot import subject_slot, subject_slot_group

    Then, add these functions somewhere in the main class:

    def on_tempo_up_value(self, value):
    if value: = min( + 1,

    def on_tempo_down_value(self, value):
    if value: = max( - 1,
    You'll assign your buttons to these functions in the assign_live_controls() method, but it will depend one what buttons you're using as to how they'll be assigned.  It looks something like this:

    self.on_tempo_up_value.subject = self._encoder_button[9]
    self.on_tempo_down_value.subject = self._encoder_button[8]

    You'll also need to deassign them again in deassign_live_controls() or things won't work when switching modes:

    self.on_tempo_up_value.subject = None
    self.on_tempo_down_value.subject = None

    If this is over your head, let me know and I'll clarify however I can.


  • Hey Amounra,

    Thanks for the 411.  Still trying to wrap my mind around where to paste these bits.

    I assumed all this code belongs in

    I put the following in the import section:
    from _Framework.SubjectSlot import subject_slot, subject_slot_group

    I put the following:
       def on_tempo_up_value(self, value):
          if value:
       = min( + 1,

       def on_tempo_down_value(self, value):
            if value:
       = max( - 1,

    In this section:
    class Cntrlr(ControlSurface):

    As to the last part I was at a loss.  I would like to map the tempo +1 -1 buttons to two of the bottom 32 buttons, specifically the first two arm buttons (20 and 21).  In order to do this I first commented out the existing arm assigns in the following section:

    """here we assign the left side of our mixer's buttons on the lower 32 keys"""

    #self._button[index+4].set_on_value(ARM[self._rgb]) #set the arm color from the

    #self._mixer.channel_strip(index).set_arm_button(self._button[index+4]) #assign the arm buttons to our mixer channel strips

    Is this correct?  Is it also required that I comment out the deassign?

    I was not able to determine the syntax for the rest as it appears encoders are perhaps treated differently then buttons?  Can you indicate what code and precisely where to?  I get the feeling the assign and deassign code needs to be surgically placed without noob antics.

    Lastly I would also like to do the same thing for pitch +1 and -1.  Would the procedure be similar?  I realize pitch is attached to each clip and the controls would have to be context sensitive.

    Thanks for explaining Python to civilians.  I mightily appreciate it.

    Many thanks,

  • Wow, missed this one, too.  Soooo sorry!

    It's never REALLY necessary to remove anything from deassign(), only to add it when you've created another definition somewhere so that it DOES get deassigned when switching modes.  You can have all sorts of superfluous deassignments listed, and all that will happen is it might (very very) slightly slow the script down when changing modes.

    SO.  Yes, you'll need to remove the assignment section for the buttons you want to use, and it looks like you found the right place (although that will remove assignments for all FOUR buttons, not just the two you want).

    Then, you just add the lines with the @subject_slot decorator somewhere in the CNTRLR class....doesn't matter where, they should be at the same level as the rest of the def statements in the class though (indentation, I mean).

    As for the encoders, they are dealt with in the same way with the newstyle framework, but they WILL have to be dealt with differently since they are sending more than just on/off values.  

    Doing pitch is going to be tricky....I don't know that it's going to be possible with built-in methods, or if there is a hook for it in the API.  I'll try to do some checking to see.

    Again, apologies for the late reply....this one slipped by me.


  • I'm grateful for your help so no worries:)

    I'd like to map the +1 -1 tempo functionality to two of the four freed ARM buttons (20 and 21).  How would I change the following code you provided to accommodate for this?

    self.on_tempo_up_value.subject = self._encoder_button[9]
    self.on_tempo_down_value.subject = self._encoder_button[8]

    These assignments appear to be for encoders.  Can you give me adjusted code for buttons?  Where would this code go?  I searched for the following category:

    assign_live_controls() method

    And located the following area.  Is this the right place for button assignment code?

    def assign_live_controls(self):

    bunch of stuff

    """here we assign the left side of our mixer's buttons on the lower 32 keys"""
    for index in range(4):
    self._button blah blah
    <GOES HERE?>

    I get a little flustered with context.


  • Been experimenting with different syntax in the interim but no luck so far.  The following button assignment code I located (if this is even correct) is very different looking in terms of syntax from the (self.on_tempo_up_value.subject = self._encoder_button[9]) you provided above.

    The code I located for button assignments:

    self._button[index+4].set_on_value(ARM[self._rgb]) #set the arm color from the

    self._mixer.channel_strip(index).set_arm_button(self._button[index+4]) #assign the arm buttons to our mixer channel strips

    Also this code appears to be for all four arm buttons and attached to the mixer strips with this [index+4] manner of assignment.  Just to be clear, I have commented out the ARM code above freeing up 4 buttons, two of which (20 and 21) I would like to use for tempo.

    Argh help!

    ps: It would be great if you could include suggestions for lighting these two tempo buttons up.  Adding code to I imagine?  I can do without this if you're running short on time.

  • Sorry for the late reply....not in a place where I can answer the details right now, but I'll get back to you tomorrow ;)

  • Most excellent looking forward to it.

  • Amounraaaa...

  • Sorry for the delay, just didn't have the time to sit down and read this entire thread to make sure I knew what you were after.  I initially thought you were after more than you appear to be.

    I'd like to map the +1 -1 tempo functionality to two of the four freed ARM buttons (20 and 21).  How would I change the following code you provided to accommodate for this?

    The buttons you're looking for are the same one's you've commented in the assign method,  and for reference you can see what all the controls are in the setup_controls() method.  The assignments should look like this:

    self.on_tempo_up_value.subject = self._button[5]
    self.on_tempo_down_value.subject = self._button[4]

    This just tells the script that whenever it gets a value at self._button[5], for instance, to trigger the subject_slot we set up earlier.

    To assign it a color, add these:

    self._button[4].set_on_value(color you want)
    self._button[5].set_on_value(color you want)

    And then turn them on:


    Or you can simply send a value:

    self._button[4].send_value(color you want, force = True)
    self._button[5]. send_value(color you want, force = True)

    Let me know if we're on the right track and we can take this further?



  • Hello, I am glad I found this thread as I had a similar question. I am also not familiar with scripting, but would like to make one crucial change to the monohm remote script, to run on a different midi channel, lets say channel 12. My problem is that I am running an APC 40 as well which operates on midi channels 1-8 as well. When I hard map knobs from one of these controllers to controls in ableton,  they step on eachother's toes.

    I  opened the  and saw """ Here we define some global variables """

    CHANNEL = 0 . 

    I tried changing the 0 to a 1. that did nothing. Im obviously noobing it here.. Amounra, is what I am thinking possible? are you able to help me find what I need to change in the script?

    thanks alot


  • Yeah, should be able to change CHANNEL variable to 11 (channels are 0 - 15) and get what you want, but keep in mind:  you'll also have to change the global channel of your controls via the Ohm's editor so that it is transmitting on that channel.  The CHANNEL variable in the Map file is only defining the transmit/receive channel for the still have to change it to match on your hardware and save it to the Ohm.

    Let me know if that fixes you up ;)


  • edited May 2014

    Was not able to figure out where to put this code with any certainty.  I imagine I've guessed incorrectly.  The following screenshots may indicate where the fail is.

    This is where I put the framework code:

    This is where I put the @subject code:

    This is what I commented to free the arm buttons:

    This is where I put the buttons code:

    I don't have any sense of syntax unfortunately, so knowing exactly where to put the code is going to be important for me.  If these locations are not correct can you be specific about placement?

    As to the LED color assignment and turning them on, where do I put these four lines?

    Lastly, what do the numbers self.button[5] and self.button[4] refer to?  The buttons I would like to map tempo control to (+1 -1) are cc21 and cc23.  Do I replace [5] and [4] with [21] and [23]?

    I have uploaded my live 9.1 script here:

    It's stock except for those screenshots.

    It's a jungle in there.


  • The button numbers you're looking for are indeed _button[4] and _button[5] I works like this:

    In the setup_controls() function, we define a bunch of objects (buttons, encoders, etc.) and assign them CC or Note #'s.  The line that creates the button objects and assigns them their Note# values is:

    for index in range(32):
    self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_BUTTONS[index], 'Button_' + str(index), self)

    This function loops through 32 times, and for each time it uses a different variable for "index".  The first time it creates _button[0] and then assigns it  the first value from the CNTRLR_BUTTONS array in the map file as it's Note#, , the next time it it creates _button[1] and uses the second value from the array, etc. until it gets to the 32nd button. The _buttons are 32 in number, and cover the bottom 2 rows of buttons on the CNTRLR.

    I moved the subject_slot methods to the bottom....generally you want any class methods to be below the class __init__ function, which is what creates the class and defines all its variables and methods.

    I moved the assignments outside of the for() loop....anytime you see a for statement with a colon, it means that a loop will be performed.  If it were inside the loop, the assignment would have been made 4 separate times for each statement, which isn't what we want.

    The led assignments go right underneath the button assignments....I added them and you can play around with the colors.

    It's really necessary to look at your log.txt file when doing this stuff.  Usually if you've done something wrong, it will tell you where the error is (sometimes down to the line #) when you load the script.

    Major problem:  I am assuming youre using an older version of Live?   If you're using 9.12 this script won't work.  It's an older version and is incompatible with some methods that Ableton changed in the most current version.  I'd recommend updating your copy of Live and downloading the most current version of our scripts, especially since I've pretty much finished a new version of the CNTRLR script that will be getting released'll make things easier in the longrun ;)

    Anyway, I couldn't check the script to see if it works or not b/c I don't have the older version of Live installed here.....let me know if you have trouble, and send me your log.txt file.


  • edited May 2014

    Good stuff!

    Appears to be an issue:

    10365 ms. RemoteScriptError:   File "MIDI Remote Scripts\Livid_CNTRLR\", line 1533, in on_tempo_down_value
    10381 ms. RemoteScriptError:     
    10387 ms. RemoteScriptError: = max( - 1,
    10393 ms. RemoteScriptError: AttributeError
    10399 ms. RemoteScriptError: : 
    10406 ms. RemoteScriptError: 'float' object has no attribute 'min'

    Multiple errors.
    Log file can be nabbed here:


  • Ok, device parameters have a min& max value, I guess tempo doesn't?

    Use this instead:
    def on_tempo_up_value(self, value):
    if value: = min( + 1, 999)

    def on_tempo_down_value(self, value):
    if value: = max( - 1, 20)

    Let me know if that works :)

  • Genius!  It works.  Super happy thank you so much.  I can't wrap my mind around how anyone could dj without this.  They must use their track pads?

    If you're ever in Oregon (Bend) you've got a place to stay!
  • Glad it works!  Let me know when you get to the next stage...

    Small world....I'm in Arcata ;)


  • @jsalmont

    I am using a Launchpad S with the LPC Live 2 script next to the CNTRL:R. This way I use the Launchpad for the global controls, such as play-stop clips, tempo adjustments, etc. And the CNTRL:R is used for the volume faders and knobs for eq 3 as well as several effects that I have mapped to buttons, this is all done on mod 3 as a separate DJ page.

  • Hey Amounra,

    I recently had a rather strange mishap.  The top four buttons on the 4x4 grid on my CNTRLR are now yellow instead of white.  Other than that they respond normally.  I reinstalled live, deleted everything I could find (all Ableton folders in appdata, documents, and programdata) and I reset the controller using the online editor.  Spent the last 4 hours working on this to no avail.  Super maddening.  I also reverted to stock scripts.

    Any suggestions?


    ps: As a sidenote, is Bitwig a dev's dream to develop for (unlike Ableton)?  Curious.
  • Hmmm.  They are they ALWAYS yellow, or only when using the Live script?  Have you used MIDI to sniff the output going to the CNTRLR and see if the buttons are receiving messages to turn the buttons yellow?

    re:  BW, I like it :)  I miss Python, but the openness is very encouraging, and I'm very accustomed to writing in Javascript.  I'll be glad when I can spend some more time with it and document some of the work I've done, and I'm looking forward to future improvements.
Sign In or Register to comment.