How to : use midi remote script Major Update (sparkle)

Discuss music production with Ableton Live.
Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

How to : use midi remote script Major Update (sparkle)

Post by Raztua » Mon Dec 23, 2013 4:28 pm

Edit 15/02/2014
new version avaliable : V1.5 Important update
sources are avaliable here Sources
changelog here





Edit january 2014 : link to the Video: Enjoy
https://vidd.me/HiH

Sources are avaliable on the 9th post



Hi everybody,

Lately I have bought a sparkle ( step sequencer from Arturia ), and i have decided to write a midi remote script for this hardware.I knew nothing about Python programming, Poo programming and else.
I am glad poeple like Hanz Petrovand Julien Baylehad put lots of tips to describe how Midi remote scripts worked.

Thank to them, i have been able to write an alpha version of my step sequencer.
Now that I understand more precisely how midi remote script works, I have decided to start a new midi remote
script from scratch in a more flexible way.

I) How do I create a midi remote script?

All the files of your script have to be in a folder that have the name of your script, situated in the Ableton\ Live \Resources\MIDI Remote Scriptsfolder.
To initialise your script you have to create a __init__.py file, you can use Notepad++, Ulipad, or any other software
This file is mandatory, because it tells to Live that you want to initialise a script. For the sparkle i have made this __init.__py file:

Code: Select all

from sparkLE2 import sparkLE2   # you import your main program during the initialisation of your script


def create_instance(c_instance):    # this function tells live that you create a new midi remote script
    return sparkLE2(c_instance)      # the initialisation result is the calling of the main function of your script.
The other file needed is the script itself. I have to have the name that u use during the importation on the __init__.py file.
below, their is a script that does NOTHING but contain all the requirement to be a working script

Code: Select all

from __future__ import with_statement #compatibility for Live 9, need to be written at the first line of the script
import Live #you import Live, in order to be able to use its components
from _Framework.ControlSurface import ControlSurface # importthe Controle surface module

class sparkLE2(ControlSurface):          # create a class element 
    __module__=__name__                  #name of the class
    __doc__="Sparkle function"           #documentation 
    
    def __init__(self, c_instance):                #initialize the sparkLE2 class as a ControleSurface
        ControlSurface.__init__(self,c_instance)   #import the components of a ControlSurface
        with self.component_guard():               #don't know the us of this, but it is recquiered in live 9 scripts
            self.__c_instance = c_instance         

This is it! you have created your first useless script

II) How do I debug my script ?

To actualise your script you have to close and reopen live (you can keep notepad++ open).
To debug your script you have to check the logfile made by Live. You can find this logfile (on window) here
C:\Users\Raztua\AppData\Roaming\Ableton\Live 9.1\Preferences\Log.txt
Errors are logged in this file.
To follow the execution of your script you can use two different functions:
self.show_message('your message here') writes on the status bar of Live
self.log_message('your message here') writes on the log file your message

III) Helloworld

To make this helloworld we will create a function that write on the log_message and the status bar Hello world
This function will be called during the nitialisation of the surface

Code: Select all

from __future__ import with_statement #compatibility for Live 9, need to be written at the first line of the script
import Live #you import Live, in order to be able to use its components
from _Framework.ControlSurface import ControlSurface

class sparkLE2(ControlSurface):
    __module__=__name__
    __doc__="Sparkle function"
    
    def __init__(self, c_instance):
        ControlSurface.__init__(self,c_instance)
        with self.component_guard():
            self.__c_instance = c_instance
            self.helloworld()                     #call the helloworld function during the initialisation of your script


    def helloworld(self):                         #create the helloworld fuction (with the self argument, live uderstand that this function belong to the SparkLE object)
        self.log_message('helloworld')     
        self.show_message('helloworld')
IV) Send and receive midi:
a) send midi :

You can find more precise information about midi messages here :http://www.midi.org/techspecs/midimessages.php
My sparkle surface uses only midi note message to "talk" with the computer, ( it uses sysex too but i will not talk about this).
Midi notes messages hare a tuple of 3 integer.
for exemple (144,60,100) the key C3 ( value 60 ) is pressed (value 144 ) on the channel 0 vith a velocity of 100
the first integer have two information : a key is pressed (note on message is 144) on the channel 1 (channels are labelled from 0 to 15)
144+0=144
if I want to send a note off message for the C3 on the channel 2 key ill send the tuple ( 128+1=129, 60, 0 )
Ill only use note on and note of message to light the leds of my surfaces
The command used to send mii message is self._send_midi( 'tuple' )

b) receive midi :
there is two way to receive a midi message :
Implicitly : if you dont program anything on your surface concerning a midi button, it will automatically be mapped to live.
The following part of the script allow to use autom mapping from live

Code: Select all

    def build_midi_map(self, midi_map_handle):      
		ControlSurface.build_midi_map(self, midi_map_handle)
		
Explicitly : if you want to execute a specific order when a key is pressed you have to explicitly forward the message and use the function: ".add_value_listener"
and is used this way :

Code: Select all

[ButtonElement].add_value_listener('the order to launch',identify_sender= True)

c) Create a button element:
To be able to use a button element on a ControlSurface you have to import the ButtonElement class.
To import constants associated with midi note and command cc, we import the package InputControlElement
At the start of the script we add : from _Framework.ButtonElement import ButtonElement
from _Framework.InputControlElement import *

Then we create a button element associated to one of the pad of the surface (here the pad 50)
the command is:
self.pad=ButtonElement(not IS_MOMENTARY, MIDI_NOTE_TYPE, 0, 18
d)Practical example:
The aim of this example is to create a script that will light the pad 61 and write on the log file "HelloWorld" when the pad 60 is pressed

Code: Select all

from __future__ import with_statement #compatibility for Live 9, need to be written at the first line of the script
import Live #you import Live, in order to be able to use its components
from _Framework.ControlSurface import ControlSurface
from _Framework.ButtonElement import ButtonElement
from _Framework.InputControlElement import *


IS_MOMENTARY=True

class sparkLE2(ControlSurface):
    __module__=__name__
    __doc__="Sparkle function"
    
    def __init__(self, c_instance):
        ControlSurface.__init__(self,c_instance)
        with self.component_guard():
            self.__c_instance = c_instance
            self.show_message('Script initiated')
            self.Pad1=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,60) # identifies P&d1 as a ButtonElement. IS_MOMENTARY is true if the button send a message on being released
            self.Pad1.add_value_listener(self.helloworld,identify_sender= False) #adda value listener that will lauch the method self.helloworld when Pad1 is pressed

	def disconnect(self):              #this function is automatically called by live when the program is closed
		self.turn_off_led(60)
		self.turn_lef_off(61)
	
    def helloworld(self,value):
        if value>0:                                 #value>0 when the pad is pressed
            self.log_message(self,'hello world')
            self.turn_led_on(61)
        else:
            self.turn_led_off(61)
        
    def turn_led_on(self,value):
        self._send_midi((144,value,64))
    def turn_led_off(self,value):
        self._send_midi((128,value,64))

V) clipslots, clips and note:
the current sont is accessed via the command :
self.actual_song=Live.Application.get_application().get_document()
this command gives access to the tracks, clips... of the song.
a)creating a clip
to select the first clipshot on the first track:

Code: Select all

self.first_clipslot=self.actual_song.tracks[0].clip_slots[0]
to create a the clip on this clipslot:

Code: Select all

self.first_clipslot.create_clip(length)
b)add a note

to add a note on a clip, for example a C3 at the second beat 0.5beat long, with a velocity of 64:

Code: Select all

self.first_clip=self.first_clipslot.clip
		self.first_clip.set_notes(((60,1.0,0.5,64,False),))    #the attribute is a tuple of tuple with the argument ((note,start,length,velocity,muted),)

c)get and remove notes
to gets notes:

Code: Select all

self.first_clip.get_notes(1.0,60,0.5,2) #to get all the notes from C3 to C4, between 1 and 1.5 beat , arguments: (starting beat,base note,length of the selection,rand of notes)
to remove notes:

Code: Select all

self.first_clip.remove_notes(1.0,60,0.5,2) #to get all the notes from C3 to C4, between 1 and 1.5 beat , arguments: (starting beat,base note,length of the selection,rand of notes)
		


VI) Session mode:
Sessions are groups of clips. they are showed on live with colored boxes(sometime called ring).
the aim on this script is to use my pads 50 and 51 to move my session to the right and to the left

Code: Select all

from __future__ import with_statement #compatibility for Live 9, need to be written at the first line of the script
import Live #you import Live, in order to be able to use its components
from _Framework.ControlSurface import ControlSurface
from _Framework.ButtonElement import ButtonElement
from _Framework.InputControlElement import *

from _Framework.SessionComponent import SessionComponent     #this is the component used to create Sessions



IS_MOMENTARY=True

class sparkLE2(ControlSurface):
    __module__=__name__
    __doc__="Sparkle function"
    
    def __init__(self, c_instance):
        ControlSurface.__init__(self,c_instance)
        with self.component_guard():
            self.__c_instance = c_instance
            #initialisation and setup of the pad
            self.Pad_left=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,60)
            self.Pad_right=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,61)
            #initialisation of the session
            self.create_session_control()
            self.set_highlighting_session_component(self.Session)        #link the session model to the Live object-> shows your ring
            

    def create_session_control(self):
        width=1                             #width of the Session
        height=8                            #height of the Session
        self.Session=SessionComponent(width,height)          #here we create a session called Session
        self.Session.set_offsets(0,0)       #offset start a the up-left corner (track1,row1)
        self.Session._do_show_highlight()   #to ensure that this session will be highlighted
        self.Session.set_track_bank_buttons(self.Pad_right,self.Pad_left)   #associate buttons 
If poeple are interested, ill continue to log here my work.
As I said i am new to scripting, but ill be glad to help you if needed, and i ll be even more happy if poeple correct my mistakes, or scripting errors :)

PS: if you want to see my former script in action --------> Video
Last edited by Raztua on Sat Feb 15, 2014 7:49 pm, edited 7 times in total.

dr.mysterium
Posts: 88
Joined: Sat Jul 14, 2012 6:15 pm

Re: How to : use midi remote script for the SparkLE

Post by dr.mysterium » Tue Dec 24, 2013 8:09 pm

Nice work. Thank you for posting this info.
I'm very interested, please continue.
I am Dr. M. Solo artist, member of 86BiTz, host of the Perfect Glitch Show, & the Live Jam Video Stream. Music on Soundcloud and BandCamp. Jam Archive on Patreon•••• I master audio & produce video of all of the above as Tremendm Labs on YouTube.

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script for the SparkLE

Post by Raztua » Sat Dec 28, 2013 3:27 pm

Today i will work on pattern button and mode selector button.
To ensure the flexibility of th script, ill create a new class "PatternButton".
In this part ill make simple scripts that doesn't talk together (ie : mode selector button doesnt modify the way pattern button works) and then post the final script

To create this class, i create a new file called PatternButton.py, in the sparkLE folder.
This class is a ButtonElement class modified adapted to my needs.
the pattern buttons have 4 different role :
  • to select a bank
  • to select a clipslot
  • to modify the sequencer
  • to be used in tune mode : just like a midi keyboard
The mode selector button

it is derivated from a button element class. When one of the four mode buttonn is selected, it changes the actual_mode_button element, and modify the sparkle

######################################ModeButton.py#################################

Code: Select all

from __future__ import with_statement #compatibility for Live 9, need to be written at the first line of the script
import Live #you import Live, in order to be able to use its components
from _Framework.ButtonElement import ButtonElement


IS_MOMENTARY=True

class ModeButton(ButtonElement):
    __module__=__name__
    __doc__="Sparkle function for mode buttons"
    
    def __init__(self, is_momentary, msg_type, channel, identifier, parent):
        ButtonElement.__init__(self, is_momentary, msg_type, channel, identifier[1])
        self.status=False
        self.identifier=identifier[1]
        self.parent=parent
        self.name=identifier[0]
        
        
        
    def mode_button_value(self, value):
        if value>0:
            if self.parent.actual_mode_button==None:
                self.parent.actual_mode_button=self
            else:
                self.parent.actual_mode_button.status=False
                self.turn_led_off(self.parent.actual_mode_button.identifier)
                self.parent.actual_mode_button=self
                self.parent.actual_mode_button.status=True
                self.turn_led_on(self.parent.actual_mode_button.identifier)
            self.parent.
            

    def turn_led_on(self,value):
        self._send_midi((144,value,64))
    def turn_led_off(self,value):
        self._send_midi((128,value,64))
    

First, i will build the sequencer :
this is a basic to check if component works. It creates a clip on the first track, and first clipslot, and listen to the value of pattern button to create on C3 or remove midi notes.
Each button is associated to a beat. When a button is pressed, a midi note is either added or removed from the actual clip ( The length of this clip is 4 -> 16 beats correspound to 16 buttons). The key element is to create a cache on the main part of the script. This cache is 16 element long. Each element is associated to a beat. If the actual clip have a beat, the value of the element is True else, it is False. When a button is pressed, the function set_notes or remove notes are called.

the files are avaliable here:
http://www.mediafire.com/download/4x0v2 ... kLE3.1.rar

######################################PatternButton.py#################################

Code: Select all

from __future__ import with_statement #compatibility for Live 9, need to be written at the first line of the script
import Live #you import Live, in order to be able to use its components
from _Framework.ButtonElement import ButtonElement


IS_MOMENTARY=True

class PatternButton(ButtonElement):
    __module__=__name__
    __doc__="Sparkle function for Pattern buttons"
    
    def __init__(self, is_momentary, msg_type, channel, identifier, parent):
        ButtonElement.__init__(self, is_momentary, msg_type, channel, identifier)
        self.status=False
        self.identifier=identifier
        self.parent=parent
        self.name= 'pattern button' + str(identifier)
        
        
        
    def pattern_button_value(self, value):   #called when a button is pressed
        if value>0:
            self.live_sequencer_update()
            self.sparkle_sequencer_update()
            
            
    def sparkle_sequencer_update(self):         #update the light of a button  on the sparkle following the cache
        self.status=self.parent.cache[self.identifier]
        if self.status==False:
            self.turn_led_off(self.identifier)
        else:
            self.turn_led_on(self.identifier)
        
    def live_sequencer_update(self):           #update the actual clipslot
        if self.parent.cache[self.identifier]==True:
            self.parent.cache[self.identifier]=False
            self.parent.actual_clipslot.clip.remove_notes(0.25*self.identifier,60,0.25,1)
        elif self.parent.cache[self.identifier]==False:
            self.parent.cache[self.identifier]=True
            self.parent.actual_clipslot.clip.set_notes(((60,0.25*self.identifier,0.22,100,False),))
            
    def turn_led_on(self,value):
        self._send_midi((144,value,64))
    def turn_led_off(self,value):
        self._send_midi((128,value,64))
            
If you want to test this script with another surface, you can modify the Const file. But you have to modify these lignes to get it working :

Code: Select all

self.parent.actual_clipslot.clip.set_notes(((60,0.25*self.identifier,0.22,100,False),))

Code: Select all

self.parent.actual_clipslot.clip.set_notes(((60,0.25*self.identifier,0.22,100,False),))
Now i build the pattern selector
When the mode button pressed is Patt, the patterns buttons listeners are changer :
this is the "dispatcher" function thant changes the function called when a pattern button is pressed :

Code: Select all

def update_pattern_button(self):
        if self.actual_mode_button==self.mode_buttons[1]:
            
            for element in self.pattern_buttons:
                self.turn_led_off(element.identifier)
                element.clear_value_listeners()
                element.add_value_listener(element.pattern_button_value, identify_sender= False)
            if self.actual_clipslot!=None:
                self.turn_led_on(self.actual_clipslot.identifier)

        
        elif self.actual_mode_button==self.mode_buttons[2]:
            for element in self.pattern_buttons:
                element.sparkle_sequencer_update()
                element.clear_value_listeners()
                element.add_value_listener(element.seq_button_value, identify_sender= False)
                        
        else:
            for element in self.pattern_buttons:
                self.turn_led_off(element.identifier)
When one of the pattern button is pressed a new clipslot is created according to the value of the pattern button.
The function called is :

Code: Select all

 def pattern_button_value(self,value):
        if self.parent.actual_clipslot==None:
            self.parent.actual_clipslot=self.parent.song().tracks[0].clip_slots[self.identifier]
            self.parent.actual_clipslot.identifier=self.identifier
            self.turn_led_on(self.identifier)
            self.parent.actual_clipslot.create_clip(4)
        else:
            self.turn_led_off(self.parent.actual_clipslot.identifier)
            self.parent.actual_clipslot=self.parent.song().tracks[0].clip_slots[self.identifier]
            self.parent.actual_clipslot.identifier=self.identifier
            
            self.turn_led_on(self.identifier)
            if self.parent.actual_clipslot.clip==None:
                self.parent.actual_clipslot.create_clip(4)
                self.parent.cache=16*[False]
                
            else:
                self.parent.update_cache()
            
        self.parent.actual_clipslot.fire()
        self.parent.song().view.highlighted_clip_slot=self.parent.actual_clipslot

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script for the SparkLE

Post by Raztua » Thu Jan 02, 2014 3:00 pm

Happy new year!

Today I will work on the mute button.
The way it works: when the mute button is pressed, it transform the way the pads of the surface react:
-if the note associated with the pad is not muted, the led of the pad is off
-else the led is lighted
when a pad is pressed, the note lane is muted/unmuted.

to update the status of the pads i have written this part of the program:

Code: Select all

    
    def mute_button_value(self,value):
        if value>0:
            if self.status==True:
                self.status=False
                self.turn_led_off(self.identifier)
                for element in self.parent.pad_buttons:
                    self.turn_led_off(element.identifier)
                
            else:
                self.status=True
                self.turn_led_on(self.identifier)
                self.update_mute_status()    
    def update_mute_status(self):
        for element in self.parent.pad_buttons:
            self.turn_led_off(element.identifier)
            element.mute=self.get_mute_status(element.identifier))          
            if element.mute==True:   
                self.turn_led_on(element.identifier)
        
    def get_mute_status(self,note):
        note_tuple=self.parent.actual_clipslot.clip.get_notes(0.0,note,4,1)
        if len(note_tuple)>0:
            return note_tuple[0][4]

The mute button value is called when the mute button is pressed. if mute is activated it callsthe function mute update status.
Then i get the tuple of note for each pad with the get_mute_status function. If the first note is muted the attribute of note_tuple[0][4] is True.

This way i can update the status of the muted notes when i change my pattern in live.

To change the status of a note i have added a new function in my pad buttons :

Code: Select all

def set_mute_status(self,note):
        note_tuple=self.parent.actual_clipslot.clip.get_notes(0.0,note,4,1)
        note_cache=[]
        if len(note_tuple)>0:
            for element in note_tuple:
                note_cache.append([element[0], element[1], element[2], element[3], not note_tuple[0][4]])
            self.parent.log_message(note_cache,note_tuple)
            self.parent.actual_clipslot.clip.remove_notes(0.0,note,4,1)
            self.parent.actual_clipslot.clip.set_notes(tuple(note_cache))
            self.parent.actual_clipslot.clip.deselect_all_notes()
The sources are avaliable here

Sources
Last edited by Raztua on Sat Feb 15, 2014 7:16 pm, edited 1 time in total.

Emerah
Posts: 42
Joined: Wed Apr 02, 2008 1:18 pm
Location: Cairo

Re: How to : use midi remote script for the SparkLE

Post by Emerah » Thu Jan 02, 2014 6:05 pm

Thanks for sharing great information.
I wanted to point out that:
self._actual_song and self.__c_instance are already constructed in (ControlSurface). and since (ControlSurface) is also initialised in SparkleLE, you can directly use self.song() and self.__c_instance in SparkleLE script. also self.application() will come in handy and is already defined in (ControlSurface)

awesome knowledge share. please continue to share your experience as you build your script.
it never ends. neither does it begin where you think it does. its only in your mind.

namlow
Posts: 12
Joined: Fri Apr 20, 2012 4:25 am

Re: How to : use midi remote script for the SparkLE

Post by namlow » Thu Jan 02, 2014 8:55 pm

Interesting post, keep posting!

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script for the SparkLE

Post by Raztua » Mon Jan 06, 2014 4:23 pm

Hello every body!
Emerah wrote:Thanks for sharing great information.
I wanted to point out that:
self._actual_song and self.__c_instance are already constructed in (ControlSurface). and since (ControlSurface) is also initialised in SparkleLE, you can directly use self.song() and self.__c_instance in SparkleLE script. also self.application() will come in handy and is already defined in (ControlSurface)

awesome knowledge share. please continue to share your experience as you build your script.
Yep you are right, it is useless, i can remove it. Can you tell me what is c_instance made for ?

Emerah
Posts: 42
Joined: Wed Apr 02, 2008 1:18 pm
Location: Cairo

Re: How to : use midi remote script for the SparkLE

Post by Emerah » Tue Jan 07, 2014 1:07 am

c_instance referes to 'Live'

there are some functions that are defined within 'Live' written in 'C' language and you use self._c_instance to access them … for example the method 'show_message' in (ControlSurface) is actually just a call to 'show_message' which is already internally defined in 'Live'. so is 'log_message', 'request_rebuild_midi_map' and many more.

call them 'Live' internally defined functions if you will and in order to access them from Python you use (self._c_instance.live_internal_function).

like when you want to partially modify a function already defined in (ControlSurface) in i.e 'SparkLE' script, you write the desired modification and then call (ControlSurface.the_same_function_you_modified). that tells the script to read the rest of the function from ControlSurface, right!?. same thing happens when you call a function with self._c_instance. it tells the script to read the function directly from 'Live'.
it never ends. neither does it begin where you think it does. its only in your mind.

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script for the SparkLE

Post by Raztua » Thu Jan 09, 2014 11:36 am

Hi followers,

Today i ll try to make a simple program that uses 5 buttons to browse instruments
I will use:
  • button 60 to activate the browser
  • button 61 to navigate up
  • button 62 to navigate down
  • button 63 to navigate left
  • button 64 to navigate right



here is the script :

Code: Select all

import Live #you import Live, in order to be able to use its components
from _Framework.ControlSurface import ControlSurface
from _Framework.ButtonElement import ButtonElement
from _Framework.InputControlElement import *



IS_MOMENTARY=True

class sparkLE2(ControlSurface):
    __module__=__name__
    __doc__="Sparkle function"
    
    def __init__(self, c_instance):
        ControlSurface.__init__(self,c_instance)
        with self.component_guard():
            self.__c_instance = c_instance
            self.view=self.application().view
            self.show_message('initialiasation du script')
            #initialisation and setup of the pad          
            self.Pad_browser=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,60)
            self.Pad_browser.status=False            
            self.Pad_up=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,61)
            self.Pad_down=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,62)            
            self.Pad_left=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,63)
            self.Pad_right=ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,64)
            
            self.Pad_browser.add_value_listener(self.browser,identify_sender= False)
            self.Pad_up.add_value_listener(self.up,identify_sender= False)
            self.Pad_down.add_value_listener(self.down,identify_sender= False)
            self.Pad_left.add_value_listener(self.left,identify_sender= False)
            self.Pad_right.add_value_listener(self.right,identify_sender= False)
            
            self.view.hide_view('Browser')

    def browser(self,value):
        if value!=0:
            if self.Pad_browser.status==False:
                self.Pad_browser.status=True
                self.view.focus_view('Browser')
                self.view.show_view('Browser')
                
            elif self.Pad_browser.status==True:
                self.Pad_browser.status=False
                self.view.hide_view('Browser')
                
    def up(self,value):
        if value!=0:
            self.view.scroll_view(0,'Browser',False)
            
            
    def down(self,value):
        if value!=0:
            self.view.scroll_view(1,'Browser',False)
            
    def left(self,value):
        if value!=0:
            self.view.scroll_view(2,'Browser',False)
            
    def right(self,value):
        if value!=0:
            self.view.scroll_view(3,'Browser',False)
How ever i am unable to simulate the return key with a midi inforamtion.
-> I can't add the device to the selected rack.

I have checked the Browser.tags.children etc etc and i am able to load a device using the browser method,

But i am unable to link the View object and the browser object.

if someone has an idea :)

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script Major Update (sparkle)

Post by Raztua » Mon Jan 27, 2014 8:44 pm

I have finally decided to Make a video on wich i show all the possibilities of the script.
you can find the sources here : Sources
And the link to the video : Video

I hope you'll enjoy this update of the script.

I you need any help to get it working, Or if you have suggestion to improve the script, feel free to tell me :)

regretfullySaid
Posts: 8913
Joined: Thu Apr 22, 2010 5:50 pm

Re: How to : use midi remote script Major Update (sparkle)

Post by regretfullySaid » Mon Jan 27, 2014 10:47 pm

Thanks for sharing, very cool.

I don't think you need to open and close Live everytime you want to re-actualise the script.
Try unselecting the script in the preferences, like 'none', and then reselect the script.
That might re-actualise it.
ImageImage

ttilberg
Posts: 587
Joined: Wed Oct 05, 2011 4:55 pm
Contact:

Re: How to : use midi remote script Major Update (sparkle)

Post by ttilberg » Tue Jan 28, 2014 2:10 am

Raz, thanks a f309783ing lot for sharing this, and trying to put together some information. I truly despise how Ableton makes controller editing some sort of black magic affair. I'm a .net programmer and DBA, and making remote scripts is still very difficult because of lack of documentation.

I appreciate the refreshed effort, man. I hate to be this guy, but I hope that BitWig's .js implementation of scripting devices puts Ableton on their toes to do a better job at making this stuff accessible. Live's built-in midi mapping is getting really long in the tooth (i.e. not being able to make my own blue-hand device preferences, mapping stuff to VSTs whenever they are open, having more than 8 flipping' parameters, etc).

I REALLLLY want to blue-hand my Behringer BCR2000 to my most common synths (Operator, Strobe) with more than 8 fricken knobs, and not have to midi map it and save the set, and rely on that one instance of the one device. UGH! </rant>

Props dude!
Tim Tilberg - Duluth, MN | SoundCloud - Arsenal
2011 13" MBP w/8GB ram | Live 9 Suite, Reason 6.5, FXPansion DCAM/Etch/Maul, Izotope Ozone 5

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script Major Update (sparkle)

Post by Raztua » Tue Jan 28, 2014 5:07 pm

shadx312 wrote:Thanks for sharing, very cool.

I don't think you need to open and close Live everytime you want to re-actualise the script.
Try unselecting the script in the preferences, like 'none', and then reselect the script.
That might re-actualise it.
I didn't talked about this, because sometimes it works, and sometime it doesn't work.
So sometime your correct a mistake, reload the script, but everithing isnt reloaded, and you this your correction is false.
If you restart each time, even if it is Damn Boring, Your are sure that the script is refreshed.
ttilberg wrote:Raz, thanks a f309783ing lot for sharing this, and trying to put together some information. I truly despise how Ableton makes controller editing some sort of black magic affair. I'm a .net programmer and DBA, and making remote scripts is still very difficult because of lack of documentation.

I appreciate the refreshed effort, man. I hate to be this guy, but I hope that BitWig's .js implementation of scripting devices puts Ableton on their toes to do a better job at making this stuff accessible. Live's built-in midi mapping is getting really long in the tooth (i.e. not being able to make my own blue-hand device preferences, mapping stuff to VSTs whenever they are open, having more than 8 flipping' parameters, etc).

I REALLLLY want to blue-hand my Behringer BCR2000 to my most common synths (Operator, Strobe) with more than 8 fricken knobs, and not have to midi map it and save the set, and rely on that one instance of the one device. UGH! </rant>

Props dude!
Tell me what you want to do, and i could tell you how to start.
By the way, the best way to learn how to code something is to use the live telnet API
It made me win a lot of time.
you can find it here. live telnet

ttilberg
Posts: 587
Joined: Wed Oct 05, 2011 4:55 pm
Contact:

Re: How to : use midi remote script Major Update (sparkle)

Post by ttilberg » Tue Jan 28, 2014 8:15 pm

That looks really helpful!

Honestly, I lost interest in hacking Live about 6 months ago after running up against so many walls of things that didn't work. In part because I was learning .py along with it, and in part because the documentation is so scattered. With these new resources, my interest has sort of been re-perked at figuring it out.

The two things that I feel would be awesome with my BCR2000:
1) Context aware synth control for more than 8 parameters, without having to shuffle pages.
i.e.: With Operator selected (blue-hand style), I can have the 24 main nobs controlling the 24 parameters I find most helpful. With Analog selected, they are different. And ideally, a way to do the same for VSTs, perhaps through config routing and saving a rack with it in there. This seems so damned straightforward in pseudo code, but I just couldn't make the right connections.

2) I always thought it would be cool to make an 808/909 style sequencer out of it -- it has 16 lights you can use, and you could map the knobs to different common drum-hit parameters like decay, etc. I have some drum racks that I've saved that would work really great, but I don't have enough control over the mapping interface to make it all work, and be contextually aware. This is where your SparkLE project piqued my interest most of all.
Tim Tilberg - Duluth, MN | SoundCloud - Arsenal
2011 13" MBP w/8GB ram | Live 9 Suite, Reason 6.5, FXPansion DCAM/Etch/Maul, Izotope Ozone 5

Raztua
Posts: 24
Joined: Fri Dec 20, 2013 7:38 pm

Re: How to : use midi remote script Major Update (sparkle)

Post by Raztua » Wed Jan 29, 2014 7:46 pm

I think it is easy to transpose my script to the bcr2000.
What you have to do :
  • 1) change your button on the berringer this way : The 16 pattern buttons ( ie the two row of 8 buttons ) have to be assigned as a Midi Note from 0 to 15 ( 0 for the upper left button etc etc. and 15 for the right button of the secon row)
  • change the 4 user buttons to midi notes with theese values : Select button = 20, pattern selector=17, sequence =18 , tune mode 19

i think this will works a bit
but i need to know wich button you can assign and wich button are not assignable

I found this sofware http://mountainutilities.eu/bcmanager

Post Reply