BUgfixs
This commit is contained in:
parent
98f039b2ee
commit
012bef55b1
11 changed files with 435 additions and 171 deletions
151
libs/midi3.py
151
libs/midi3.py
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
|
@ -13,6 +14,8 @@ Midi Handler :
|
|||
by Sam Neurohack
|
||||
from /team/laser
|
||||
|
||||
Midi conversions from https://github.com/craffel/pretty-midi
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -32,6 +35,7 @@ import weakref
|
|||
import sys
|
||||
from sys import platform
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
is_py2 = sys.version[0] == '2'
|
||||
|
|
@ -103,13 +107,90 @@ STATUS_MAP = {
|
|||
}
|
||||
|
||||
|
||||
def GetTime():
|
||||
return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
|
||||
|
||||
notes = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]
|
||||
def midi2note(midinote):
|
||||
|
||||
print("midinote",midinote, "note", notes[midinote%12]+str(round(midinote/12)))
|
||||
print(GetTime(),"midinote",midinote, "note", notes[midinote%12]+str(round(midinote/12)))
|
||||
return notes[midinote%12]+str(round(midinote/12))
|
||||
|
||||
|
||||
def note2midi(note_name):
|
||||
"""Converts a note name in the format
|
||||
``'(note)(accidental)(octave number)'`` (e.g. ``'C#4'``) to MIDI note
|
||||
number.
|
||||
``'(note)'`` is required, and is case-insensitive.
|
||||
``'(accidental)'`` should be ``''`` for natural, ``'#'`` for sharp and
|
||||
``'!'`` or ``'b'`` for flat.
|
||||
If ``'(octave)'`` is ``''``, octave 0 is assumed.
|
||||
Parameters
|
||||
----------
|
||||
note_name : str
|
||||
A note name, as described above.
|
||||
Returns
|
||||
-------
|
||||
note_number : int
|
||||
MIDI note number corresponding to the provided note name.
|
||||
Notes
|
||||
-----
|
||||
Thanks to Brian McFee.
|
||||
"""
|
||||
|
||||
# Map note name to the semitone
|
||||
pitch_map = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
|
||||
# Relative change in semitone denoted by each accidental
|
||||
acc_map = {'#': 1, '': 0, 'b': -1, '!': -1}
|
||||
|
||||
# Reg exp will raise an error when the note name is not valid
|
||||
try:
|
||||
# Extract pitch, octave, and accidental from the supplied note name
|
||||
match = re.match(r'^(?P<n>[A-Ga-g])(?P<off>[#b!]?)(?P<oct>[+-]?\d+)$',
|
||||
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
|
||||
return 12*(octave + 1) + pitch_map[pitch] + offset
|
||||
|
||||
|
||||
|
||||
def hz2midi(frequency):
|
||||
"""Convert a frequency in Hz to a (fractional) note number.
|
||||
Parameters
|
||||
----------
|
||||
frequency : float
|
||||
Frequency of the note in Hz.
|
||||
Returns
|
||||
-------
|
||||
note_number : float
|
||||
MIDI note number, can be fractional.
|
||||
"""
|
||||
# MIDI note numbers are defined as the number of semitones relative to C0
|
||||
# in a 440 Hz tuning
|
||||
return 12*(np.log2(frequency) - np.log2(440.0)) + 69
|
||||
|
||||
def midi2hz(note_number):
|
||||
"""Convert a (fractional) MIDI note number to its frequency in Hz.
|
||||
Parameters
|
||||
----------
|
||||
note_number : float
|
||||
MIDI note number, can be fractional.
|
||||
Returns
|
||||
-------
|
||||
note_frequency : float
|
||||
Frequency of the note in Hz.
|
||||
"""
|
||||
# MIDI note numbers are defined as the number of semitones relative to C0
|
||||
# in a 440 Hz tuning
|
||||
return 440.0*(2.0**((note_number - 69)/12.0))
|
||||
|
||||
|
||||
|
||||
# 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 =
|
||||
|
|
@ -139,7 +220,7 @@ def MidinProcess(inqueue, portname):
|
|||
time.sleep(0.001)
|
||||
msg = inqueue_get()
|
||||
print("")
|
||||
print("Generic from", portname,"msg : ", msg)
|
||||
print(GetTime(),"Generic from", portname,"msg : ", msg)
|
||||
|
||||
|
||||
# Noteon message on all midi channels
|
||||
|
|
@ -148,9 +229,9 @@ def MidinProcess(inqueue, portname):
|
|||
MidiChannel = msg[0]-144
|
||||
MidiNote = msg[1]
|
||||
MidiVel = msg[2]
|
||||
print("NOTE ON :", MidiNote, 'velocity :', MidiVel, "Channel", MidiChannel)
|
||||
print(GetTime(),"NOTE ON :", MidiNote, 'velocity :', MidiVel, "Channel", MidiChannel)
|
||||
#NoteOn(msg[1],msg[2],mididest)
|
||||
print("Midi in process send /"+findJamName(portname, MidiChannel)+"/noteon "+str(msg[1])+" "+str(msg[2]))
|
||||
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]))
|
||||
|
||||
'''
|
||||
|
|
@ -174,15 +255,15 @@ def MidinProcess(inqueue, portname):
|
|||
# Note Off or Note with 0 velocity on all midi channels
|
||||
if NOTE_OFF -1 < msg[0] < 145 or (NOTE_OFF -1 < msg[0] < 160 and msg[2] == 0):
|
||||
|
||||
print(NOTE_OFF)
|
||||
print(GetTime(),"NOTE_OFF :",NOTE_OFF)
|
||||
if msg[0] > 143:
|
||||
MidiChannel = msg[0]-144
|
||||
else:
|
||||
MidiChannel = msg[0]-128
|
||||
|
||||
print("NOTE OFF :", MidiNote, 'velocity :', MidiVel, "Channel", MidiChannel)
|
||||
print(GetTime(),"NOTE OFF :", MidiNote, 'velocity :', MidiVel, "Channel", MidiChannel)
|
||||
#NoteOff(msg[1],msg[2], mididest)
|
||||
print("Midi in process send /"+findJamName(portname, MidiChannel)+"/noteoff "+str(msg[1]))
|
||||
print(GetTime(),"Midi in process send /"+findJamName(portname, MidiChannel)+"/noteoff "+str(msg[1]))
|
||||
wssend("/"+findJamName(portname, MidiChannel)+"/noteoff "+str(msg[1]))
|
||||
|
||||
|
||||
|
|
@ -191,8 +272,8 @@ def MidinProcess(inqueue, portname):
|
|||
|
||||
MidiChannel = msg[0]-175
|
||||
#findJamName(portname, MidiChannel)
|
||||
print("channel", MidiChannel, " ",findJamName(portname, MidiChannel), " CC :", msg[1], msg[2])
|
||||
print("Midi in process send /"+findJamName(portname, MidiChannel)+"/cc/"+str(msg[1])+" "+str(msg[2])+" to WS")
|
||||
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]))
|
||||
|
||||
|
||||
|
|
@ -290,7 +371,7 @@ class OutObject():
|
|||
self._instances.add(weakref.ref(self))
|
||||
OutObject.counter += 1
|
||||
|
||||
print("Adding OutDevice name", self.name, "kind", self.kind, "port", self.port)
|
||||
print(GetTime(),"Adding OutDevice name", self.name, "kind", self.kind, "port", self.port)
|
||||
|
||||
@classmethod
|
||||
def getinstances(cls):
|
||||
|
|
@ -314,8 +395,8 @@ def OutConfig():
|
|||
#
|
||||
if len(OutDevice) == 0:
|
||||
print("")
|
||||
print("MIDIout...")
|
||||
print("List and attach to available devices on host with IN port :")
|
||||
print(GetTime(),"MIDIout...")
|
||||
print(GetTime(),"List and attach to available devices on host with IN port :")
|
||||
|
||||
# Display list of available midi IN devices on the host, create and start an OUT instance to talk to each of these Midi IN devices
|
||||
midiout = rtmidi.MidiOut()
|
||||
|
|
@ -331,7 +412,7 @@ def OutConfig():
|
|||
OutDevice.append(OutObject(name, "generic", port))
|
||||
|
||||
#print "")
|
||||
print(len(OutDevice), "Out devices")
|
||||
print(GetTime(),len(OutDevice), "Out devices")
|
||||
#ListOutDevice()
|
||||
MidInsNumber = len(OutDevice)+1
|
||||
|
||||
|
|
@ -339,7 +420,7 @@ def ListOutDevice():
|
|||
|
||||
for item in OutObject.getinstances():
|
||||
|
||||
print(item.name)
|
||||
print(GetTime(),item.name)
|
||||
|
||||
def FindOutDevice(name):
|
||||
|
||||
|
|
@ -355,14 +436,14 @@ def FindOutDevice(name):
|
|||
def DelOutDevice(name):
|
||||
|
||||
Outnumber = Findest(name)
|
||||
print('deleting OutDevice', name)
|
||||
print(GetTime(),'deleting OutDevice', name)
|
||||
|
||||
if Outnumber != -1:
|
||||
print('found OutDevice', Outnumber)
|
||||
print(GetTime(),'found OutDevice', Outnumber)
|
||||
delattr(OutObject, str(name))
|
||||
print("OutDevice", Outnumber,"was removed")
|
||||
print(GetTime(),"OutDevice", Outnumber,"was removed")
|
||||
else:
|
||||
print("OutDevice was not found")
|
||||
print(GetTime(),"OutDevice was not found")
|
||||
|
||||
|
||||
|
||||
|
|
@ -387,7 +468,7 @@ class InObject():
|
|||
self._instances.add(weakref.ref(self))
|
||||
InObject.counter += 1
|
||||
|
||||
print("Adding InDevice name", self.name, "kind", self.kind, "port", self.port)
|
||||
print(GetTime(),"Adding InDevice name", self.name, "kind", self.kind, "port", self.port)
|
||||
|
||||
@classmethod
|
||||
def getinstances(cls):
|
||||
|
|
@ -407,16 +488,16 @@ class InObject():
|
|||
def InConfig():
|
||||
|
||||
print("")
|
||||
print("MIDIin...")
|
||||
print(GetTime(),"MIDIin...")
|
||||
|
||||
# client mode
|
||||
if debug > 0:
|
||||
if clientmode == True:
|
||||
print("midi3 in client mode")
|
||||
print(GetTime(),"midi3 in client mode")
|
||||
else:
|
||||
print("midi3 in server mode")
|
||||
print(GetTime(),"midi3 in server mode")
|
||||
|
||||
print("List and attach to available devices on host with OUT port :")
|
||||
print(GetTime(),"List and attach to available devices on host with OUT port :")
|
||||
|
||||
if platform == 'darwin':
|
||||
mido.set_backend('mido.backends.rtmidi/MACOSX_CORE')
|
||||
|
|
@ -437,7 +518,7 @@ def InConfig():
|
|||
try:
|
||||
#print name, name.find("RtMidi output"))
|
||||
if name.find("RtMidi output") > -1:
|
||||
print("No thread started for device", name)
|
||||
print(GetTime(),"No thread started for device", name)
|
||||
else:
|
||||
portin = object
|
||||
port_name = ""
|
||||
|
|
@ -460,7 +541,7 @@ def InConfig():
|
|||
traceback.print_exc()
|
||||
|
||||
#print "")
|
||||
print(InObject.counter, "In devices")
|
||||
print(GetTime(),InObject.counter, "In devices")
|
||||
#ListInDevice()
|
||||
|
||||
|
||||
|
|
@ -469,7 +550,7 @@ def ListInDevice():
|
|||
#print "known IN devices :"
|
||||
for item in InObject.getinstances():
|
||||
|
||||
print(item.name)
|
||||
print(GetTime(),item.name)
|
||||
print("")
|
||||
|
||||
def FindInDevice(name):
|
||||
|
|
@ -486,14 +567,14 @@ def FindInDevice(name):
|
|||
def DelInDevice(name):
|
||||
|
||||
Innumber = Findest(name)
|
||||
print('deleting InDevice', name)
|
||||
print(GetTime(),'deleting InDevice', name)
|
||||
|
||||
if Innumber != -1:
|
||||
print('found InDevice', Innumber)
|
||||
print(GetTime(),'found InDevice', Innumber)
|
||||
delattr(InObject, str(name))
|
||||
print("InDevice", Innumber,"was removed")
|
||||
print(GetTime(),"InDevice", Innumber,"was removed")
|
||||
else:
|
||||
print("InDevice was not found")
|
||||
print(GetTime(),"InDevice was not found")
|
||||
|
||||
|
||||
|
||||
|
|
@ -517,18 +598,18 @@ def MidiMsg(midimsg, mididest):
|
|||
|
||||
desterror = -1
|
||||
|
||||
print("jamidi3 got midimsg", midimsg, "for", mididest)
|
||||
print(GetTime(),"jamidi3 got midimsg", midimsg, "for", mididest)
|
||||
|
||||
for port in range(len(OutDevice)):
|
||||
# To mididest
|
||||
if midiname[port].find(mididest) != -1:
|
||||
if debug>0:
|
||||
print("jamidi 3 sending to name", midiname[port], "port", port, ":", midimsg)
|
||||
print(GetTime(),"jamidi 3 sending to name", midiname[port], "port", port, ":", midimsg)
|
||||
midiport[port].send_message(midimsg)
|
||||
desterror = 0
|
||||
|
||||
if desterror == -1:
|
||||
print("mididest",mididest, ": ** This midi destination doesn't exists **")
|
||||
print(GetTime(),"mididest",mididest, ": ** This midi destination doesn't exists **")
|
||||
|
||||
# send midi msg over ws.
|
||||
#if clientmode == True:
|
||||
|
|
@ -566,7 +647,7 @@ def findJamName(mididevice, midichan):
|
|||
|
||||
#print(v[0]["mididevice"],v[0]["midichan"], type(v[0]["midichan"]))
|
||||
if (v[0]["mididevice"] == mididevice) and (v[0]["midichan"] == midichan):
|
||||
print("Incoming event from", k, "xname", v[0]["xname"])
|
||||
print(GetTime(),"Incoming event from", k, "xname", v[0]["xname"])
|
||||
return v[0]["xname"]
|
||||
return "None"
|
||||
|
||||
|
|
@ -575,7 +656,7 @@ def findJamName(mididevice, midichan):
|
|||
def findJamDevices(name):
|
||||
|
||||
devices = []
|
||||
print ("searching", name)
|
||||
print (GetTime(),"searching", name)
|
||||
for (k, v) in Confs.items():
|
||||
|
||||
if v[0]["type"] == "mididevice":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue