Re: How to : use midi remote script Major Update (sparkle)
Posted: Tue Feb 04, 2014 7:59 am
Awesome post! There can never be enough post on making MIDI remote scripts. Keep up the good work!
Wow i have checked the price of the BCR 2000.... occasion for 70 euros.ttilberg wrote: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.
ttilberg wrote:Raz, if you do, I would really appreciate you documenting your journey some more, sharing source, etc.
Thanks for your contributions!
Ill help you with your research as much as i can : wewill try to modify the sparkle script to work with the presets of the BCRttilberg wrote:I spent some time tweaking the code to install the Live Telnet script, and started working on getting the code hooked up for BCR, but didn't get very far. I was actually messing with the BCR again this past weekend (fixing some internal hardware issues) and was going to start writing code again today, which is why I thought to come back and check this thread lol.
Programming the BCR to accept the sparkle mapping shouldn't be tricky, but I'm wanting to try writing the stuff using it's factory presets, so that other BCR2000 scripts work as well. On the factory preset, the first page is all strictly CC messages for every control. I imagine that should work out just as well, just needing to alter all of the definitions in the script you wrote.
I'll let you know if I come up with anything cool as well.
Code: Select all
#button map
REC=24
STOP=25
PLAY=26
TRANSPORT_BUTTONS=(('REC',REC),
('STOP',STOP),
('PLAY',PLAY))
SELECT=20
BUTTON_18_916=21
MUTE=22
SOLO=23
SELECT_BUTTONS=(('SELECT',SELECT),
('BUTTON_18_916',BUTTON_18_916))
LOW=35
MEDIUM=34
HIGH=33
VOLUME_BUTTONS=(('LOW',LOW,35),
('MEDIUM',MEDIUM,64),
('HIGH',HIGH,127))
BANK=16
PATT=17
SEQ=18
TUNE=19
MODE_BUTTONS=(('BANK',BANK),
('PATT',PATT),
('SEQ',SEQ),
('TUNE',TUNE))
PATTERN_LENGTH_BUTTON=(('LESS',36),
('MORE',37))
PATTERN_BUTTONS=range(0,16)
PAD_BUTTONS=range(60,68)
PAD_LEDS=range(68,76)
Code: Select all
PAD_BUTTONS=range(60,68)
PAD_LEDS=range(68,76) // you have to find how you light the ledsCode: Select all
BANK=16
PATT=17
SEQ=18
TUNE=19
Code: Select all
def bank_button_value(self,value):
if value>0:
if self.parent.actual_clipslot!=None:
for element in self.parent.pattern_buttons :
self.turn_led_off(element.identifier)
self.turn_led_on(self.identifier)
self.parent.song().scenes[self.identifier].fire()Code: Select all
def bank_button_value(self,value):
if value>0:
self.status=True
for element in self.parent.pattern_buttons :
self.turn_led_off(element.identifier)
self.turn_led_on(self.identifier)
self.parent.actual_pad=self
self.parent.update_cache()
self.parent.update_pattern_button()
self.parent.update_led()
I m glad to see poeple still trying to manage to use midiremotescript.infernal.machine wrote:Really happy to see someone posting information about this stuff on the forums! Learning how to make simple MIDI remote scripts is way more difficult than it needs to be, glad to see people talking about it!
Code: Select all
The LiveUtils.py file, written by Rob King in that LiveTelnet package you posted, has been invaluable for me to understand the syntax needed to access Live's API. I'm currently working on a version of LiveUtils that includes ALL the commands that I know how to use, with good documentation to explain how to use them. I'm pretty much just pulling from the Live Object Model, located here: http://cycling74.com/docs/max6/dynamic/c74_docs.html#live_object_model
... so if you know of any other resources let me know!!Code: Select all
The scripts I've written look a lot different from yours, so I'm interested to dive deeper. For the most part, I write a bunch of 'if MIDI message received is X, make Live do Y', which really just serves to avoid MIDI mapping and to control Live directly with my controllers. It also gives my controllers more functionality and improves my workflow.Code: Select all
def update_pattern_button(self):
if self.actual_mode_button==self.mode_buttons[0]:
for element in self.pattern_buttons:
self.turn_led_off(element.identifier)
element.clear_value_listeners()
element.add_value_listener(element.bank_button_value, identify_sender= False)
elif 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]:
self.update_cache()
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)
Any of the values (60, 61) end up representing a control of 50? Is this just a typo?d)Practical example:
The aim of this example is to create a script that will light the pad 51 and write on the log file "HelloWorld" when the pad 50 is pressed
Code:
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))
Woops, this is a mistake, because i used for my exemple thevalue 51, and for the sparkle the first pad was the 60 ( and the second 61 instead of 51)...Any of the values (60, 61) end up representing a control of 50? Is this just a typo?
wich version of the sparkle did you downloaded? it doesn't seems to be the latest, and many mistakes have been modified.I tried following your suggestions, but started getting lost when talking about the PAT, SEQ, TUNE, BANK stuff.
Specifically, the parts of the code that you were recommending changing:
def bank_button_value():
do not appear in the source I downloaded. As I am not totally clear what all of the different buttons and options are supposed to do in the first place, I'm not able to carry on debugging it.