From 14b872c57b54571fcf155ffced52f8b774ab088d Mon Sep 17 00:00:00 2001 From: michaelmariaott Date: Thu, 24 Nov 2022 10:46:35 +0000 Subject: [PATCH 1/6] updated repeat decorator --- iipyper/iipyper/__init__.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/iipyper/iipyper/__init__.py b/iipyper/iipyper/__init__.py index fdab666..0f433aa 100644 --- a/iipyper/iipyper/__init__.py +++ b/iipyper/iipyper/__init__.py @@ -1,4 +1,6 @@ import asyncio +import functools +import threading import fire @@ -6,19 +8,33 @@ from .osc import * _loop_fns = [] -# decorator to make a function loop -def repeat(time): + +def repeat(_time): + """ + decorator to repeat function every 'time' seconds + """ # close the decorator over time argument def decorator(f): # define the coroutine - async def g(): + @functools.wraps(f) + async def g(*args, **kwargs): # call `f` every `time` seconds while True: - f() - await asyncio.sleep(time) + t1 = time.time() + f(*args, **kwargs) + t2 = time.time() + delta_t = t2 - t1 + sleep_time = _time - delta_t + + if (sleep_time < 0): + print("Warning: repeat@ sleep time < 0") + await asyncio.sleep(0) + else: + await asyncio.sleep(sleep_time) + # track the coroutine in a global list _loop_fns.append(g) - + return f return decorator From 20660304e532e942a8634a007fc65f326120d6db Mon Sep 17 00:00:00 2001 From: michaelmariaott Date: Thu, 24 Nov 2022 13:34:53 +0000 Subject: [PATCH 2/6] fixed midi keyboard gui bug --- examples/mrp/sc/MRP.sc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/mrp/sc/MRP.sc b/examples/mrp/sc/MRP.sc index c4f81f5..667230d 100644 --- a/examples/mrp/sc/MRP.sc +++ b/examples/mrp/sc/MRP.sc @@ -276,7 +276,8 @@ a.set(\intensity, 0.7) win = Window.new("- MRP GUI -", Rect(100, 500, bounds.width+20, bounds.height+10), resizable:false).front; win.alwaysOnTop = true; - midikeyboardview = MIDIKeyboard.new(win, Rect(10, 70, 990, 160), 5, 36) + // Michael: MIDIKeyboard -> MRPMIDIKeyboard + midikeyboardview = MRPMIDIKeyboard.new(win, Rect(10, 70, 990, 160), 5, 36) .keyDownAction_({arg key; this.noteOn(key, 60); "Note ON :".post; key.postln; From 4b03bbe1992b194673136102139f15e090ce7b20 Mon Sep 17 00:00:00 2001 From: michaelmariaott Date: Thu, 24 Nov 2022 15:54:08 +0000 Subject: [PATCH 3/6] implemented allnotesof for mrp sim mrp listens to all incoming osc --- examples/mrp/sc/MRP.sc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/mrp/sc/MRP.sc b/examples/mrp/sc/MRP.sc index 667230d..3b70791 100644 --- a/examples/mrp/sc/MRP.sc +++ b/examples/mrp/sc/MRP.sc @@ -183,6 +183,7 @@ MRP { allNotesOff { notes.do({arg note; note.status = \note_off}); osc.sendMsg("/mrp/ui/allnotesoff"); + osc.sendMsg("/mrp/allnotesoff"); //this is the message actually used in the python library } simulator_ {arg boolean; if( boolean==true, { this.startMRPSimulator }, { this.stopMRPSimulator }) } @@ -237,25 +238,33 @@ a.set(\intensity, 0.7) }, { notes[msg[2]].simsynth.release; }); - }, '/mrp/midi', osc); + }, '/mrp/midi'); OSCdef(\brightness, {|msg, time, addr, recvPort| msg.postln; "brightness in simulation mode".postln; notes[msg[2]].simsynth.set(\brightness, msg[3]); - }, '/mrp/quality/brightness', osc); // def style + }, '/mrp/quality/brightness'); // def style OSCdef(\harmonic, {|msg, time, addr, recvPort| msg.postln; "harmonic in simulation mode".postln; notes[msg[2]].simsynth.set(\harmonic, msg[3]); - }, '/mrp/quality/harmonic', osc); // def style + }, '/mrp/quality/harmonic'); // def style OSCdef(\intensity, {|msg, time, addr, recvPort| msg.postln; "intensity in simulation mode".postln; notes[msg[2]].simsynth.set(\intensity, msg[3]); - }, '/mrp/quality/intensity', osc); // def style + }, '/mrp/quality/intensity'); // def style + + OSCdef(\allnotesoff, {|msg, time, addr, recvPort| + msg.postln; + "all notes off".postln; + notes.do({arg note, i; + notes[i].simsynth.release; + }); + }, '/mrp/allnotesoff'); } From dfe28ababa708dfcfda6b1041604f463ba0e5a73 Mon Sep 17 00:00:00 2001 From: michaelmariaott Date: Mon, 9 Jan 2023 13:24:01 +0100 Subject: [PATCH 4/6] fixed bug in note_on_numbers --- mrp/mrp/mrp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrp/mrp/mrp.py b/mrp/mrp/mrp.py index 3157ee7..e3d7d1c 100644 --- a/mrp/mrp/mrp.py +++ b/mrp/mrp/mrp.py @@ -422,7 +422,7 @@ def note_on_numbers(self): return numbers of notes that are on """ on_numbers = [] - for note in enumerate(self.notes): + for note in self.notes: if note['status'] == NOTE_ON: on_numbers.append(note['midi']['number']) return on_numbers From 57346be794cd8ed11a6f8a5cd51a1f3273dda205 Mon Sep 17 00:00:00 2001 From: michaelmariaott Date: Sat, 4 Feb 2023 11:19:57 +0100 Subject: [PATCH 5/6] commit last changes again From 06b18db4b4465d36457b20613da2eca235e64529 Mon Sep 17 00:00:00 2001 From: michaelmariaott Date: Sat, 4 Feb 2023 12:40:57 +0100 Subject: [PATCH 6/6] mrp.py update_qualities bug fix mrp.py new update_qualities_all, update_quality_all --- mrp/mrp/mrp.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/mrp/mrp/mrp.py b/mrp/mrp/mrp.py index e3d7d1c..664736b 100644 --- a/mrp/mrp/mrp.py +++ b/mrp/mrp/mrp.py @@ -278,6 +278,30 @@ def quality_update(self, note, quality, value, relative=False, channel=None): print('quality_update(): "quality" is not a string:', quality) return None + def quality_update_all(self, quality, value, relative=False, channel=None): + """ + Update quality of all active notes to a new value. + + Example + quality_update_all('brightness', 0.5) + + Args + quality (string): name of quality to update, must be same as key in osc_paths + value (float): value of quality + relative (bool): replace the value or add it to the current value + channel (int): which MIDI channel to send on + """ + if isinstance(quality, str): + active_notes = self.note_on_numbers() + changed_notes = [] + for note in active_notes: + changed_note = self.quality_update(self, note, quality, value, relative, channel) + changed_notes.append(changed_note) + return changed_notes + else: + print('quality_update(): "quality" is not a string:', quality) + return None + def qualities_update(self, note, qualities, relative=False, channel=None): """ Update a note's qualities to a new set of values. @@ -302,7 +326,7 @@ def qualities_update(self, note, qualities, relative=False, channel=None): channel = self.settings['channel'] tmp = self.notes[self.note_index(note)] for q, v in qualities.items(): - if isinstance(value, list) or isinstance(value, np.ndarray): # e.g. /harmonics/raw + if isinstance(v, list) or isinstance(v, np.ndarray): # e.g. /harmonics/raw if relative is True: print('quality_update(): relative updating of lists not supported') else: @@ -325,7 +349,35 @@ def qualities_update(self, note, qualities, relative=False, channel=None): else: print('quality_update(): "qualities" is not an object:', note, qualities) return None + + def qualities_update_all(self, qualities, relative=False, channel=None): + """ + Update the qualities for all active notes to a new set of values. + Example + qualities_update_all({ + 'brightness': 0.5, + 'intensity': 0.6, + 'harmonics_raw': [0.2, 0.3, 0.4] + }) + + Args + qualities (dict): dict of qualities in key (string):value (float) pairs to update, + must be same as key in osc_paths + relative (bool): replace the value or add it to the current value + channel (int): which MIDI channel to send on + """ + if isinstance(qualities, dict): + active_notes = self.note_on_numbers() + changed_notes = [] + for note in active_notes: + changed_note = self.qualities_update(self, qualities, relative, channel) + changed_notes.append(changed_note) + return changed_notes + else: + print('quality_update(): "qualities" is not an object:', note, qualities) + return None + """ /mrp/pedal """