Better UI
This commit is contained in:
parent
36766367c8
commit
946528cb67
18
README.md
18
README.md
@ -3,10 +3,12 @@ By Sam Neurohack
|
|||||||
|
|
||||||
Display Link, OSC, Artnet and Midi timecodes
|
Display Link, OSC, Artnet and Midi timecodes
|
||||||
|
|
||||||
Listen on all network interface and midi interfaces
|
Listen on all network interfaces and midi interfaces
|
||||||
|
|
||||||
OSC port : 9001
|
OSC port : 9001
|
||||||
ARTNET Port : 6454
|
Artnet Port : 6454
|
||||||
|
|
||||||
|
Needs timecode, rtmidi, mido
|
||||||
|
|
||||||
* Link
|
* Link
|
||||||
|
|
||||||
@ -15,15 +17,17 @@ ARTNET Port : 6454
|
|||||||
|
|
||||||
* OSC
|
* OSC
|
||||||
|
|
||||||
- hour:minutes:seconds:ms (from OSC message received /TC1/time/30 '00:00:02:23')
|
- hour:minutes:seconds:ms (from OSC message received containing /TC like /TC1/time/30 '00:00:02:23')
|
||||||
- (https://github.com/hautetechnique/OSCTimeCode.git)
|
- Tested against https://github.com/hautetechnique/OSCTimeCode.git
|
||||||
|
|
||||||
* Artnet (OpTimeCode)
|
* Artnet
|
||||||
|
|
||||||
- codetype hours:minutes:seconds:frames
|
- hours:minutes:seconds:frames codetype
|
||||||
|
- OpTimeCode
|
||||||
|
- Tested against lightingapps.de/software/artnetviewer
|
||||||
|
|
||||||
* Midi (Clock)
|
* Midi (Clock)
|
||||||
|
|
||||||
- BPM computed from received clock messages
|
- BPM computed from received clock messages
|
||||||
- MTC https://github.com/jeffmikels/timecode_tools.git
|
- MTC (quarterframes).Tested against mtc_generate from https://github.com/jeffmikels/timecode_tools.git
|
||||||
|
|
||||||
|
Binary file not shown.
29
midix.py
29
midix.py
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Midi3 light version for soundt/Jamidi/clapt
|
Midix light version
|
||||||
v0.7.0
|
v0.7.0
|
||||||
|
|
||||||
Midi Handler :
|
Midi Handler :
|
||||||
@ -22,10 +22,11 @@ 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
|
||||||
|
import tools
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
import weakref
|
import weakref
|
||||||
@ -71,6 +72,10 @@ stop = mido.Message(type ="stop")
|
|||||||
ccontinue = mido.Message(type ="continue")
|
ccontinue = mido.Message(type ="continue")
|
||||||
reset = mido.Message(type ="reset")
|
reset = mido.Message(type ="reset")
|
||||||
songpos = mido.Message(type ="songpos")
|
songpos = mido.Message(type ="songpos")
|
||||||
|
qframe = mido.Message(type = 'quarter_frame')
|
||||||
|
sysex = mido.Message(type = 'sysex')
|
||||||
|
|
||||||
|
print(SYSTEM_EXCLUSIVE, MIDI_TIME_CODE)
|
||||||
|
|
||||||
#mode = "maxwell"
|
#mode = "maxwell"
|
||||||
|
|
||||||
@ -142,7 +147,7 @@ bpm = 0
|
|||||||
running = True
|
running = True
|
||||||
samples = deque()
|
samples = deque()
|
||||||
last_clock = None
|
last_clock = None
|
||||||
|
quarter_frames = [0,0,0,0,0,0,0,0]
|
||||||
|
|
||||||
#
|
#
|
||||||
# Events from Generic MIDI Handling
|
# Events from Generic MIDI Handling
|
||||||
@ -251,6 +256,24 @@ def MidinProcess(inqueue, portname):
|
|||||||
#print("Midi in process send /aurora/stop")
|
#print("Midi in process send /aurora/stop")
|
||||||
SendTCview("/stop",[])
|
SendTCview("/stop",[])
|
||||||
|
|
||||||
|
if msg[0] == SYSTEM_EXCLUSIVE:
|
||||||
|
# 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:
|
||||||
|
57
tcview.py
57
tcview.py
@ -59,6 +59,11 @@ bpm = 120
|
|||||||
|
|
||||||
ccs =[0]*10
|
ccs =[0]*10
|
||||||
|
|
||||||
|
tkred = "#FFF0F0"
|
||||||
|
tkgreen = "#F0FFF0"
|
||||||
|
tkblue = "#F0F0FF"
|
||||||
|
tktitle =('Arial', 11)
|
||||||
|
tkfont =('Verdana', 18)
|
||||||
|
|
||||||
#
|
#
|
||||||
# OSC
|
# OSC
|
||||||
@ -127,7 +132,7 @@ def OSC_Stop():
|
|||||||
oscserver.close()
|
oscserver.close()
|
||||||
|
|
||||||
|
|
||||||
# default handler
|
# OSC default handler
|
||||||
def handler(path, tags, args, source):
|
def handler(path, tags, args, source):
|
||||||
|
|
||||||
oscaddress = ''.join(path.split("/"))
|
oscaddress = ''.join(path.split("/"))
|
||||||
@ -150,7 +155,12 @@ def handler(path, tags, args, source):
|
|||||||
if path.find('/MIDIBPM') > -1:
|
if path.find('/MIDIBPM') > -1:
|
||||||
|
|
||||||
#print("midibpm", args)
|
#print("midibpm", args)
|
||||||
interface.update_midibpm("BPM " +str(args[0]))
|
interface.update_midibpm(str(args[0])+" bpm")
|
||||||
|
|
||||||
|
if path.find('/MIDIQF') > -1:
|
||||||
|
|
||||||
|
#print("midimtc", args)
|
||||||
|
interface.update_midimtc(str(args[0]))
|
||||||
|
|
||||||
|
|
||||||
# Dcode OSC Timecode /TC1/time/30 "00:01:07:12" or /TC2/time/30 "00:01:07:12"
|
# Dcode OSC Timecode /TC1/time/30 "00:01:07:12" or /TC2/time/30 "00:01:07:12"
|
||||||
@ -205,8 +215,8 @@ def BeatEvent():
|
|||||||
# new beat ?
|
# new beat ?
|
||||||
if int(phase) != prevphase:
|
if int(phase) != prevphase:
|
||||||
prevphase = int(phase)
|
prevphase = int(phase)
|
||||||
interface.update_link("Beat "+str(beats_str)+" "+str(phase_str))
|
interface.update_link(str(beats_str)+" "+str(phase_str))
|
||||||
interface.update_linkbpm("BPM "+str(bpm))
|
interface.update_linkbpm(str(bpm)+" bpm")
|
||||||
#sys.stdout.write("Beat "+str(beats_str) + ' \r')
|
#sys.stdout.write("Beat "+str(beats_str) + ' \r')
|
||||||
#sys.stdout.flush()
|
#sys.stdout.flush()
|
||||||
currentbeat = float(beats_str)
|
currentbeat = float(beats_str)
|
||||||
@ -329,7 +339,7 @@ def artnetHandler(data):
|
|||||||
codetype = data[18]
|
codetype = data[18]
|
||||||
print("OptimeCode : hours", hours, "minutes", minutes, "seconds", seconds, "frames", frames,"type", codetypes[codetype])
|
print("OptimeCode : hours", hours, "minutes", minutes, "seconds", seconds, "frames", frames,"type", codetypes[codetype])
|
||||||
#motherosc.send('/artnet/timecode', str(hours)+ ":"+str(minutes)+ ":"+ str(seconds)+ ":"+str(frames)+" timecode type "+str(codetype))
|
#motherosc.send('/artnet/timecode', str(hours)+ ":"+str(minutes)+ ":"+ str(seconds)+ ":"+str(frames)+" timecode type "+str(codetype))
|
||||||
interface.update_artnetcode(codetypes[codetype]+" "+str(hours)+ ":"+str(minutes)+ ":"+ str(seconds)+ ":"+str(frames))
|
interface.update_artnetcode(str(hours)+ ":"+str(minutes)+ ":"+ str(seconds)+ ":"+str(frames)+" "+codetypes[codetype])
|
||||||
|
|
||||||
if data[8] == 0x00 and data[9] == 0x98:
|
if data[8] == 0x00 and data[9] == 0x98:
|
||||||
print("OpTimeSync")
|
print("OpTimeSync")
|
||||||
@ -364,55 +374,61 @@ class Interface(Frame):
|
|||||||
Tous les widgets sont stockés comme attributs de cette fenêtre."""
|
Tous les widgets sont stockés comme attributs de cette fenêtre."""
|
||||||
|
|
||||||
def __init__(self, myframe, **kwargs):
|
def __init__(self, myframe, **kwargs):
|
||||||
Frame.__init__(self, myframe, width=300, height=576, bg="black", **kwargs)
|
Frame.__init__(self, myframe, width=350, height=576, bg="black", **kwargs)
|
||||||
self.pack(fill=NONE)
|
self.pack(fill=NONE)
|
||||||
self.nb_clic = 0
|
self.nb_clic = 0
|
||||||
|
|
||||||
# Création de nos widgets
|
# Création de nos widgets
|
||||||
self.message = Label(self, text=" Timecodes viewer ", bg="black", foreground="white")
|
#self.message = Label(self, text=" Timecodes viewer ", bg="black", foreground="white")
|
||||||
self.message.place(x = 0, y = 25)
|
#self.message.place(x = 0, y = 25)
|
||||||
self.message.pack()
|
#self.message.pack()
|
||||||
#self.message.config(bg="black", foreground="white")
|
#self.message.config(bg="black", foreground="white")
|
||||||
|
|
||||||
self.link = Label(self, text="-- Link --", bg="black", foreground="white")
|
|
||||||
|
self.link = Label(self, text="Link", bg="black", foreground="white", font = tktitle, justify ='left')
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.link.pack()
|
self.link.pack()
|
||||||
self.linkbpm = Label(self, text="BPM", bg="black", foreground="white")
|
self.linkbpm = Label(self, text="..bpm..", bg="black", foreground="white", font = tkfont)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.linkbpm.pack()
|
self.linkbpm.pack()
|
||||||
self.lbl1 = Label(self, text="Waiting...", bg="black", foreground="white")
|
self.lbl1 = Label(self, text="..beats..", bg="black", foreground="white", font = tkfont)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.lbl1.pack()
|
self.lbl1.pack()
|
||||||
|
|
||||||
|
|
||||||
self.lbl2 = Label(self, text="-- OSC --", bg="black", foreground="white")
|
self.lbl2 = Label(self, text="OSC", bg="black", foreground=tkblue, font = tktitle, anchor =W)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.lbl2.pack()
|
self.lbl2.pack()
|
||||||
|
|
||||||
self.oscode = Label(self, text="Waiting...", bg="black", foreground="white")
|
self.oscode = Label(self, text="..:..:..:.. ", bg="black", foreground=tkblue, font = tkfont)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.oscode.pack()
|
self.oscode.pack()
|
||||||
|
|
||||||
self.artnet = Label(self, text="-- Artnet --", bg="black", foreground="white")
|
self.artnet = Label(self, text="Artnet", bg="black", foreground=tkgreen, font = tktitle)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.artnet.pack()
|
self.artnet.pack()
|
||||||
|
|
||||||
self.artnetcode = Label(self, text="Waiting...", bg="black", foreground="white")
|
self.artnetcode = Label(self, text="..:..:..:..", bg="black", foreground=tkgreen, font = tkfont)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.artnetcode.pack()
|
self.artnetcode.pack()
|
||||||
|
|
||||||
self.midi = Label(self, text="-- Midi --", bg="black", foreground="white")
|
self.midi = Label(self, text="Midi", bg="black", foreground=tkred, font = tktitle)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.midi.pack()
|
self.midi.pack()
|
||||||
|
|
||||||
self.midibpm = Label(self, text="Waiting...", bg="black", foreground="white")
|
self.midibpm = Label(self, text="... bpm", bg="black", foreground=tkred, font = tkfont)
|
||||||
#self.lbl0.place(x = 0, y = 55)
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
self.midibpm.pack()
|
self.midibpm.pack()
|
||||||
|
|
||||||
self.quit_button = Button(self, text="Quit", command=self.quit)
|
self.midimtc = Label(self, text="..:..:..:..", bg="black", foreground=tkred, font = tkfont)
|
||||||
|
#self.lbl0.place(x = 0, y = 55)
|
||||||
|
self.midimtc.pack()
|
||||||
|
|
||||||
|
self.quit_button = Button(self, text="Quit", command=self.quit, font = tktitle)
|
||||||
#self.quit_button.configure(background = "green")
|
#self.quit_button.configure(background = "green")
|
||||||
self.quit_button.pack(side="bottom")
|
self.quit_button.pack(side="bottom")
|
||||||
self.update_UI()
|
self.update_UI()
|
||||||
|
|
||||||
'''
|
'''
|
||||||
self.bouton_cliquer = Button(self, text="Cliquez ici", fg="red",
|
self.bouton_cliquer = Button(self, text="Cliquez ici", fg="red",
|
||||||
command=self.cliquer)
|
command=self.cliquer)
|
||||||
@ -431,6 +447,9 @@ class Interface(Frame):
|
|||||||
def update_midibpm(self, msg):
|
def update_midibpm(self, msg):
|
||||||
self.midibpm.configure(text = msg)
|
self.midibpm.configure(text = msg)
|
||||||
|
|
||||||
|
def update_midimtc(self, msg):
|
||||||
|
self.midimtc.configure(text = msg)
|
||||||
|
|
||||||
def update_artnetcode(self, msg):
|
def update_artnetcode(self, msg):
|
||||||
self.artnetcode.configure(text = msg)
|
self.artnetcode.configure(text = msg)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user