Added UDP connector for ORCA Livecoding !!
This commit is contained in:
parent
012bef55b1
commit
b79a3487eb
8 changed files with 850 additions and 319 deletions
207
libs/OSCom.py
Normal file
207
libs/OSCom.py
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- mode: Python -*-
|
||||
|
||||
'''
|
||||
OSCcom for jamidi v0.1b
|
||||
|
||||
OSCom.Start(serverIP, OSCPORT)
|
||||
default handler : handler(path, tags, args, source)
|
||||
register particular OSC command in Start(): i.e oscserver.addMsgHandler( "/n", Note)
|
||||
|
||||
'''
|
||||
|
||||
import midi3
|
||||
|
||||
#import socket
|
||||
import types, json
|
||||
from OSC3 import OSCServer, OSCClient, OSCMessage
|
||||
import _thread, time
|
||||
import gstt
|
||||
import WScom, UDPcom
|
||||
import midi3
|
||||
|
||||
#base36 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
|
||||
|
||||
|
||||
def GetTime():
|
||||
return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
|
||||
|
||||
# this method of reporting timeouts only works by convention
|
||||
# that before calling handle_request() field .timed_out is
|
||||
# set to False
|
||||
def handle_timeout(self):
|
||||
self.timed_out = True
|
||||
|
||||
|
||||
def Start(serverIP, OSCPORT):
|
||||
global oscserver
|
||||
|
||||
#print(GetTime(),gstt.oscname, gstt.Confs[gstt.oscname][0]["midichan"])
|
||||
#print(gstt.Confs)
|
||||
#print(gstt.Confs[gstt.oscname])
|
||||
for i in range(len(gstt.Confs[gstt.oscname])):
|
||||
print(GetTime(),gstt.oscname, gstt.Confs[gstt.oscname][i]["midichan"])
|
||||
|
||||
oscserver = OSCServer( (serverIP, OSCPORT) )
|
||||
oscserver.timeout = 0
|
||||
# funny python's way to add a method to an instance of a class
|
||||
import types
|
||||
oscserver.handle_timeout = types.MethodType(handle_timeout, oscserver)
|
||||
|
||||
oscserver.addMsgHandler( "default", handler )
|
||||
oscserver.addMsgHandler( "/n", Note)
|
||||
oscserver.addMsgHandler( "/c", CC)
|
||||
oscserver.addMsgHandler( "/p", PB)
|
||||
_thread.start_new_thread(osc_thread, ())
|
||||
|
||||
|
||||
# RAW OSC Frame available ?
|
||||
def OSCframe():
|
||||
# clear timed_out flag
|
||||
oscserver.timed_out = False
|
||||
# handle all pending requests then return
|
||||
while not oscserver.timed_out:
|
||||
oscserver.handle_request()
|
||||
|
||||
|
||||
|
||||
|
||||
# OSC server Thread : handler, dacs reports and simulator points sender to UI.
|
||||
def osc_thread():
|
||||
|
||||
|
||||
#print("osc Thread launched")
|
||||
try:
|
||||
while True:
|
||||
|
||||
time.sleep(0.005)
|
||||
OSCframe()
|
||||
|
||||
except Exception as e:
|
||||
import sys, traceback
|
||||
print('\n---------------------')
|
||||
print('Exception: %s' % e)
|
||||
print('- - - - - - - - - - -')
|
||||
traceback.print_tb(sys.exc_info()[2])
|
||||
print("\n")
|
||||
|
||||
|
||||
|
||||
|
||||
# Properly close the system. Todo
|
||||
def Stop():
|
||||
oscserver.close()
|
||||
|
||||
|
||||
# default handler
|
||||
def handler(path, tags, args, source):
|
||||
|
||||
oscaddress = ''.join(path.split("/"))
|
||||
print()
|
||||
print("Jamidi Default OSC Handler got from " + str(source[0]),"OSC msg", path, "args", args)
|
||||
#print("OSC address", path)
|
||||
#print("find.. /bhoreal ?", path.find('/bhoreal'))
|
||||
if len(args) > 0:
|
||||
#print("with args", args)
|
||||
pass
|
||||
|
||||
'''
|
||||
# for example
|
||||
if path == '/truc':
|
||||
arg1 = args[0]
|
||||
arg2 = args[1])
|
||||
'''
|
||||
|
||||
'''
|
||||
MIDI NOTES
|
||||
=n in ORCA
|
||||
/n in OSC
|
||||
ORCA OSC
|
||||
=nmonv /n m o n v
|
||||
m : midi channel (0-15 / ORCA 0-F)
|
||||
o : octave (0-8 / ORCA 0-7)
|
||||
n : Note A to G
|
||||
v : velocity 0-Z will output (v/36)*127
|
||||
|
||||
'''
|
||||
def Note(path, tags, args, source):
|
||||
|
||||
#print('Note from ORCA received',args)
|
||||
|
||||
midichannel = int(args[0],36)
|
||||
octave = int(args[1],36)
|
||||
note = args[2]
|
||||
velocity = int((int(args[3],36)/36)*127)
|
||||
|
||||
if note.istitle() == True:
|
||||
notename = str(note)+ str(octave)
|
||||
else:
|
||||
notename = str(note)+ "#"+ str(octave)
|
||||
|
||||
if gstt.debug > 0:
|
||||
print("incoming note", note, octave, notename, midi3.note2midi(notename) )
|
||||
|
||||
for mididevice in midi3.findJamDevices(gstt.oscname):
|
||||
midi3.NoteOn(midi3.note2midi(notename), velocity, mididevice)
|
||||
#midi3.NoteOn(int(wspath[1]), int(wspath[2]), gstt.Confs[wscommand[1]][0]["mididevice"])
|
||||
|
||||
|
||||
'''
|
||||
CC
|
||||
=c in ORCA
|
||||
/c in OSC
|
||||
|
||||
ORCA OSC
|
||||
=cmcd /c m n d
|
||||
m : midi channel
|
||||
n : number (0-35 / ORCA 0-Z)
|
||||
d : data 0-Z will output (d/36)*127
|
||||
'''
|
||||
def CC(path, tags, args, source):
|
||||
|
||||
midichannel = int(args[0],36)
|
||||
ccvr = int(args[1],36)
|
||||
ccvl = int((int(args[2],36)/36)*127)
|
||||
|
||||
if gstt.debug > 0:
|
||||
print("ccvr=%d/ccvl=%d"%(ccvr,ccvl))
|
||||
if gstt.oscname == "ocs2":
|
||||
gstt.crtvalueOCS2[ccvr]=ccvl
|
||||
else:
|
||||
gstt.crtvalueMMO3[ccvr]=ccvl
|
||||
|
||||
for mididevice in midi3.findJamDevices(gstt.oscname):
|
||||
midi3.cc(gstt.Confs[gstt.oscname][0]["midichan"], ccvr, ccvl, mididevice)
|
||||
|
||||
|
||||
|
||||
def PB(path, tags, args, source):
|
||||
|
||||
#print("Pitch number",ccnumber, value)
|
||||
midichannel = int(args[0])
|
||||
ccnumber = int(args[1])
|
||||
ccdata = int(args[3])
|
||||
|
||||
'''
|
||||
# If needed to send some OSC
|
||||
def SendOSC(ip,port,oscaddress,oscargs=''):
|
||||
|
||||
oscmsg = OSCMessage()
|
||||
oscmsg.setAddress(oscaddress)
|
||||
oscmsg.append(oscargs)
|
||||
|
||||
osclient = OSCClient()
|
||||
osclient.connect((ip, port))
|
||||
|
||||
if gstt.debug == True :
|
||||
print("sending OSC message : ", oscmsg, "to", ip, ":", port)
|
||||
|
||||
try:
|
||||
osclient.sendto(oscmsg, (ip, port))
|
||||
oscmsg.clearData()
|
||||
return True
|
||||
except:
|
||||
print ('Connection to', ip, 'refused : died ?')
|
||||
return False
|
||||
'''
|
||||
175
libs/UDPcom.py
Normal file
175
libs/UDPcom.py
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- mode: Python -*-
|
||||
|
||||
'''
|
||||
UDPcom for jamidi v0.1b
|
||||
|
||||
UDPcom.Start(serverIP, UDPORT)
|
||||
Handler : udp_thread()
|
||||
|
||||
Read below for :
|
||||
|
||||
- MIDI NOTES use ;nmonv
|
||||
- MIDI CCs use ;cmnd
|
||||
|
||||
'''
|
||||
|
||||
import midi3
|
||||
|
||||
#import socket
|
||||
import types, json
|
||||
import socket
|
||||
import _thread, time
|
||||
import midi3
|
||||
import WScom, OSCom
|
||||
import gstt
|
||||
import time
|
||||
|
||||
#base36 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
|
||||
|
||||
def GetTime():
|
||||
return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
|
||||
|
||||
def udp_thread():
|
||||
|
||||
while True:
|
||||
payload, client_address = sock.recvfrom(1024)
|
||||
udpath = payload.decode('utf_8')
|
||||
if gstt.debug > 1:
|
||||
print(GetTime(),"UDP got", udpath, "from", str(client_address))
|
||||
#print(udpath[0:1], " ",udpath[1:2], " ",udpath[2:3], " ",udpath[3:4], " " )
|
||||
|
||||
if udpath[0:1] == "n":
|
||||
Note(udpath)
|
||||
|
||||
if udpath[0:1] == "c":
|
||||
CC(udpath)
|
||||
|
||||
if udpath[0:1] == "f":
|
||||
FullCC(udpath)
|
||||
|
||||
time.sleep(0.005)
|
||||
|
||||
|
||||
|
||||
def Start(serverIP, UDPORT):
|
||||
global sock
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
server = ( serverIP,UDPORT)
|
||||
sock.bind(server)
|
||||
_thread.start_new_thread(udp_thread, ())
|
||||
|
||||
|
||||
'''
|
||||
|
||||
MIDI NOTES use ;nmonv
|
||||
|
||||
m : midi channel 0-F (0-15)
|
||||
o : octave 0-8
|
||||
n : Note A-G. For note with # : a-g
|
||||
v : velocity 0-Z will output (v/36)*127
|
||||
|
||||
'''
|
||||
def Note(udpnote):
|
||||
|
||||
if gstt.debug>0:
|
||||
print()
|
||||
print(GetTime(),'UDPNote from ORCA received', udpnote, udpnote[1:1])
|
||||
|
||||
midichannel = int(udpnote[1:2],36)
|
||||
octave = int(udpnote[2:3],36)
|
||||
note = udpnote[3:4]
|
||||
velocity = (int(udpnote[4:5],36)/36)*127
|
||||
|
||||
#if gstt.debug>0:
|
||||
print(GetTime(),'UDPNote from ORCA received:','midichannel:',midichannel,'octave:',octave,'note:',note,'velocity:',velocity)
|
||||
|
||||
|
||||
#if octave < 9 or midichannel < 16 or int(note,36) < 10 or int(note,36) > 16:
|
||||
if octave < 9 and midichannel < 16 and int(note,36) >= 10 and int(note,36) <= 16:
|
||||
|
||||
if note.istitle() == True:
|
||||
notename = str(note.upper())+ str(octave)
|
||||
else:
|
||||
notename = str(note.upper())+ "#"+ str(octave)
|
||||
|
||||
if gstt.debug > 0:
|
||||
print(GetTime(),"Incoming note", notename, "=", midi3.note2midi(notename), "velocity", velocity, "for channel", midichannel)
|
||||
|
||||
|
||||
for mididevice in midi3.findJamDevices(gstt.oscname):
|
||||
midi3.NoteOn(midi3.note2midi(notename), int(velocity), mididevice, midichannel-1)
|
||||
|
||||
# if sending note back to WS users :
|
||||
#WScom.sendWSall("/"+midi3.findJamName(gstt.oscname, midichannel)+"/noteon "+str(midi3.note2midi(notename)))
|
||||
|
||||
else:
|
||||
print(GetTime(),"Note", midichannel, octave, note, velocity,"had offchart parameters.")
|
||||
|
||||
|
||||
'''
|
||||
MIDI CCs base 36 use ;cmnd
|
||||
|
||||
m : midi channel 0-F (0-15)
|
||||
n : number 0-Z (0-35)
|
||||
d : data 0-Z will output (d/36)*127
|
||||
'''
|
||||
def CC(udpcc):
|
||||
|
||||
print()
|
||||
midichannel = int(udpcc[1:2],36)
|
||||
#midichannel = base36.index(udpcc[1:2].upper())
|
||||
ccvr = int(udpcc[2:3],36)
|
||||
ccvl = int((int(udpcc[3:4],36)/36)*127)
|
||||
|
||||
if midichannel < 16:
|
||||
|
||||
if gstt.debug > 0:
|
||||
print(GetTime(),"ccvr=%d/ccvl=%d"%(ccvr,ccvl))
|
||||
|
||||
if gstt.oscname == "ocs2":
|
||||
gstt.crtvalueOCS2[ccvr]=ccvl
|
||||
else:
|
||||
gstt.crtvalueMMO3[ccvr]=ccvl
|
||||
|
||||
for mididevice in midi3.findJamDevices(gstt.oscname):
|
||||
midi3.cc(midichannel, ccvr, ccvl, mididevice)
|
||||
#midi3.cc(gstt.Confs[gstt.oscname][0]["midichan"], ccvr, ccvl, mididevice)
|
||||
WScom.sendWSall("/"+midi3.findJamName(mididevice, midichannel)+"/cc/"+str(ccvr)+" "+str(ccvl))
|
||||
else:
|
||||
print(GetTime(),"Bad midichannel")
|
||||
|
||||
'''
|
||||
MIDI Full CCs all 128 channels and data use ;fmnndd
|
||||
|
||||
m : midi channel 0-F (0-15)
|
||||
nn : number 0-3J (0-127)
|
||||
dd : data 0-3J (0-127)
|
||||
'''
|
||||
def FullCC(udpcc):
|
||||
|
||||
print()
|
||||
midichannel = int(udpcc[1:2],36)
|
||||
#midichannel = base36.index(udpcc[1:2].upper())
|
||||
ccvr = int(udpcc[2:4],36)
|
||||
ccvl = int(udpcc[4:6],36)
|
||||
|
||||
if midichannel < 16:
|
||||
|
||||
if gstt.debug > 0:
|
||||
print(GetTime(),"ccvr=%d/ccvl=%d"%(ccvr,ccvl))
|
||||
|
||||
if gstt.oscname == "ocs2":
|
||||
gstt.crtvalueOCS2[ccvr]=ccvl
|
||||
else:
|
||||
gstt.crtvalueMMO3[ccvr]=ccvl
|
||||
|
||||
for mididevice in midi3.findJamDevices(gstt.oscname):
|
||||
midi3.cc(midichannel, ccvr, ccvl, mididevice)
|
||||
WScom.sendWSall("/"+midi3.findJamName(mididevice, midichannel)+"/cc/"+str(ccvr)+" "+str(ccvl))
|
||||
|
||||
else:
|
||||
print(GetTime(),"Bad midichannel")
|
||||
|
||||
169
libs/WScom.py
Normal file
169
libs/WScom.py
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- mode: Python -*-
|
||||
|
||||
'''
|
||||
WScom for jamidi v0.1b
|
||||
|
||||
WScom.Start(serverIP, wsPORT)
|
||||
WScom.runforever()
|
||||
handler : message_received(client, wserver, message)
|
||||
|
||||
'''
|
||||
|
||||
import midi3
|
||||
|
||||
#import socket
|
||||
import types, json
|
||||
import _thread, time
|
||||
|
||||
from websocket_server import WebsocketServer
|
||||
import gstt
|
||||
import UDPcom, OSCom
|
||||
|
||||
def Start(serverIP, wsPORT):
|
||||
global wserver
|
||||
|
||||
wserver = WebsocketServer(wsPORT,host=serverIP)
|
||||
midi3.ws = wserver
|
||||
|
||||
wserver.set_fn_new_client(new_client)
|
||||
wserver.set_fn_client_left(client_left)
|
||||
wserver.set_fn_message_received(message_received)
|
||||
|
||||
|
||||
def runforever():
|
||||
wserver.run_forever()
|
||||
|
||||
|
||||
# Called for every WS client connecting (after handshake)
|
||||
def new_client(client, wserver):
|
||||
|
||||
|
||||
print(midi3.GetTime(),"New WS client connected and was given id %d" % client['id'])
|
||||
#sendWSall("/status Hello %d" % client['id'])
|
||||
if gstt.current == True:
|
||||
sendallcurrentccvalues("mmo3")
|
||||
sendallcurrentccvalues("ocs2")
|
||||
|
||||
gstt.Players+=1
|
||||
sendWSall("/status Hello %d" %(client['id']))
|
||||
if gstt.Players > 1:
|
||||
#sendWSall("/gstt.Players %d" %(Players))
|
||||
sendWSall("/players (players:%d)" %(gstt.Players))
|
||||
else:
|
||||
sendWSall("/players (player:%d)" %(gstt.Players))
|
||||
|
||||
|
||||
|
||||
# Called for every WS client disconnecting
|
||||
def client_left(client, wserver):
|
||||
|
||||
|
||||
try:
|
||||
print(midi3.GetTime(),"WS Client(%d) disconnected" % client['id'])
|
||||
gstt.Players-=1
|
||||
sendWSall("/players %d" %(gstt.Players))
|
||||
except:
|
||||
print("Something weird if coming from",client,"on the wire...")
|
||||
pass
|
||||
|
||||
|
||||
# Called for each WS received message.
|
||||
def message_received(client, wserver, message):
|
||||
|
||||
print("")
|
||||
if len(message) > 200:
|
||||
message = message[:200]+'..'
|
||||
|
||||
wspath = message.split(" ")
|
||||
if gstt.debug > 0:
|
||||
print(midi3.GetTime(),"Main got from WS", client['id'], "said :", message, "splitted in an wspath :", wspath)
|
||||
else:
|
||||
print(midi3.GetTime(),"Main got WS Client", client['id'], "said :", message)
|
||||
|
||||
wscommand = wspath[0].split("/")
|
||||
|
||||
# gstt.debug
|
||||
if gstt.debug > 0:
|
||||
print("wscommand :",wscommand)
|
||||
|
||||
# noarg
|
||||
if len(wspath) == 1:
|
||||
args[0] = "noargs"
|
||||
#print "noargs command"
|
||||
|
||||
|
||||
# CC : /device/cc/2 127
|
||||
elif wscommand[2] == "cc":
|
||||
ccvr=int(wscommand[3]) #cc variable
|
||||
ccvl=int(wspath[1]) #cc value
|
||||
if gstt.debug > 0:
|
||||
print("ccvr=%d/ccvl=%d"%(ccvr,ccvl))
|
||||
if wscommand[1] == "ocs2":
|
||||
gstt.crtvalueOCS2[ccvr]=ccvl
|
||||
else:
|
||||
gstt.crtvalueMMO3[ccvr]=ccvl
|
||||
|
||||
for mididevice in midi3.findJamDevices(wscommand[1]):
|
||||
midi3.cc(gstt.Confs[wscommand[1]][0]["midichan"], ccvr, ccvl, mididevice)
|
||||
|
||||
|
||||
# RESET : /device/reset 1
|
||||
elif wscommand[2] == "reset":
|
||||
if wscommand[1] == "ocs2":
|
||||
reset("ocs2")
|
||||
else:
|
||||
reset("mmo3")
|
||||
|
||||
|
||||
# NOTEON : /device/noteon note velocity
|
||||
elif wscommand[2] == "noteon":
|
||||
for mididevice in midi3.findJamDevices(wscommand[1]):
|
||||
midi3.NoteOn(int(wspath[1]), int(wspath[2]), mididevice)
|
||||
#midi3.NoteOn(int(wspath[1]), int(wspath[2]), gstt.Confs[wscommand[1]][0]["mididevice"])
|
||||
|
||||
|
||||
# NOTEOFF /device/noteoff note
|
||||
elif wscommand[2] == "noteoff":
|
||||
for mididevice in midi3.findJamDevices(wscommand[1]):
|
||||
midi3.NoteOff(int(wspath[1]), mididevice)
|
||||
#midi3.NoteOff(int(wspath[1]), gstt.Confs[wscommand[1]][0]["mididevice"])
|
||||
|
||||
|
||||
# Loop back : WS Client -> server -> WS Client
|
||||
sendWSall(message)
|
||||
|
||||
# Send through websocket.
|
||||
# Different websocket library for client (websocket) or server (websocket_server.
|
||||
# ws object is added here by main.py or client.py startup : midi3.ws =
|
||||
def send(message):
|
||||
|
||||
if gstt.clientmode == True:
|
||||
send(message)
|
||||
else:
|
||||
wserver.send_message_to_all(msg = message)
|
||||
|
||||
|
||||
|
||||
def sendWSall(message):
|
||||
|
||||
if gstt.broadcast == True:
|
||||
if gstt.debug >0:
|
||||
print(midi3.GetTime(),"WS sending to all %s" % (message))
|
||||
|
||||
wserver.send_message_to_all(message)
|
||||
|
||||
# /send all current cc values
|
||||
def sendallcurrentccvalues(nozoid):
|
||||
|
||||
if gstt.broadcast == True:
|
||||
#print ""
|
||||
print(midi3.GetTime(),"sending all current cc values of", nozoid)
|
||||
|
||||
if nozoid == "mmo3":
|
||||
for ccnumber in range(0,32):
|
||||
sendWSall("/mmo3/cc/"+str(ccnumber)+" "+str(gstt.crtvalueMMO3[ccnumber]))
|
||||
else:
|
||||
for ccnumber in range(0,32):
|
||||
sendWSall("/ocs2/cc/"+str(ccnumber)+" "+str(gstt.crtvalueOCS2[ccnumber]))
|
||||
39
libs/gstt.py
Normal file
39
libs/gstt.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- mode: Python -*-
|
||||
|
||||
"""
|
||||
Jamidi states
|
||||
v0.2.4b
|
||||
|
||||
|
||||
LICENCE : CC
|
||||
by Sam Neurohack
|
||||
from /team/laser
|
||||
|
||||
|
||||
"""
|
||||
|
||||
# reset = [64,64,0,32,96] # un truc comme ca pour les valeurs de reset ?
|
||||
resetMMO3 = [0] * 32
|
||||
resetOCS2 = [0] * 32
|
||||
|
||||
# record current values
|
||||
crtvalueMMO3 = [0] * 32
|
||||
crtvalueOCS2 = [0] * 32
|
||||
|
||||
# record number of loaded pages (aka client id or players)
|
||||
Players=0
|
||||
|
||||
oscname = ""
|
||||
Confs = []
|
||||
|
||||
debug = 0
|
||||
|
||||
BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
def to_base(s, b):
|
||||
res = ""
|
||||
while s:
|
||||
res+=BS[s%b]
|
||||
s//= b
|
||||
return res[::-1] or "0"
|
||||
|
|
@ -36,6 +36,8 @@ import sys
|
|||
from sys import platform
|
||||
import os
|
||||
import re
|
||||
import gstt
|
||||
import WScom
|
||||
|
||||
|
||||
is_py2 = sys.version[0] == '2'
|
||||
|
|
@ -61,10 +63,8 @@ midinputsname = ["Name"] * 16
|
|||
midinputsqueue = [Queue() for i in range(16) ]
|
||||
midinputs = []
|
||||
|
||||
debug = 0
|
||||
|
||||
# False = server / True = Client
|
||||
clientmode = False
|
||||
gstt.clientmode = False
|
||||
|
||||
#Mser = False
|
||||
|
||||
|
|
@ -152,6 +152,7 @@ def note2midi(note_name):
|
|||
pitch = match.group('n').upper()
|
||||
offset = acc_map[match.group('off')]
|
||||
octave = int(match.group('oct'))
|
||||
|
||||
except:
|
||||
raise ValueError('Improper note format: {}'.format(note_name))
|
||||
# Convert from the extrated ints to a full note number
|
||||
|
|
@ -189,17 +190,17 @@ def midi2hz(note_number):
|
|||
# in a 440 Hz tuning
|
||||
return 440.0*(2.0**((note_number - 69)/12.0))
|
||||
|
||||
# /cc cc number value
|
||||
def cc(midichannel, ccnumber, value, mididest):
|
||||
|
||||
if gstt.debug>0:
|
||||
print(GetTime(),"Jamidi Sending Midi channel", midichannel, "cc", ccnumber, "value", value, "to", mididest)
|
||||
|
||||
MidiMsg([CONTROLLER_CHANGE+midichannel-1, ccnumber, value], mididest)
|
||||
|
||||
|
||||
|
||||
# Send through websocket.
|
||||
# Different websocket library for client (websocket) or server (websocket_server.
|
||||
# ws object is added here by main.py or client.py startup : midi3.ws =
|
||||
def wssend(message):
|
||||
|
||||
if clientmode == True:
|
||||
ws.send(message)
|
||||
else:
|
||||
ws.send_message_to_all(msg = message)
|
||||
|
||||
#
|
||||
# MIDI Startup and handling
|
||||
|
|
@ -231,8 +232,18 @@ def MidinProcess(inqueue, portname):
|
|||
MidiVel = msg[2]
|
||||
print(GetTime(),"NOTE ON :", MidiNote, 'velocity :', MidiVel, "Channel", MidiChannel)
|
||||
#NoteOn(msg[1],msg[2],mididest)
|
||||
#NoteOn(msg[1],msg[2],mididest,MidiChannel-1)
|
||||
|
||||
#beware !!
|
||||
if gstt.nothrough == False:
|
||||
for mididevice in findJamDevices(gstt.oscname):
|
||||
#NoteOn(msg[1],msg[2],"XXXX",MidiChannel-1)
|
||||
if gstt.debug>0:
|
||||
print(GetTime(),"mididevice/oscname:",mididevice,"/",gstt.oscname)
|
||||
NoteOn(msg[1],msg[2],mididevice,MidiChannel-1)
|
||||
|
||||
print(GetTime(),"Midi in process send /"+findJamName(portname, MidiChannel)+"/noteon "+str(msg[1])+" "+str(msg[2]))
|
||||
wssend("/"+findJamName(portname, MidiChannel)+"/noteon "+str(msg[1])+" "+str(msg[2]))
|
||||
WScom.send("/"+findJamName(portname, MidiChannel)+"/noteon "+str(msg[1])+" "+str(msg[2]))
|
||||
|
||||
'''
|
||||
# Sampler mode : note <63 launch snare.wav / note > 62 kick.wav
|
||||
|
|
@ -264,7 +275,7 @@ def MidinProcess(inqueue, portname):
|
|||
print(GetTime(),"NOTE OFF :", MidiNote, 'velocity :', MidiVel, "Channel", MidiChannel)
|
||||
#NoteOff(msg[1],msg[2], mididest)
|
||||
print(GetTime(),"Midi in process send /"+findJamName(portname, MidiChannel)+"/noteoff "+str(msg[1]))
|
||||
wssend("/"+findJamName(portname, MidiChannel)+"/noteoff "+str(msg[1]))
|
||||
WScom.send("/"+findJamName(portname, MidiChannel)+"/noteoff "+str(msg[1]))
|
||||
|
||||
|
||||
# # CC on all Midi Channels
|
||||
|
|
@ -274,7 +285,7 @@ def MidinProcess(inqueue, portname):
|
|||
#findJamName(portname, MidiChannel)
|
||||
print(GetTime(),"channel", MidiChannel, " ",findJamName(portname, MidiChannel), " CC :", msg[1], msg[2])
|
||||
print(GetTime(),"Midi in process send /"+findJamName(portname, MidiChannel)+"/cc/"+str(msg[1])+" "+str(msg[2])+" to WS")
|
||||
wssend("/"+findJamName(portname, MidiChannel)+"/cc/"+str(msg[1])+" "+str(msg[2]))
|
||||
WScom.send("/"+findJamName(portname, MidiChannel)+"/cc/"+str(msg[1])+" "+str(msg[2]))
|
||||
|
||||
|
||||
'''
|
||||
|
|
@ -282,7 +293,7 @@ def MidinProcess(inqueue, portname):
|
|||
if CONTROLLER_CHANGE -1 < msg[0] < 192:
|
||||
print("channel 1 (MMO-3) CC :", msg[1], msg[2])
|
||||
print("Midi in process send /mmo3/cc/"+str(msg[1])+" "+str(msg[2])+" to WS")
|
||||
wssend("/mmo3/cc/"+str(msg[1])+" "+str(msg[2]))
|
||||
WScom.send("/mmo3/cc/"+str(msg[1])+" "+str(msg[2]))
|
||||
|
||||
|
||||
# OCS-2 Midi CC message CHANNEL 2
|
||||
|
|
@ -290,7 +301,7 @@ def MidinProcess(inqueue, portname):
|
|||
print("channel 2 (OCS-2) CC :", msg[1], msg[2])
|
||||
|
||||
print("Midi in process send /ocs2/cc/"+str(msg[1])+" "+str(msg[2])+" to WS")
|
||||
wssend("/ocs2/cc/"+str(msg[1])+" "+str(msg[2]))
|
||||
WScom.send("/ocs2/cc/"+str(msg[1])+" "+str(msg[2]))
|
||||
'''
|
||||
|
||||
|
||||
|
|
@ -303,19 +314,24 @@ def MidinProcess(inqueue, portname):
|
|||
'''
|
||||
|
||||
|
||||
def NoteOn(note,color, mididest):
|
||||
#def NoteOn(note, color, mididest):
|
||||
#https://pypi.org/project/python-rtmidi/0.3a/
|
||||
#à NOTE_ON=#90 et NOTE_OFF=#80 on ajoute le channel (0 le premier) pour envoyer effectivement sur le channel
|
||||
def NoteOn(note, color, mididest, midichannel=0):
|
||||
global MidInsNumber
|
||||
|
||||
|
||||
if gstt.debug >0:
|
||||
print(GetTime(),"Sending", note, color, "to", mididest, "on channel", midichannel)
|
||||
|
||||
for port in range(MidInsNumber):
|
||||
|
||||
# To mididest
|
||||
if midiname[port].find(mididest) == 0:
|
||||
midiport[port].send_message([NOTE_ON, note, color])
|
||||
midiport[port].send_message([NOTE_ON+midichannel, note, color])
|
||||
|
||||
# To All
|
||||
elif mididest == "all" and midiname[port].find(mididest) != 0:
|
||||
midiport[port].send_message([NOTE_ON, note, color])
|
||||
midiport[port].send_message([NOTE_ON+midichannel, note, color])
|
||||
|
||||
|
||||
|
||||
|
|
@ -491,8 +507,8 @@ def InConfig():
|
|||
print(GetTime(),"MIDIin...")
|
||||
|
||||
# client mode
|
||||
if debug > 0:
|
||||
if clientmode == True:
|
||||
if gstt.debug > 0:
|
||||
if gstt.clientmode == True:
|
||||
print(GetTime(),"midi3 in client mode")
|
||||
else:
|
||||
print(GetTime(),"midi3 in server mode")
|
||||
|
|
@ -603,8 +619,8 @@ def MidiMsg(midimsg, mididest):
|
|||
for port in range(len(OutDevice)):
|
||||
# To mididest
|
||||
if midiname[port].find(mididest) != -1:
|
||||
if debug>0:
|
||||
print(GetTime(),"jamidi 3 sending to name", midiname[port], "port", port, ":", midimsg)
|
||||
if gstt.debug>0:
|
||||
print(GetTime(),"jamidi3 sending to name", midiname[port], "port", port, ":", midimsg)
|
||||
midiport[port].send_message(midimsg)
|
||||
desterror = 0
|
||||
|
||||
|
|
@ -612,11 +628,11 @@ def MidiMsg(midimsg, mididest):
|
|||
print(GetTime(),"mididest",mididest, ": ** This midi destination doesn't exists **")
|
||||
|
||||
# send midi msg over ws.
|
||||
#if clientmode == True:
|
||||
#if gstt.clientmode == True:
|
||||
# ws.send("/ocs2/cc/1 2")
|
||||
|
||||
|
||||
|
||||
'''
|
||||
def NoteOn(note, velocity, mididest):
|
||||
global MidInsNumber
|
||||
|
||||
|
|
@ -626,7 +642,7 @@ def NoteOn(note, velocity, mididest):
|
|||
# To mididest
|
||||
if midiname[port].find(mididest) == 0:
|
||||
midiport[port].send_message([NOTE_ON, note, velocity])
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def listdevice(number):
|
||||
|
|
@ -638,17 +654,20 @@ def listdevice(number):
|
|||
# return device name for given mididevice and midichannel
|
||||
def findJamName(mididevice, midichan):
|
||||
|
||||
#print("searching", mididevice, "channel", midichan,'...')
|
||||
|
||||
for (k, v) in Confs.items():
|
||||
if gstt.debug >0:
|
||||
print(GetTime(),"Findjamname searching", mididevice, "channel", midichan,'...')
|
||||
|
||||
for (k, v) in gstt.Confs.items():
|
||||
#print("Key: " + k)
|
||||
#print("Value: " + str(v))
|
||||
if v[0]["type"] == "mididevice":
|
||||
|
||||
#print(v[0]["mididevice"],v[0]["midichan"], type(v[0]["midichan"]))
|
||||
#print(k, v[0]["mididevice"],v[0]["midichan"],type(v[0]["midichan"]),v[0]["xname"], "?")
|
||||
if (v[0]["mididevice"] == mididevice) and (v[0]["midichan"] == midichan):
|
||||
print(GetTime(),"Incoming event from", k, "xname", v[0]["xname"])
|
||||
return v[0]["xname"]
|
||||
|
||||
return "None"
|
||||
|
||||
|
||||
|
|
@ -656,15 +675,17 @@ def findJamName(mididevice, midichan):
|
|||
def findJamDevices(name):
|
||||
|
||||
devices = []
|
||||
print (GetTime(),"searching", name)
|
||||
for (k, v) in Confs.items():
|
||||
if gstt.debug >0:
|
||||
print (GetTime(),"Findjamdevice searching", name)
|
||||
for (k, v) in gstt.Confs.items():
|
||||
|
||||
if v[0]["type"] == "mididevice":
|
||||
#print(k, name,v[0]["xname"])
|
||||
if v[0]["xname"] == name:
|
||||
#print(v[0]["mididevice"])
|
||||
devices.append(v[0]["mididevice"])
|
||||
# print(devices)
|
||||
if gstt.debug>0:
|
||||
print(GetTime(),devices)
|
||||
return devices
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue