275 lines
6.9 KiB
Python
Executable File
275 lines
6.9 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
# -*- mode: Python -*-
|
|
'''
|
|
Jamidi Server v0.1b
|
|
|
|
wserver = WebsocketServer(wsPORT,host=serverIP)
|
|
|
|
wserver.set_fn_new_client(new_client)
|
|
wserver.set_fn_client_left(client_left)
|
|
wserver.set_fn_message_received(message_received)
|
|
|
|
wserver.run_forever()
|
|
|
|
wserver.send_message_to_all(message)
|
|
|
|
ORCA:
|
|
|
|
CTRL K pour rentrer une commande
|
|
|
|
CTRL K ip:127.0.0.1
|
|
CTRL K osc:8082
|
|
CTRL K cc:0
|
|
CTRL K udp:udport
|
|
|
|
|
|
|
|
/p
|
|
Pitch bend
|
|
|
|
|
|
|
|
'''
|
|
|
|
print("")
|
|
print("")
|
|
print("Jamidi Server")
|
|
print("v0.1b")
|
|
|
|
import sys
|
|
import traceback
|
|
import os
|
|
import time
|
|
|
|
from rtmidi.midiconstants import (CHANNEL_PRESSURE, CONTROLLER_CHANGE, NOTE_ON, NOTE_OFF,
|
|
PITCH_BEND, POLY_PRESSURE, PROGRAM_CHANGE)
|
|
|
|
sys.path.append('libs/')
|
|
import midi3
|
|
|
|
#import socket
|
|
import types, json
|
|
import argparse
|
|
|
|
import _thread, time
|
|
|
|
from midi3 import note2midi
|
|
from midi3 import GetTime
|
|
|
|
import OSCom
|
|
import WScom
|
|
import UDPcom
|
|
import gstt
|
|
|
|
|
|
print ("")
|
|
print ("Arguments parsing if needed...")
|
|
argsparser = argparse.ArgumentParser(description="Jamidi Server v0.1b commands help mode")
|
|
argsparser.add_argument("-s","--servername",help="Servername: 'local', 'llstrvpn' (local by default)", type=str)
|
|
argsparser.add_argument("-d","--device",help="midi device for incoming ORCA via UDP (mmo3 by default)", type=str)
|
|
argsparser.add_argument('-nothrough',help="Disable the builtin midithrough from any midi IN to --device enabled by default", dest='nothrough', action='store_true')
|
|
argsparser.set_defaults(nothrough=False)
|
|
argsparser.add_argument('-nocurrent',help="Do not send all current CC values to all new client (enabled by default)", dest='current', action='store_false')
|
|
argsparser.set_defaults(current=True)
|
|
argsparser.add_argument('-nobroadcast',help="Do not broadcast all incomings commands to all client (enabled by default)", dest='broadcast', action='store_false')
|
|
argsparser.set_defaults(broadcast=True)
|
|
argsparser.add_argument('-noreset',help="Do not broadcast all incomings commands to all client (enabled by default)", dest='reset', action='store_false')
|
|
argsparser.set_defaults(reset=True)
|
|
argsparser.add_argument('-verbose',help="Enable debug mode (disabled by default)", dest='verbose', action='store_true')
|
|
argsparser.set_defaults(verbose=False)
|
|
|
|
args = argsparser.parse_args()
|
|
|
|
# Server name
|
|
if args.servername:
|
|
servername = args.servername
|
|
else:
|
|
servername = "local"
|
|
|
|
# ORCA destination device
|
|
if args.device:
|
|
gstt.oscname = args.device
|
|
else:
|
|
gstt.oscname = "mmo3"
|
|
|
|
|
|
# Broadcast commands to all clients ?
|
|
if args.broadcast == False:
|
|
print("Broadcast disabled")
|
|
gstt.broadcast = False
|
|
else:
|
|
print("Broadcast enabled")
|
|
gstt.broadcast = True
|
|
|
|
# Send current values to all new client ?
|
|
if args.current == False:
|
|
print("Do not send current values at startup disabled")
|
|
gstt.current = False
|
|
else:
|
|
print("Current values update at startup disabled")
|
|
gstt.current = True
|
|
|
|
# Reset at startup ?
|
|
if args.reset == False:
|
|
print("Reset at startup disabled")
|
|
gstt.startreset = False
|
|
else:
|
|
print("Reset at startup enabled")
|
|
gstt.startreset = True
|
|
|
|
# Debug/verbose mode ?
|
|
if args.verbose == False:
|
|
print("Debug mode disabled")
|
|
gstt.debug = 0
|
|
else:
|
|
print("Debug mode enabled")
|
|
gstt.debug = 1
|
|
|
|
# nomidithrough mode ?
|
|
if args.nothrough == False:
|
|
print("Midi through mode")
|
|
gstt.nothrough = False
|
|
else:
|
|
print("No midi through mode")
|
|
gstt.nothrough = True
|
|
|
|
|
|
#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"}
|
|
|
|
'''
|
|
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}
|
|
|
|
transpose =
|
|
"0": None, "1": None, "2": None, "3":, None, "4":, None, "5":, "6":, "7":, "8":, "9":, "A": "A0", "B": B0,
|
|
C ,"C0", D : "D0", "E": "E0" F G H I J K L M N
|
|
"C0" "D0" "E0" "F0" "G0" "A0" "B0" "C1" "D1" "E1" "F1" "G1"
|
|
O P Q R S T U V W X Y Z
|
|
"A1" "B1" "C2" "D2" "E2" "F2" "G2" "A2" "B2" "C3" "D3" "E3"
|
|
'''
|
|
|
|
#
|
|
# Settings from jamidi.json
|
|
#
|
|
|
|
# Load midi definitions in jamidi.json
|
|
def LoadConfs():
|
|
|
|
if os.path.exists('jamidi.json'):
|
|
f=open("jamidi.json","r")
|
|
|
|
s = f.read()
|
|
gstt.Confs = json.loads(s)
|
|
#print(GetTime(),gstt.Confs)
|
|
|
|
|
|
# return midi confname number for given type
|
|
def findConfs(confname,conftype):
|
|
|
|
#print("searching", midiconfname,'...')
|
|
position = -1
|
|
for counter in range(len(gstt.Confs[conftype])):
|
|
if confname == gstt.Confs[conftype][counter]['name']:
|
|
#print(confname, "is ", counter)
|
|
position = counter
|
|
return position
|
|
|
|
LoadConfs()
|
|
|
|
|
|
|
|
#
|
|
# Midi part
|
|
#
|
|
|
|
print("Midi Configuration...")
|
|
# print("Midi Destination", nozmidi)
|
|
|
|
midi3.check()
|
|
|
|
def GetTime():
|
|
return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
|
|
|
|
|
|
# /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)
|
|
|
|
midi3.MidiMsg([CONTROLLER_CHANGE+midichannel-1, ccnumber, value], mididest)
|
|
|
|
|
|
# /reset nozoids with "default" values
|
|
def reset(nozoid):
|
|
|
|
print("")
|
|
print(GetTime(),"reseting", nozoid)
|
|
|
|
if nozoid == "mmo3":
|
|
for ccnumber in range(0,32):
|
|
midi3.MidiMsg([CONTROLLER_CHANGE+gstt.Confs["mmo3"][0]["midichan"]-1, ccnumber, gstt.resetMMO3[ccnumber]], gstt.Confs["mmo3"][0]["mididevice"])
|
|
WScom.sendWSall("/mmo3/cc/"+str(ccnumber)+" "+str(gstt.resetMMO3[ccnumber]))
|
|
gstt.crtvalueMMO3[ccnumber]=gstt.resetMMO3[ccnumber]
|
|
else:
|
|
for ccnumber in range(0,32):
|
|
midi3.MidiMsg([CONTROLLER_CHANGE+gstt.Confs["ocs2"][0]["midichan"]-1, ccnumber, gstt.resetOCS2[ccnumber]], gstt.Confs["ocs2"][0]["mididevice"])
|
|
WScom.sendWSall("/ocs2/cc/"+str(ccnumber)+" "+str(gstt.resetOCS2[ccnumber]))
|
|
gstt.crtvalueOCS2[ccnumber]=gstt.resetOCS2[ccnumber]
|
|
print(GetTime(),"End of reset for", nozoid)
|
|
print("")
|
|
|
|
|
|
|
|
|
|
#
|
|
# Running...
|
|
#
|
|
|
|
|
|
serverIP = gstt.Confs[servername][0]["IP"]
|
|
wsPORT = gstt.Confs[servername][0]["port"]
|
|
OSCPORT = gstt.Confs[servername][0]["oscport"]
|
|
UDPORT = gstt.Confs[servername][0]["udport"]
|
|
|
|
print()
|
|
print(GetTime(),"Launching servers...")
|
|
print(GetTime(),"Launching OSC Server", serverIP,':', OSCPORT)
|
|
OSCom.Start(serverIP, OSCPORT)
|
|
|
|
print(GetTime(),"Launching UDP Server", serverIP,':', wsPORT)
|
|
UDPcom.Start(serverIP, UDPORT)
|
|
|
|
print(GetTime(),"Launching WS Server", serverIP,':', UDPORT)
|
|
WScom.Start(serverIP, wsPORT)
|
|
|
|
|
|
if gstt.startreset == True:
|
|
print(GetTime(),"resetting nozoids...")
|
|
reset("mmo3")
|
|
reset("ocs2")
|
|
|
|
# Main
|
|
|
|
try:
|
|
|
|
print(GetTime(),"Jamidi running forever...")
|
|
|
|
WScom.runforever()
|
|
|
|
except Exception:
|
|
traceback.print_exc()
|
|
|
|
finally:
|
|
OSCom.Stop()
|
|
|
|
|
|
# Gently stop on CTRL C
|
|
|
|
|
|
print("Fin de Jamidi.")
|
|
|
|
|
|
|
|
|