Added opensource Ableton Link protocol
This commit is contained in:
parent
e023a5ede6
commit
77afd636e8
11
README.md
11
README.md
@ -1,6 +1,7 @@
|
||||
# Forward Midi events to redis/OSC
|
||||
|
||||
Miredis hooks to all midi devices connected and listen for events.
|
||||
Miredis can optionnaly hook to Link protocol -> "/beats" & "/bpm"
|
||||
All events are forwarded to a redis server and an OSC server.
|
||||
|
||||
Run :
|
||||
@ -20,6 +21,10 @@ python3 miredis.py -h
|
||||
|
||||
"/midi/cc/midichannel/ccnumber" value : "ccvalue"
|
||||
|
||||
"/beats" value : "beatnumber"
|
||||
|
||||
"/bpm" value : "currentbpm"
|
||||
|
||||
## OSC
|
||||
|
||||
/midi/noteon midichannel note velocity
|
||||
@ -32,4 +37,8 @@ python3 miredis.py -h
|
||||
|
||||
/midi/start
|
||||
|
||||
/midi/stop
|
||||
/midi/stop
|
||||
|
||||
/beats beatnumber
|
||||
|
||||
/bpm bpm
|
||||
|
Binary file not shown.
135
libs/alink.py
Normal file
135
libs/alink.py
Normal file
@ -0,0 +1,135 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- mode: Python -*-
|
||||
|
||||
'''
|
||||
|
||||
Ableton Link
|
||||
|
||||
LICENCE : CC
|
||||
Sam Neurohack
|
||||
|
||||
|
||||
Get:
|
||||
|
||||
git clone --recursive https://github.com/gonzaloflirt/link-python.git
|
||||
|
||||
Build:
|
||||
|
||||
Make sure python 3 is installed on your system.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
|
||||
'''
|
||||
from libs import midix
|
||||
import sys
|
||||
|
||||
prevphase = 0
|
||||
bpm = 120
|
||||
|
||||
def Start():
|
||||
global lnk
|
||||
from libs import link
|
||||
|
||||
print("Link ENABLED")
|
||||
lnk = link.Link(120)
|
||||
lnk.enabled = True
|
||||
lnk.startStopSyncEnabled = True
|
||||
linked = True
|
||||
|
||||
def RedOSC(tempo_str, beats_str):
|
||||
|
||||
print()
|
||||
print("Link : BPM " +tempo_str+" Beat "+str(beats_str) + ' \r')
|
||||
#sys.stdout.flush()
|
||||
|
||||
|
||||
# redis key : "/beats" value : currentbeat
|
||||
if midix.toKey('/beats', beats_str)==True:
|
||||
print("redis :", '/beats', beats_str)
|
||||
|
||||
# OSC : /midi/cc midichannel ccnumber value
|
||||
midix.SendOSC('/beats', [beats_str])
|
||||
print("osc :",'/beats', [beats_str])
|
||||
|
||||
# redis key : "/bpm" value : newbpm
|
||||
if midix.toKey('/bpm', bpm)==True:
|
||||
print("redis :", '/bpm', bpm)
|
||||
|
||||
# OSC : /bpm newbpm
|
||||
midix.SendOSC('/bpm', [bpm])
|
||||
print("osc :",'/bpm', [bpm])
|
||||
|
||||
|
||||
def BeatEvent():
|
||||
global lnk, prevphase
|
||||
|
||||
|
||||
lnkstr = lnk.captureSessionState()
|
||||
link_time = lnk.clock().micros();
|
||||
tempo_str = '{0:.2f}'.format(lnkstr.tempo())
|
||||
bpm = float(tempo_str)
|
||||
#beatstep.SendOSCUI('/bpm', [bpm])
|
||||
beats_str = '{0:.2f}'.format(lnkstr.beatAtTime(link_time, 0))
|
||||
playing_str = str(lnkstr.isPlaying()) # always False ???
|
||||
phase = lnkstr.phaseAtTime(link_time, 4)
|
||||
|
||||
|
||||
# new beat ?
|
||||
if int(phase) != prevphase:
|
||||
prevphase = int(phase)
|
||||
|
||||
RedOSC(tempo_str, beats_str)
|
||||
currentbeat = float(beats_str)
|
||||
#midix.SendAU('/aurora/beats', beats_str)
|
||||
#AllStatus("Beat "+str(beats_str))
|
||||
|
||||
|
||||
|
||||
# Change current Link Tempo.
|
||||
def newtempo(tempo):
|
||||
global lnk
|
||||
|
||||
#print("val2", val2, "tempo", tempo)
|
||||
|
||||
if linked == True:
|
||||
lnk.enabled = False
|
||||
lnk.startStopSyncEnabled = False
|
||||
lnk = link.Link(tempo)
|
||||
lnk.enabled = True
|
||||
lnk.startStopSyncEnabled = True
|
||||
bpm = tempo
|
||||
print("New BPM to Link", bpm)
|
||||
RedOSC(str(tempo), "0.0")
|
||||
|
||||
'''
|
||||
# redis key : "/bpm" value : newbpm
|
||||
if midix.toKey('/bpm', bpm)==True:
|
||||
print("redis :", '/bpm', bpm)
|
||||
|
||||
# OSC : /bpm newbpm
|
||||
midix.SendOSC('/bpm', [bpm])
|
||||
print("osc :",'/bpm', [bpm])
|
||||
'''
|
||||
|
||||
else:
|
||||
print("Link is disabled")
|
||||
|
||||
|
||||
# increase or decrease BPM
|
||||
def BPMAdj(val1, keyname):
|
||||
|
||||
|
||||
# + 1
|
||||
if val1 == 1:
|
||||
newtempo(bpm+1)
|
||||
|
||||
# -1
|
||||
if val1 == 127 and bpm > 0:
|
||||
newtempo(bpm-1)
|
||||
|
||||
|
||||
|
BIN
libs/link.cpython-35m-x86_64-linux-gnu.so
Normal file
BIN
libs/link.cpython-35m-x86_64-linux-gnu.so
Normal file
Binary file not shown.
BIN
libs/link.cpython-36m-x86_64-linux-gnu.so
Normal file
BIN
libs/link.cpython-36m-x86_64-linux-gnu.so
Normal file
Binary file not shown.
BIN
libs/link.cpython-37m-darwin.so
Normal file
BIN
libs/link.cpython-37m-darwin.so
Normal file
Binary file not shown.
BIN
libs/link.cpython-38-darwin.so
Executable file
BIN
libs/link.cpython-38-darwin.so
Executable file
Binary file not shown.
BIN
libs/link.so
Executable file
BIN
libs/link.so
Executable file
Binary file not shown.
@ -146,7 +146,18 @@ def SendUI(oscaddress,oscargs=''):
|
||||
log.err('Connection to Aurora UI refused : died ?')
|
||||
pass
|
||||
#time.sleep(0.001
|
||||
# Ask redis for a given key
|
||||
|
||||
def fromKey(keyname):
|
||||
|
||||
return r.get(keyname)
|
||||
|
||||
#
|
||||
# Write to redis key
|
||||
def toKey(keyname,keyvalue):
|
||||
#print(keyname,keyvalue)
|
||||
# Store encoded data in Redis
|
||||
return r.set(keyname,keyvalue)
|
||||
|
||||
def GetTime():
|
||||
return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
|
||||
|
15
miredis.py
15
miredis.py
@ -96,7 +96,8 @@ argsparser.add_argument("-p","--port",help="Port of the Redis server ",default="
|
||||
# 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("-q","--oscport",help="Port of the OSC server ",default="9000",type=str)
|
||||
|
||||
argsparser.add_argument('-link',help="Enable Ableton Link (disabled by default)", dest='link', action='store_true')
|
||||
argsparser.set_defaults(link=False)
|
||||
|
||||
args = argsparser.parse_args()
|
||||
redisIP = args.ip
|
||||
@ -105,7 +106,15 @@ midix.oscIP = args.oscip
|
||||
midix.oscPORT = int(args.oscport)
|
||||
midix.debug = args.verbose
|
||||
|
||||
# with Ableton Link
|
||||
if args.link == True:
|
||||
from libs import alink
|
||||
|
||||
alink.Start()
|
||||
linked = True
|
||||
else:
|
||||
print("Link DISABLED")
|
||||
linked = False
|
||||
|
||||
r = redis.StrictRedis(host=redisIP , port=redisPORT, db=0)
|
||||
midix.r = r
|
||||
@ -122,7 +131,9 @@ if __name__ == '__main__':
|
||||
try:
|
||||
|
||||
while True:
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.001)
|
||||
if linked:
|
||||
alink.BeatEvent()
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
Loading…
Reference in New Issue
Block a user