New features
This commit is contained in:
parent
dcaa716d29
commit
b36da76c22
57
README.md
57
README.md
@ -1,8 +1,11 @@
|
|||||||
# Forward Midi events to redis/OSC
|
# Forward Midi events to redis and OSC
|
||||||
|
|
||||||
|
Miredis hooks to all midi devices connected and listen for events. All events are forwarded to your redis server and your OSC server.
|
||||||
|
|
||||||
|
Miredis can optionnaly hook to opensourced Link protocol (200+ music & videos apps) -> "/beat" & "/bpm".
|
||||||
|
|
||||||
|
Custom events can be triggered with reranged values from one or two CC. Szz custom action types
|
||||||
|
|
||||||
Miredis hooks to all midi devices connected and listen for events.
|
|
||||||
Miredis can optionnaly hook to opensourced Link protocol (200+ music & videos apps) -> "/beat" & "/bpm"
|
|
||||||
All events are forwarded to your redis server and your OSC server.
|
|
||||||
|
|
||||||
|
|
||||||
![Clitools](https://www.teamlaser.fr/images/miredispad.png)
|
![Clitools](https://www.teamlaser.fr/images/miredispad.png)
|
||||||
@ -19,16 +22,28 @@ To enable Link :
|
|||||||
|
|
||||||
python3 miredis.py -link
|
python3 miredis.py -link
|
||||||
|
|
||||||
(for cheap midi interface midisport/midiman from audio on Linux : apt-get install midisport-firmware)
|
(for cheap midi interface midisport/midiman support on Linux : apt-get install midisport-firmware)
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
|
|
||||||
- Client example : midicontrol.py
|
- Midi timecode thks to https://github.com/jeffmikels/timecode_tools.git
|
||||||
- Added verbose mode -v
|
- CC values can be reranged, see 'custom action type'
|
||||||
- Added redis subscribe events
|
- LJ2 custom actions for laser settings (midichannel -> laser number)
|
||||||
- Added Clitools program selection mode for Launchpads
|
- Midi controlled python example : midicontrol.py
|
||||||
- Added custom redis 'key event', to be more semantic/hardware agnostic with Configuration file : miredis.json. i.e "/feedback/1/114/value" is generated each time a CC message on channel 1, CC 114 is recevied.
|
- Verbose mode -v
|
||||||
|
- Redis subscribe events
|
||||||
|
- Clitools program selection mode for Launchpads
|
||||||
|
- Cstom redis 'key event'. To be more semantic/hardware agnostic with configuration file miredis.json. i.e "/feedback/1/114/value" is generated each time a CC message on channel 1/ CC 114 is received.
|
||||||
|
|
||||||
|
## Custom action types (see miredis.json)
|
||||||
|
|
||||||
|
Process given CC(s), create and send result with a "name" event. Builtin types with mandatory parameters :
|
||||||
|
|
||||||
|
- 0 : note number (name, type, note)
|
||||||
|
- 7 : rerange 7 bits midi cc (0-127) to a lowend-highend number (name, type, CC, low end, high end, default value)
|
||||||
|
- 8 : rerange 7 bits midi cc (0-127) to 8 bits number (0-255) (name, type, CC, default value)
|
||||||
|
- 140 : rerange one midi cc (0-127) to 14 bits number (0-16383) (name, type, CC, default value)
|
||||||
|
- 14 : 2 cc (14 bits value) reranged to a lowend-highend number (name, type, highCC, lowCC, low end, high end, default value)
|
||||||
|
|
||||||
## OSC
|
## OSC
|
||||||
|
|
||||||
@ -76,3 +91,25 @@ custom ones
|
|||||||
"/midi/cc/midichannel/ccnumber/ccvalue"
|
"/midi/cc/midichannel/ccnumber/ccvalue"
|
||||||
|
|
||||||
customs one like "/feedback/1/114/value"
|
customs one like "/feedback/1/114/value"
|
||||||
|
|
||||||
|
## Custom events examples : LJ2 settings for midi controller
|
||||||
|
|
||||||
|
Buttons :
|
||||||
|
|
||||||
|
- grid/lasernumber note on 33
|
||||||
|
- black/lasernumber note on 35
|
||||||
|
- swap/X/lasernumber note on 24
|
||||||
|
- swap/Y/lasernumber note on 26
|
||||||
|
|
||||||
|
Sliders :
|
||||||
|
|
||||||
|
- kpps/lasernumber cc 0 cc 1
|
||||||
|
- angle/lasernumber cc 2 (0-360)
|
||||||
|
- scale/X/lasernumber value cc 4 (0-200)
|
||||||
|
- scale/Y/lasernumber value cc 5 (0-200)
|
||||||
|
- red/lasernumber cc 8 (0-255)
|
||||||
|
- green/lasernumber cc 9 (0-255)
|
||||||
|
- blue/lasernumber cc 10 (0-255)
|
||||||
|
- intensity/lasernumber cc 11 (0-255)
|
||||||
|
- loffset/X/lasernumber cc 12 cc 13 (-27000, 27000)
|
||||||
|
- loffset/Y/lasernumber cc 14 cc 15 (-27000, 27000)
|
||||||
|
Binary file not shown.
262
libs/midix.py
262
libs/midix.py
@ -3,7 +3,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Midi3 light version for soundt/Jamidi/clapt
|
Midi3 light version with LJ2 settings support
|
||||||
v0.7.0
|
v0.7.0
|
||||||
|
|
||||||
Midi Handler :
|
Midi Handler :
|
||||||
@ -15,6 +15,7 @@ by Sam Neurohack
|
|||||||
from /team/laser
|
from /team/laser
|
||||||
|
|
||||||
Midi conversions from https://github.com/craffel/pretty-midi
|
Midi conversions from https://github.com/craffel/pretty-midi
|
||||||
|
Guide to the MIDI Software Specification : http://www.somascape.org/midi/tech/spec.html#rpns
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ from threading import Thread
|
|||||||
|
|
||||||
import rtmidi
|
import rtmidi
|
||||||
from rtmidi.midiutil import open_midiinput
|
from rtmidi.midiutil import open_midiinput
|
||||||
from rtmidi.midiconstants import (CHANNEL_PRESSURE, CONTROLLER_CHANGE, NOTE_ON, NOTE_OFF,
|
from rtmidi.midiconstants import (CHANNEL_PRESSURE, CONTROLLER_CHANGE, NOTE_ON, NOTE_OFF, SYSTEM_EXCLUSIVE, MIDI_TIME_CODE,
|
||||||
PITCH_BEND, POLY_PRESSURE, PROGRAM_CHANGE, TIMING_CLOCK, SONG_CONTINUE, SONG_START, SONG_STOP)
|
PITCH_BEND, POLY_PRESSURE, PROGRAM_CHANGE, TIMING_CLOCK, SONG_CONTINUE, SONG_START, SONG_STOP)
|
||||||
import mido
|
import mido
|
||||||
from mido import MidiFile
|
from mido import MidiFile
|
||||||
@ -35,7 +36,7 @@ from sys import platform
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from libs import log
|
from libs import log, tools
|
||||||
import json
|
import json
|
||||||
|
|
||||||
oscIP = "127.0.0.1"
|
oscIP = "127.0.0.1"
|
||||||
@ -168,19 +169,17 @@ def SendUI(oscaddress,oscargs=''):
|
|||||||
|
|
||||||
|
|
||||||
# Ask redis for a given key
|
# Ask redis for a given key
|
||||||
|
|
||||||
def fromKey(keyname):
|
def fromKey(keyname):
|
||||||
|
|
||||||
return r.get(keyname)
|
return r.get(keyname)
|
||||||
|
|
||||||
#
|
|
||||||
# Write to redis key
|
# Write to redis key
|
||||||
def toKey(keyname,keyvalue):
|
def toKey(keyname,keyvalue):
|
||||||
#print(keyname,keyvalue)
|
#print(keyname,keyvalue)
|
||||||
# Store encoded data in Redis
|
# Store encoded data in Redis
|
||||||
return r.set(keyname,keyvalue)
|
return r.set(keyname,keyvalue)
|
||||||
|
|
||||||
|
# Publish to redis key
|
||||||
def toKeyevent(eventname):
|
def toKeyevent(eventname):
|
||||||
|
|
||||||
print("redis midi event key :", eventname)
|
print("redis midi event key :", eventname)
|
||||||
@ -281,8 +280,6 @@ def cc(midichannel, ccnumber, value, mididest):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# MIDI Startup and handling
|
# MIDI Startup and handling
|
||||||
#
|
#
|
||||||
@ -313,7 +310,6 @@ def MidinProcess(inqueue, portname):
|
|||||||
#print("")
|
#print("")
|
||||||
#print("Generic from", portname,"msg : ", msg)
|
#print("Generic from", portname,"msg : ", msg)
|
||||||
|
|
||||||
|
|
||||||
# NOTE ON message on all midi channels
|
# NOTE ON message on all midi channels
|
||||||
if NOTE_ON -1 < msg[0] < 160 and msg[2] !=0 :
|
if NOTE_ON -1 < msg[0] < 160 and msg[2] !=0 :
|
||||||
|
|
||||||
@ -329,10 +325,22 @@ def MidinProcess(inqueue, portname):
|
|||||||
|
|
||||||
NoteOn(MidiNote, MidiVel, "pads" , midichannel=MidiChannel)
|
NoteOn(MidiNote, MidiVel, "pads" , midichannel=MidiChannel)
|
||||||
|
|
||||||
|
for param in conf['params']:
|
||||||
|
|
||||||
|
islj2 = param["name"].find('lasernumber')
|
||||||
|
if param["type"] == 0 and param["note"] == msg[1] and islj2 != -1:
|
||||||
|
|
||||||
|
# LJ2 parameter : replace lasernumber with channel number
|
||||||
|
tolj = param["name"].replace('lasernumber',str(MidiChannel))
|
||||||
|
print("LJ2 button :", tolj, ["1"])
|
||||||
|
SendOSC(tolj, ['1'])
|
||||||
|
|
||||||
|
|
||||||
# OSC : /midi/noteon midichannel note velocity
|
# OSC : /midi/noteon midichannel note velocity
|
||||||
SendOSC("/midi/noteon",[MidiChannel, msg[1], msg[2]])
|
SendOSC("/midi/noteon",[MidiChannel, msg[1], msg[2]])
|
||||||
print("osc :","/midi/noteon/",[MidiChannel, msg[1], msg[2]])
|
print("osc :","/midi/noteon/",[MidiChannel, msg[1], msg[2]])
|
||||||
toKeyevent("/midi/noteon/"+str(MidiChannel)+"/"+str(MidiNote)+"/"+str(MidiVel))
|
toKeyevent("/midi/noteon/"+str(MidiChannel)+"/"+str(MidiNote)+"/"+str(MidiVel))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# Sampler mode : note <63 launch snare.wav / note > 62 kick.wav
|
# Sampler mode : note <63 launch snare.wav / note > 62 kick.wav
|
||||||
if MidiNote < 63 and MidiVel >0:
|
if MidiNote < 63 and MidiVel >0:
|
||||||
@ -360,6 +368,7 @@ def MidinProcess(inqueue, portname):
|
|||||||
else:
|
else:
|
||||||
MidiChannel = msg[0]-128
|
MidiChannel = msg[0]-128
|
||||||
MidiNote = msg[1]
|
MidiNote = msg[1]
|
||||||
|
print()
|
||||||
print("NOTE_off channel :", MidiChannel, "note :", MidiNote)
|
print("NOTE_off channel :", MidiChannel, "note :", MidiNote)
|
||||||
NoteOff(MidiNote, "pads" , midichannel=MidiChannel)
|
NoteOff(MidiNote, "pads" , midichannel=MidiChannel)
|
||||||
|
|
||||||
@ -376,10 +385,10 @@ def MidinProcess(inqueue, portname):
|
|||||||
if CONTROLLER_CHANGE -1 < msg[0] < 192:
|
if CONTROLLER_CHANGE -1 < msg[0] < 192:
|
||||||
|
|
||||||
MidiChannel = msg[0]-175
|
MidiChannel = msg[0]-175
|
||||||
|
print()
|
||||||
cc(MidiChannel, msg[1], msg[2], "pads" )
|
cc(MidiChannel, msg[1], msg[2], "pads" )
|
||||||
#print("channel", MidiChannel, "CC :", msg[1], msg[2])
|
#print("channel", MidiChannel, "CC :", msg[1], msg[2])
|
||||||
print("CC channel : "+str(msg[0]-175-1)+" CC :"+str(msg[1])+" value : "+str(msg[2]))
|
print("CC : channel : "+str(msg[0]-175-1)+" CC : "+str(msg[1])+" value : "+str(msg[2]))
|
||||||
toKeyevent("/midi/cc/"+str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
toKeyevent("/midi/cc/"+str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
|
||||||
# redis key : "/midi/cc/midichannel/ccnumber" value : "ccvalue"
|
# redis key : "/midi/cc/midichannel/ccnumber" value : "ccvalue"
|
||||||
@ -393,11 +402,111 @@ def MidinProcess(inqueue, portname):
|
|||||||
|
|
||||||
for param in conf['params']:
|
for param in conf['params']:
|
||||||
|
|
||||||
if MidiChannel == param["chanIN"] and param["CC"] == msg[1]:
|
#print()
|
||||||
#print(param["name"]+"/"+ str(msg[1])+"/"+str(msg[2]))
|
#print('custom action',param["name"], param)
|
||||||
SendOSC(param["name"],[msg[0]-175-1, msg[1], msg[2]])
|
# print('type', param["type"] )
|
||||||
toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
islj2 = param["name"].find('lasernumber')
|
||||||
toKey(param["name"],str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
# print('lasernumber position', islj2)
|
||||||
|
|
||||||
|
|
||||||
|
# 0-127 parameter
|
||||||
|
if param["type"] == 7:
|
||||||
|
|
||||||
|
# LJ2 parameter : replace lasernumber with channel number - 1
|
||||||
|
if islj2 != -1:
|
||||||
|
|
||||||
|
if param["CC"] == msg[1]:
|
||||||
|
|
||||||
|
print('lj2 7 bits custom action')
|
||||||
|
tolj = param["name"].replace('lasernumber',str(MidiChannel-1))
|
||||||
|
SendOSC(tolj, [midifactor(ccnumber = msg[1], channel = MidiChannel, low =param["low"], high=param["high"], default =1)])
|
||||||
|
|
||||||
|
print('tolj', tolj, midifactor(ccnumber = msg[1], channel = MidiChannel, low =param["low"], high=param["high"], default =1) )
|
||||||
|
#toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
#toKey(param["name"], str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
#tolj = param["name"].replace('lasernumber',str(MidiChannel))
|
||||||
|
#print("LJ2 cc :", tolj, ["1"])
|
||||||
|
#SendOSC(tolj, ['1'])
|
||||||
|
|
||||||
|
# Not LJ2
|
||||||
|
elif MidiChannel == param["chanIN"] and param["CC"] == msg[1]:
|
||||||
|
#print(param["name"]+"/"+ str(msg[1])+"/"+str(msg[2]))
|
||||||
|
SendOSC(param["name"], [msg[0]-175-1, msg[1], msg[2]])
|
||||||
|
toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
toKey(param["name"], str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
|
||||||
|
|
||||||
|
# convert 7 bits midi cc to 8 bits and send to "name"
|
||||||
|
if param["type"] == 8:
|
||||||
|
|
||||||
|
# LJ2 parameter : replace lasernumber with channel number - 1
|
||||||
|
if islj2 != -1:
|
||||||
|
|
||||||
|
if param["CC"] == msg[1]:
|
||||||
|
print('lj2 8 bits custom action')
|
||||||
|
tolj = param["name"].replace('lasernumber',str(MidiChannel-1))
|
||||||
|
SendOSC(tolj, [msg[2]*2])
|
||||||
|
print('tolj', tolj, msg[2]*2 )
|
||||||
|
#toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
#toKey(param["name"], str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
|
||||||
|
# Not LJ2
|
||||||
|
elif MidiChannel == param["chanIN"] and param["CC"] == msg[1]:
|
||||||
|
SendOSC(param["name"], [msg[0]-175-1, msg[1], msg[2]*2])
|
||||||
|
toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
toKey(param["name"], str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
|
||||||
|
|
||||||
|
# reranged 2 cc -> 14 bits parameters
|
||||||
|
if param["type"] == 14:
|
||||||
|
|
||||||
|
# LJ2 parameter : replace lasernumber with channel number - 1
|
||||||
|
if islj2 != -1:
|
||||||
|
if param["lowCC"] == msg[1] or param["highCC"] == msg[1]:
|
||||||
|
|
||||||
|
print('lj2 14 bits reranged custom action')
|
||||||
|
tolj = param["name"].replace('lasernumber',str(MidiChannel-1))
|
||||||
|
print('highcc',str(param["highCC"]),r.get("/midi/cc/"+str(MidiChannel)+"/"+str(param["highCC"])))
|
||||||
|
print('lowcc',str(param["lowCC"]),r.get("/midi/cc/"+str(MidiChannel)+"/"+str(param["lowCC"])))
|
||||||
|
|
||||||
|
SendOSC(tolj, [str(int(midifactor14(highcc=param["highCC"], lowcc=param["lowCC"], channel=MidiChannel, low=param["low"], high=param["high"], default=param["default"])))])
|
||||||
|
print('tolj', tolj, int(midifactor14(highcc=param["highCC"], lowcc=param["lowCC"], channel=MidiChannel, low=param["low"], high=param["high"], default=param["default"])) )
|
||||||
|
#toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
#toKey(param["name"], str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]*2))
|
||||||
|
|
||||||
|
# Not LJ2
|
||||||
|
elif MidiChannel == param["chanIN"] and (param["lowCC"] == msg[1] or param["highCC"] == msg[1]):
|
||||||
|
#print(param["name"]+"/"+ str(msg[1])+"/"+str(msg[2]))
|
||||||
|
|
||||||
|
highcc = r.get("/midi/cc/"+str(MidiChannel)+"/"+str(msg[1]))
|
||||||
|
print('highcc',highcc)
|
||||||
|
midifactor14(highcc, lowcc, ccnumber, channel, param["low"], param["high"], default)
|
||||||
|
|
||||||
|
SendOSC(param["name"], [msg[0]-175-1, msg[1], msg[2]])
|
||||||
|
toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
toKey(param["name"],str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
|
||||||
|
|
||||||
|
# 14 bits parameters with one CC
|
||||||
|
if param["type"] == 140:
|
||||||
|
|
||||||
|
# LJ2 parameter : replace lasernumber with channel number - 1
|
||||||
|
if islj2 != -1:
|
||||||
|
if param["CC"] == msg[1]:
|
||||||
|
print('lj2 140 bits custom action')
|
||||||
|
tolj = param["name"].replace('lasernumber',str(MidiChannel-1))
|
||||||
|
print('no program here')
|
||||||
|
|
||||||
|
# Not LJ2
|
||||||
|
elif MidiChannel == param["chanIN"] and param["CC"] == msg[1]:
|
||||||
|
#print(param["name"]+"/"+ str(msg[1])+"/"+str(msg[2]))
|
||||||
|
SendOSC(param["name"], [msg[0]-175-1, msg[1], msg[2]])
|
||||||
|
toKeyevent(param["name"]+"/"+ str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
toKey(param["name"], str(MidiChannel)+"/"+str(msg[1])+"/"+str(msg[2]))
|
||||||
|
|
||||||
|
midifactor140(ccnumber, channel=MidiChannel, low=param["low"], high=param["high"], default = param["default"])
|
||||||
|
#midifactor14(highcc, lowcc, channel = cchannel, low =0, high=16383, default =1)
|
||||||
|
|
||||||
|
|
||||||
if msg[0] == TIMING_CLOCK:
|
if msg[0] == TIMING_CLOCK:
|
||||||
now = time.time()
|
now = time.time()
|
||||||
@ -427,6 +536,7 @@ def MidinProcess(inqueue, portname):
|
|||||||
|
|
||||||
if msg[0] in (SONG_CONTINUE, SONG_START):
|
if msg[0] in (SONG_CONTINUE, SONG_START):
|
||||||
running = True
|
running = True
|
||||||
|
|
||||||
#print("START/CONTINUE received.")
|
#print("START/CONTINUE received.")
|
||||||
#print("Midi in process send /aurora/start")
|
#print("Midi in process send /aurora/start")
|
||||||
|
|
||||||
@ -443,7 +553,27 @@ def MidinProcess(inqueue, portname):
|
|||||||
# OSC : /midi/start
|
# OSC : /midi/start
|
||||||
SendOSC("/midi/stop",[])
|
SendOSC("/midi/stop",[])
|
||||||
print("osc : /midi/stop")
|
print("osc : /midi/stop")
|
||||||
print()
|
|
||||||
|
|
||||||
|
if msg[0] == SYSTEM_EXCLUSIVE:
|
||||||
|
print('sysex', msg)
|
||||||
|
# check to see if this is a timecode frame
|
||||||
|
if len(msg) == 8 and msg[0:4] == [127,127,1,1]:
|
||||||
|
data = message.data[4:]
|
||||||
|
tc = tools.mtc_decode(data)
|
||||||
|
print('FF:',tc)
|
||||||
|
|
||||||
|
|
||||||
|
# https://en.wikipedia.org/wiki/MIDI_timecode
|
||||||
|
if msg[0] == MIDI_TIME_CODE:
|
||||||
|
frame_type = (msg[1] >> 4) & 0xF
|
||||||
|
quarter_frames[frame_type] = msg[1] & 15
|
||||||
|
if frame_type == 7:
|
||||||
|
tc = tools.mtc_decode_quarter_frames(quarter_frames)
|
||||||
|
print('QF:',tc)
|
||||||
|
SendTCview("/MIDIQF",[str(tc)])
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# other midi message
|
# other midi message
|
||||||
if msg[0] != NOTE_OFF and msg[0] != NOTE_ON and msg[0] != CONTROLLER_CHANGE:
|
if msg[0] != NOTE_OFF and msg[0] != NOTE_ON and msg[0] != CONTROLLER_CHANGE:
|
||||||
@ -821,6 +951,59 @@ def NoteOn(note, velocity, mididest):
|
|||||||
if midiname[port].find(mididest) == 0:
|
if midiname[port].find(mididest) == 0:
|
||||||
midiport[port].send_message([NOTE_ON, note, velocity])
|
midiport[port].send_message([NOTE_ON, note, velocity])
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
# 1 CC -> 7 bits number : 0-127
|
||||||
|
# rerange end value between low high
|
||||||
|
# midifactor(ccnumber, channel, low, high, default)
|
||||||
|
def midifactor(ccnumber, channel = 0, low =0, high=127, default =1):
|
||||||
|
|
||||||
|
ccvalue = r.get('/midi/cc/'+str(channel)+'/'+str(ccnumber))
|
||||||
|
|
||||||
|
if ccvalue is not None:
|
||||||
|
return rerange(int(ccvalue), 0, 127, low, high)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('Default value returned. No midi value in redis for channel', channel, 'CC', ccnumber)
|
||||||
|
return default
|
||||||
|
|
||||||
|
# 2 CC -> 14 bits number : 0 - 16383
|
||||||
|
# rerange end value between low high
|
||||||
|
# midifactor14(highcc, lowcc, ccnumber, channel, low, high, default)
|
||||||
|
def midifactor14(highcc, lowcc, channel = 0, low =0, high=16383, default =1):
|
||||||
|
|
||||||
|
lowvalue = r.get('/midi/cc/'+str(channel)+'/'+str(lowcc))
|
||||||
|
highvalue = r.get('/midi/cc/'+str(channel)+'/'+str(highcc))
|
||||||
|
|
||||||
|
if lowvalue is not None and highcc is not None:
|
||||||
|
return rerange((int(highvalue) << 7)+ int(lowvalue), 0, 16383, low, high)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('Default value returned. No midi value in redis for channel', channel, 'CCs', highvalue, lowvalue)
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
# 1 CC -> 14 bits number : 0 - 16383
|
||||||
|
# rerange end value between low high
|
||||||
|
# set low cc (=Byte) to 0
|
||||||
|
# midifactor140(ccnumber, channel, low, high, default)
|
||||||
|
def midifactor140(highcc, channel = 0, low =0, high=16383, default =1):
|
||||||
|
|
||||||
|
highvalue = r.get('/midi/cc/'+str(channel)+'/'+str(highcc))
|
||||||
|
|
||||||
|
if highcc is not None:
|
||||||
|
return rerange((int(highvalue) << 7), 0, 16383, low, high)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('Default value returned. No midi value in redis for channel', channel, 'CC', ccnumber)
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def rerange(s,a1,a2,b1,b2):
|
||||||
|
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# launchpad
|
# launchpad
|
||||||
#
|
#
|
||||||
@ -1026,10 +1209,10 @@ def loadConf():
|
|||||||
f = open(ConFile,"r")
|
f = open(ConFile,"r")
|
||||||
s = f.read()
|
s = f.read()
|
||||||
conf = json.loads(s)
|
conf = json.loads(s)
|
||||||
print("params", len(conf['params']))
|
print(len(conf['params']), "custom actions")
|
||||||
nbparam = len(conf['params'])
|
nbparam = len(conf['params'])
|
||||||
|
|
||||||
print(conf)
|
#print(conf)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("_loadPlaylist error when loading '{}':{}".format(ConFile,e))
|
print("_loadPlaylist error when loading '{}':{}".format(ConFile,e))
|
||||||
@ -1040,4 +1223,45 @@ def check():
|
|||||||
InConfig()
|
InConfig()
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
from rtmidi.midiconstants import (CONTROL_CHANGE, DATA_DECREMENT,
|
||||||
|
DATA_ENTRY_LSB, DATA_ENTRY_MSB,
|
||||||
|
DATA_INCREMENT, RPN_LSB, RPN_MSB)
|
||||||
|
from rtmidi.midiutil import open_midiinput
|
||||||
|
|
||||||
|
|
||||||
|
class RPNDecoder:
|
||||||
|
def __init__(self, channel=1):
|
||||||
|
self.channel = (channel - 1) & 0xF
|
||||||
|
self.rpn = 0
|
||||||
|
self.values = defaultdict(int)
|
||||||
|
self.last_changed = None
|
||||||
|
|
||||||
|
def __call__(self, event, data=None):
|
||||||
|
msg, deltatime = event
|
||||||
|
|
||||||
|
# event type = upper four bits of first byte
|
||||||
|
if msg[0] == (CONTROL_CHANGE | self.channel):
|
||||||
|
cc, value = msg[1], msg[2]
|
||||||
|
|
||||||
|
if cc == RPN_LSB:
|
||||||
|
self.rpn = (self.rpn >> 7) * 128 + value
|
||||||
|
elif cc == RPN_MSB:
|
||||||
|
self.rpn = value * 128 + (self.rpn & 0x7F)
|
||||||
|
elif cc == DATA_INCREMENT:
|
||||||
|
self.set_rpn(self.rpn, min(2 ** 14, self.values[self.rpn] + 1))
|
||||||
|
elif cc == DATA_DECREMENT:
|
||||||
|
self.set_rpn(self.rpn, max(0, self.values[self.rpn] - 1))
|
||||||
|
elif cc == DATA_ENTRY_LSB:
|
||||||
|
self.set_rpn(self.rpn,
|
||||||
|
(self.values[self.rpn] >> 7) * 128 + value)
|
||||||
|
elif cc == DATA_ENTRY_MSB:
|
||||||
|
self.set_rpn(self.rpn,
|
||||||
|
value * 128 + (self.values[self.rpn] & 0x7F))
|
||||||
|
|
||||||
|
def set_rpn(self, rpn, value):
|
||||||
|
self.values[rpn] = value
|
||||||
|
self.last_changed = rpn
|
||||||
|
|
||||||
|
'''
|
||||||
|
194
libs/tools.py
Executable file
194
libs/tools.py
Executable file
@ -0,0 +1,194 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from timecode import Timecode
|
||||||
|
|
||||||
|
def bitstring_to_bytes(s, bytecount=1, byteorder='big'):
|
||||||
|
return int(s, 2).to_bytes(bytecount, byteorder)
|
||||||
|
|
||||||
|
# binary big-endian
|
||||||
|
def bbe(n, bits=8):
|
||||||
|
# terminal condition
|
||||||
|
retval = ''
|
||||||
|
if n == 0:
|
||||||
|
retval = '0'
|
||||||
|
else:
|
||||||
|
retval = bbe(n//2, None) + str(n%2)
|
||||||
|
if bits is None:
|
||||||
|
return retval
|
||||||
|
else:
|
||||||
|
return (('0'*bits) + retval)[-bits:]
|
||||||
|
|
||||||
|
|
||||||
|
# binary, little-endian
|
||||||
|
def ble(n, bits=8):
|
||||||
|
# terminal condition
|
||||||
|
retval = ''
|
||||||
|
if n == 0:
|
||||||
|
retval = '0'
|
||||||
|
else:
|
||||||
|
retval = str(n%2) + ble(n//2, None)
|
||||||
|
if bits is None:
|
||||||
|
return retval
|
||||||
|
else:
|
||||||
|
return (retval + ('0'*bits))[0:bits]
|
||||||
|
|
||||||
|
def cint(n, bytecount=2):
|
||||||
|
return int(n).to_bytes(bytecount, byteorder='little')
|
||||||
|
|
||||||
|
def units_tens(n):
|
||||||
|
return n % 10, int(n/10)
|
||||||
|
|
||||||
|
##
|
||||||
|
## LTC functions
|
||||||
|
##
|
||||||
|
# GENERATE BINARY-CODED DATA FOR LTC
|
||||||
|
# ACCORDING TO https://en.wikipedia.org/wiki/Linear_timecode
|
||||||
|
# everything is encoded little endian
|
||||||
|
# so to encode the number 3 with four bits, we have 1100
|
||||||
|
def ltc_encode(timecode, as_string=False):
|
||||||
|
LTC = ''
|
||||||
|
HLP = ''
|
||||||
|
hrs, mins, secs, frs = timecode.frames_to_tc(timecode.frames)
|
||||||
|
frame_units, frame_tens = units_tens(frs)
|
||||||
|
secs_units, secs_tens = units_tens(secs)
|
||||||
|
mins_units, mins_tens = units_tens(mins)
|
||||||
|
hrs_units, hrs_tens = units_tens(hrs)
|
||||||
|
|
||||||
|
#frames units / user bits field 1 / frames tens
|
||||||
|
LTC += ble(frame_units,4) + '0000' + ble(frame_tens,2)
|
||||||
|
HLP += '---{u}____-{t}'.format(u=frame_units, t=frame_tens)
|
||||||
|
|
||||||
|
#drop frame / color frame / user bits field 2
|
||||||
|
LTC += '00'+'0000'
|
||||||
|
HLP += '__'+'____'
|
||||||
|
|
||||||
|
#secs units / user bits field 3 / secs tens
|
||||||
|
LTC += ble(secs_units,4) + '0000' + ble(secs_tens,3)
|
||||||
|
HLP += '---{u}____--{t}'.format(u=secs_units, t=secs_tens)
|
||||||
|
|
||||||
|
# bit 27 flag / user bits field 4
|
||||||
|
LTC += '0' + '0000'
|
||||||
|
HLP += '_' + '____'
|
||||||
|
|
||||||
|
#mins units / user bits field 5 / mins tens
|
||||||
|
LTC += ble(mins_units,4) + '0000' + ble(mins_tens,3)
|
||||||
|
HLP += '---{u}____--{t}'.format(u=mins_units, t=mins_tens)
|
||||||
|
|
||||||
|
# bit 43 flag / user bits field 6
|
||||||
|
LTC += '0' + '0000'
|
||||||
|
HLP += '_' + '____'
|
||||||
|
|
||||||
|
#hrs units / user bits field 7 / hrs tens
|
||||||
|
LTC += ble(hrs_units,4) + '0000' + ble(hrs_tens,2)
|
||||||
|
HLP += '---{u}____--{t}'.format(u=hrs_units, t=hrs_tens)
|
||||||
|
|
||||||
|
# bit 58 clock flag / bit 59 flag / user bits field 8
|
||||||
|
LTC += '0' + '0' + '0000'
|
||||||
|
HLP += '_' + '_' + '____'
|
||||||
|
|
||||||
|
# sync word
|
||||||
|
LTC += '0011111111111101'
|
||||||
|
HLP += '################'
|
||||||
|
if as_string:
|
||||||
|
return LTC
|
||||||
|
else:
|
||||||
|
return bitstring_to_bytes(LTC, bytecount=10)
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## MTC functions
|
||||||
|
##
|
||||||
|
def mtc_encode(timecode, as_string=False):
|
||||||
|
# MIDI bytes are little-endian
|
||||||
|
# Byte 0
|
||||||
|
# 0rrhhhhh: Rate (0–3) and hour (0–23).
|
||||||
|
# rr = 000: 24 frames/s
|
||||||
|
# rr = 001: 25 frames/s
|
||||||
|
# rr = 010: 29.97 frames/s (SMPTE drop-frame timecode)
|
||||||
|
# rr = 011: 30 frames/s
|
||||||
|
# Byte 1
|
||||||
|
# 00mmmmmm: Minute (0–59)
|
||||||
|
# Byte 2
|
||||||
|
# 00ssssss: Second (0–59)
|
||||||
|
# Byte 3
|
||||||
|
# 000fffff: Frame (0–29, or less at lower frame rates)
|
||||||
|
hrs, mins, secs, frs = timecode.frames_to_tc(timecode.frames)
|
||||||
|
framerate = timecode.framerate
|
||||||
|
rateflags = {
|
||||||
|
'24': 0,
|
||||||
|
'25': 1,
|
||||||
|
'29.97': 2,
|
||||||
|
'30': 3
|
||||||
|
}
|
||||||
|
rateflag = rateflags[framerate] * 32 # multiply by 32, because the rate flag starts at bit 6
|
||||||
|
|
||||||
|
# print('{:8} {:8} {:8} {:8}'.format(hrs, mins, secs, frs))
|
||||||
|
if as_string:
|
||||||
|
b0 = bbe(rateflag + hrs, 8)
|
||||||
|
b1 = bbe(mins)
|
||||||
|
b2 = bbe(secs)
|
||||||
|
b3 = bbe(frs)
|
||||||
|
# print('{:8} {:8} {:8} {:8}'.format(b0, b1, b2, b3))
|
||||||
|
return b0+b1+b2+b3
|
||||||
|
else:
|
||||||
|
b = bytearray([rateflag + hrs, mins, secs, frs])
|
||||||
|
# debug_string = ' 0x{:02} 0x{:02} 0x{:02} 0x{:02}'
|
||||||
|
# debug_array = [ord(b[0]), ord(b[1]), ord(b[2]), ord(b[3])]
|
||||||
|
# print(debug_string.format(debug_array))
|
||||||
|
return b
|
||||||
|
|
||||||
|
# convert a bytearray back to timecode
|
||||||
|
def mtc_decode(mtc_bytes):
|
||||||
|
rhh, mins, secs, frs = mtc_bytes
|
||||||
|
rateflag = rhh >> 5
|
||||||
|
hrs = rhh & 31
|
||||||
|
fps = ['24','25','29.97','30'][rateflag]
|
||||||
|
total_frames = int(frs + float(fps) * (secs + mins * 60 + hrs * 60 * 60))
|
||||||
|
return Timecode(fps, frames=total_frames)
|
||||||
|
|
||||||
|
def mtc_full_frame(timecode):
|
||||||
|
# if sending this to a MIDI device, remember that MIDI is generally little endian
|
||||||
|
# but the full frame timecode bytes are big endian
|
||||||
|
mtc_bytes = mtc_encode(timecode)
|
||||||
|
# mtc full frame has a special header and ignores the rate flag
|
||||||
|
return bytearray([0xf0, 0x7f, 0x7f, 0x01, 0x01]) + mtc_bytes + bytearray([0xf7])
|
||||||
|
|
||||||
|
def mtc_decode_full_frame(full_frame_bytes):
|
||||||
|
mtc_bytes = full_frame_bytes[5:-1]
|
||||||
|
return mtc_decode(mtc_bytes)
|
||||||
|
|
||||||
|
def mtc_quarter_frame(timecode, piece=0):
|
||||||
|
# there are 8 different mtc_quarter frame pieces
|
||||||
|
# see https://en.wikipedia.org/wiki/MIDI_timecode
|
||||||
|
# and https://web.archive.org/web/20120212181214/http://home.roadrunner.com/~jgglatt/tech/mtc.htm
|
||||||
|
# these are little-endian bytes
|
||||||
|
# piece 0 : 0xF1 0000 ffff frame
|
||||||
|
mtc_bytes = mtc_encode(timecode)
|
||||||
|
this_byte = mtc_bytes[3 - piece//2] #the order of pieces is the reverse of the mtc_encode
|
||||||
|
if piece % 2 == 0:
|
||||||
|
# even pieces get the low nibble
|
||||||
|
nibble = this_byte & 15
|
||||||
|
else:
|
||||||
|
# odd pieces get the high nibble
|
||||||
|
nibble = this_byte >> 4
|
||||||
|
return bytearray([0xf1, piece * 16 + nibble])
|
||||||
|
|
||||||
|
def mtc_decode_quarter_frames(frame_pieces):
|
||||||
|
mtc_bytes = bytearray(4)
|
||||||
|
if len(frame_pieces) < 8:
|
||||||
|
return None
|
||||||
|
for piece in range(8):
|
||||||
|
mtc_index = 3 - piece//2 # quarter frame pieces are in reverse order of mtc_encode
|
||||||
|
this_frame = frame_pieces[piece]
|
||||||
|
if this_frame is bytearray or this_frame is list:
|
||||||
|
this_frame = this_frame[1]
|
||||||
|
data = this_frame & 15 # ignore the frame_piece marker bits
|
||||||
|
if piece % 2 == 0:
|
||||||
|
# 'even' pieces came from the low nibble
|
||||||
|
# and the first piece is 0, so it's even
|
||||||
|
mtc_bytes[mtc_index] += data
|
||||||
|
else:
|
||||||
|
# 'odd' pieces came from the high nibble
|
||||||
|
mtc_bytes[mtc_index] += data * 16
|
||||||
|
return mtc_decode(mtc_bytes)
|
||||||
|
|
||||||
|
|
114
miredis.json
114
miredis.json
@ -1,27 +1,123 @@
|
|||||||
{
|
{"params": [
|
||||||
"params": [
|
|
||||||
{
|
{
|
||||||
"_comment": "normalized named CC for filters",
|
"_comment": "normalized named CC for filters",
|
||||||
"name": "/velocity",
|
"name": "/velocity",
|
||||||
|
"type": 7,
|
||||||
"chanIN" : 1,
|
"chanIN" : 1,
|
||||||
"CC" : 1
|
"CC" : 30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "/strength",
|
"name": "/strength",
|
||||||
|
"type": 7,
|
||||||
"chanIN" : 1,
|
"chanIN" : 1,
|
||||||
"CC" : 3
|
"CC" : 31
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "/decay",
|
"name": "/decay",
|
||||||
|
"type": 7,
|
||||||
"chanIN" : 1,
|
"chanIN" : 1,
|
||||||
"CC" : 5
|
"CC" : 32
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "/feedback ",
|
"name": "/feedback",
|
||||||
|
"type": 7,
|
||||||
"chanIN" : 1,
|
"chanIN" : 1,
|
||||||
"CC" : 114
|
"CC" : 34
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"_comment": "LJ settings for Beatstep",
|
||||||
|
"name": "/grid/lasernumber",
|
||||||
|
"type": 0,
|
||||||
|
"note" : 33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/black/lasernumber",
|
||||||
|
"type": 0,
|
||||||
|
"note" : 35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/swap/X/lasernumber",
|
||||||
|
"type": 0,
|
||||||
|
"note" : 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/swap/Y/lasernumber",
|
||||||
|
"type": 0,
|
||||||
|
"note" : 26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/kpps/lasernumber",
|
||||||
|
"type": 14,
|
||||||
|
"highCC" : 0,
|
||||||
|
"lowCC" : 1,
|
||||||
|
"low": 0,
|
||||||
|
"high": 70000,
|
||||||
|
"default": 20000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/angle/lasernumber",
|
||||||
|
"type": 14,
|
||||||
|
"highCC" : 2,
|
||||||
|
"lowCC" : 3,
|
||||||
|
"low": 0,
|
||||||
|
"high": 360,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/scale/X/lasernumber",
|
||||||
|
"type": 7,
|
||||||
|
"CC" : 4,
|
||||||
|
"low": 0,
|
||||||
|
"high": 200,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/scale/Y/lasernumber",
|
||||||
|
"type": 7,
|
||||||
|
"CC" : 5,
|
||||||
|
"low": 0,
|
||||||
|
"high": 200,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/red/lasernumber",
|
||||||
|
"type": 8,
|
||||||
|
"CC" : 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/green/lasernumber",
|
||||||
|
"type": 8,
|
||||||
|
"CC" : 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/blue/lasernumber",
|
||||||
|
"type": 8,
|
||||||
|
"CC" : 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/intens/lasernumber",
|
||||||
|
"type": 8,
|
||||||
|
"CC" : 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/loffset/X/lasernumber",
|
||||||
|
"type": 14,
|
||||||
|
"highCC" : 12,
|
||||||
|
"lowCC" : 13,
|
||||||
|
"low": -27000,
|
||||||
|
"high": 27000,
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "/loffset/Y/lasernumber",
|
||||||
|
"type": 14,
|
||||||
|
"highCC" : 14,
|
||||||
|
"lowCC" : 15,
|
||||||
|
"low": -27000,
|
||||||
|
"high": 27000,
|
||||||
|
"default": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
miredis.py
20
miredis.py
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
miredis
|
miredis
|
||||||
v0.1
|
v0.2
|
||||||
|
|
||||||
Forward midi events to OSC and redis.
|
Forward midi events to OSC and redis.
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ from ProtonPhoton
|
|||||||
from libs import log
|
from libs import log
|
||||||
|
|
||||||
print()
|
print()
|
||||||
log.infog('Miredis v0.1')
|
log.infog('Miredis v0.2')
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import redis
|
import redis
|
||||||
@ -38,11 +38,11 @@ argsparser = argparse.ArgumentParser(description="Miredis")
|
|||||||
# General Args
|
# General Args
|
||||||
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose")
|
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose")
|
||||||
# Redis Args
|
# Redis Args
|
||||||
argsparser.add_argument("-i","--ip",help="IP address of the Redis server ",default="127.0.0.1",type=str)
|
argsparser.add_argument("-i","--ip",help="Redis server IP address to forward midi events.",default="127.0.0.1",type=str)
|
||||||
argsparser.add_argument("-p","--port",help="Port of the Redis server ",default="6379",type=str)
|
argsparser.add_argument("-p","--port",help="Redis server port number",default="6379",type=str)
|
||||||
# OSC Args
|
# OSC Args
|
||||||
argsparser.add_argument("-o","--oscip",help="IP address of the OSC server to forward midi events.",default="127.0.0.1",type=str)
|
argsparser.add_argument("-o","--oscip",help="OSC server IP address to forward midi events.",default="127.0.0.1",type=str)
|
||||||
argsparser.add_argument("-q","--oscport",help="Port of the OSC server ",default="9000",type=str)
|
argsparser.add_argument("-q","--oscport",help="OSC server port number",default="9000",type=str)
|
||||||
argsparser.add_argument('-link',help="Enable Ableton Link (disabled by default)", dest='link', action='store_true')
|
argsparser.add_argument('-link',help="Enable Ableton Link (disabled by default)", dest='link', action='store_true')
|
||||||
argsparser.add_argument("-m","--mode",help="Mode choice : simplex, clitools",default="clitools",type=str)
|
argsparser.add_argument("-m","--mode",help="Mode choice : simplex, clitools",default="clitools",type=str)
|
||||||
argsparser.set_defaults(link=False)
|
argsparser.set_defaults(link=False)
|
||||||
@ -55,6 +55,12 @@ midix.oscPORT = int(args.oscport)
|
|||||||
midix.debug = args.verbose
|
midix.debug = args.verbose
|
||||||
midix.mode = args.mode
|
midix.mode = args.mode
|
||||||
|
|
||||||
|
print("Destination OSC server : " +midix.oscIP+ " port "+str(midix.oscPORT))
|
||||||
|
|
||||||
|
r = redis.StrictRedis(host=redisIP , port=redisPORT, db=0)
|
||||||
|
print("Redis server : " +redisIP+ " port "+str(redisPORT))
|
||||||
|
midix.r = r
|
||||||
|
|
||||||
# with Ableton Link
|
# with Ableton Link
|
||||||
if args.link == True:
|
if args.link == True:
|
||||||
from libs import alink
|
from libs import alink
|
||||||
@ -65,8 +71,6 @@ else:
|
|||||||
print("Link DISABLED")
|
print("Link DISABLED")
|
||||||
linked = False
|
linked = False
|
||||||
|
|
||||||
r = redis.StrictRedis(host=redisIP , port=redisPORT, db=0)
|
|
||||||
midix.r = r
|
|
||||||
|
|
||||||
|
|
||||||
def Osc():
|
def Osc():
|
||||||
|
Loading…
Reference in New Issue
Block a user