Compare commits

...

7 Commits

  1. 2
      README.md
  2. 31
      config.json
  3. 7
      osc_client.py
  4. 80
      osc_server.py

2
README.md

@ -16,7 +16,7 @@ git clone https://git.sav.net.au/Public/osc_led.git
```
# Setup Reaper, load the template
Set up reaper to listen on port 9000 and send to port 8000.
Set up reaper to listen on port 8000 and send to port 9000.
Control surface mode: OSC
Mode: Configure device IP + local port
Device port: 9000

31
config.json

@ -0,0 +1,31 @@
{
"inputs":{
"buttons":{
"restart":{
"pin": 2,
"when_pressed": "restart"
}
}
},
"outputs":{
"leds":[
{"name":"1",
"pin": 21,
"target": 3
},
{ "name":"2", "pin":20, "target":"4", "defaults": { "state":0,"brightness":1.0}},
{ "name":"3", "pin":16, "target":"5"},
{ "name":"4", "pin":12, "target":"6"},
{ "name":"5", "pin":5, "target":"7"}],
"defaults":{
"led":{
"brightness": 1.0,
"colour": 1.0 ,
"state": 0
}
}
}
}

7
osc_client.py

@ -24,13 +24,14 @@ def cmd_stop():
osc_msg_send("/stop","i",1)
def cmd_restart():
stop()
cmd_stop()
osc_msg_send("/gotomarker","i",1)
play()
cmd_play()
parser = argparse.ArgumentParser(description='OSC controller for REAPER')
parser.add_argument('command', action='store',choices=[cmd.replace("cmd_",'') for cmd in globals() if 'cmd_' in cmd],help='Command to send via OSC')
if __name__ == '__main__':
parser.add_argument('command', action='store',choices=[cmd.replace("cmd_",'') for cmd in globals() if 'cmd_' in cmd],help='Command to send via OSC')
parser.add_argument('--debug-osc',action='store_true',default=False,help='Debug OSC messages')
parser.add_argument('--server',action='store',default='127.0.0.1:8000',help="Server to connect to <server>:<port>. Defaults to localhost:8000",metavar='server:port')
args=parser.parse_args()

80
osc_server.py

@ -8,12 +8,16 @@ from pprint import pprint
import argparse
import colorsys
import gpiozero
import osc_client
import json
# Set up basic vars and logging
logging.basicConfig(format='%(asctime)s - %(threadName)s ø %(name)s - '
'%(levelname)s - %(message)s')
log = logging.getLogger("osc")
log = logging.getLogger("ledserver")
log.setLevel(logging.INFO)
osc_log=logging.getLogger("osc")
osc_log.setLevel(logging.WARNING)
clientname="ledserver"
# Get the normalised RGB values for the HSV (i.e, the colour float designating hue from OSC)
@ -43,21 +47,24 @@ class LED:
state=False
# The pin number of the LED
pin=None
# The OSC target FX param
target=0
name=""
# List for logging state
mode=["off","on"]
# Initialize the object, set up GPIO
def __init__(self,pin):
def __init__(self,pin,target):
self.pin=pin
self.target=target
self.led=gpiozero.PWMLED(pin)
# Set the brightness, this only triggers on a delta threshold so that we don't go crazy
def set_brightness(self,value):
if abs(self.brightness-value) > .005:
self.brightness=value
self.led.value=self.state*self.brightness
print("Setting brightness for LED on pin {} to {}".format(self.pin, self.brightness))
log.info("Setting brightness for LED on pin {} to {}".format(self.pin, self.brightness))
# Set the colour, only on a delta threshold
def set_colour(self,value):
@ -82,17 +89,66 @@ class LED:
# Set the colour of the LEDs. This only does the first LED, but when the REAPER controls are finalised, it'll be more controllable
def led_colour(value):
leds[0].set_colour(value)
for name,led in leds.items():
led.set_colour(value)
# Set the brightness of all LEDs. As above, when REAPER is finalised it'll be controllable (or everything, as required)
def led_brightness(value):
for led in leds:
for name,led in leds.items():
led.set_brightness(value)
# Turn an individual LED on or off based on FX param 3+
def led_state(addr,value):
led=addr.split("/")[6]
leds[int(led)-3].toggle_state(bool(value))
target=addr.split("/")[6]
for led in [led for name,led in leds.items() if led.target==target]:
led.toggle_state(bool(value))
def btn_restart():
initialise()
osc_client.cmd_restart()
def btn_play():
osc_client.cmd_play()
def btn_stop():
osc_client.cmd_stop()
def initialise(filename='config.json'):
global config
global leds
global buttons
config=json.load(open(filename))
log.info("Creating LEDs...")
# Create LEDs
if 'leds' in globals():
del leds
leds={led['name']:LED(led['pin'],led['target']) for led in config['outputs']['leds']}
for led in config['outputs']['leds']:
if "defaults" not in led:
led['defaults']={}
for i in config['outputs']['defaults']['led'].keys():
led['defaults'][i]=config['outputs']['defaults']['led'][i]
state=led['defaults']["state"] if "state" in led["defaults"] else config['outputs']["defaults"]['led']["state"]
colour=led['defaults']['colour'] if 'colour' in led['defaults'] else config['outputs']['defaults']['led']['colour']
brightness=led['defaults']['brightness'] if 'brightness' in led['defaults'] else config['outputs']['defaults']['led']['brightness']
leds[led['name']].set_state(bool(state))
leds[led['name']].set_colour(colour)
leds[led['name']].set_brightness(brightness)
# Don't re-initialise buttons, specifically because we expect this to be called by a button
# And unassigning the calling button will probably break things
if 'buttons' not in globals():
buttons={}
for name,button in config['inputs']['buttons'].items():
log.info('Binding button {} to pin {}'.format(name,button['pin']))
buttons[name]=gpiozero.Button(button['pin'])
log.info('Binding button {} when_pressed to {}'.format(name,button['when_pressed']))
buttons[name].when_pressed=globals()['btn_'+button['when_pressed']]
pprint(buttons[name].when_pressed)
# Set up command line arguments
@ -108,7 +164,7 @@ log.info("Starting OSC...")
# Log OSC stuff if requested
if args.debug_osc:
osc_startup(logger=log)
osc_startup(logger=osc_log)
else:
osc_startup()
@ -129,10 +185,10 @@ osc_method("/track/2/fx/1/fxparam/2/value",led_brightness)
osc_method("/track/2/fx/1/fxparam/[!12]/value",led_state,argscheme=OSCARG_ADDRESS+OSCARG_DATAUNPACK)
log.info("Creating LEDs...")
# Create LEDs
leds=[LED(i) for i in [16,20,21]]
initialise()
#restart_button=gpiozero.Button(2)
#restart_button.when_pressed=osc_client.cmd_restart
# Do a massive loop listening for messages. This should really be cleaner...

Loading…
Cancel
Save