From 70dbc4e9545b11248f350448cc1c6b45ccabdba2 Mon Sep 17 00:00:00 2001 From: Tristan Rowley Date: Fri, 21 Feb 2020 16:49:58 +0000 Subject: [PATCH] tidy up LFOModulation to make it easier to add selectable formulas later --- plugins/LFOModulation.py | 56 ++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/plugins/LFOModulation.py b/plugins/LFOModulation.py index 3b6865e..a51655d 100644 --- a/plugins/LFOModulation.py +++ b/plugins/LFOModulation.py @@ -1,12 +1,17 @@ +import math import data_centre.plugin_collection from data_centre.plugin_collection import ActionsPlugin, SequencePlugin, DisplayPlugin class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): disabled = False + MAX_LFOS = 4 + + # active = True (toggle_lfo_active) to enable sending of modulation active = False - level = [0.0, 0.0, 0.0, 0.0] + # for keeping track of LFO levels + level = [0.0]*MAX_LFOS #, 0.0, 0.0, 0.0] stop_flag = False pause_flag = False @@ -17,6 +22,8 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): self.pc.shaders.root.after(1000, self.run_automation) + + # DisplayPlugin methods def get_display_modes(self): return ['LFOMODU','NAV_LFO'] @@ -24,18 +31,23 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): from tkinter import Text, END #super(DisplayPlugin).show_plugin(display, display_mode) display.display_text.insert(END, '{} \n'.format(display.body_title)) - display.display_text.insert(END, "test from LFOModulationPlugin!\n") + display.display_text.insert(END, "LFOModulationPlugin ") - display.display_text.insert(END, "\tACTIVE\n" if self.active else "not active\n") + display.display_text.insert(END, "ACTIVE\n" if self.active else "not active\n\n") - for i,value in enumerate(self.level): - display.display_text.insert(END, "{} level: {:03.2f}%\n".format(i,value)) + for lfo,value in enumerate(self.level): + display.display_text.insert(END, "lfo {} level: {:03.2f}%\t".format(lfo,value)) + display.display_text.insert(END, "%s\n" %self.last_lfo_status[lfo]) + display.display_text.insert(END, "\t%s\n" % self.formula[lfo]) + + # ActionsPlugin methods @property def parserlist(self): return [ ( r"^set_lfo_modulation_([0-3])_level$", self.set_lfo_modulation_level ), ( r"^toggle_lfo_active$", self.toggle_lfo_active ) + # TODO: changing formulas and LFO modes, speed ] def set_lfo_modulation_level(self, slot, value): @@ -44,6 +56,32 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): def toggle_lfo_active(self): self.active = not self.active + # Formula handling for generating automation + # mapping 0-3 to match the LFO + # TODO: save & load this to config file, make editable + formula = [ + "f_sin", + "f_inverted_sin", + "f_sin", + "f_inverted_sin" + ] + + # run the formula for the stored lfo configuration + last_lfo_status = [None]*MAX_LFOS # for displaying status + def getLFO(self, position, lfo): + lfo_value = getattr(self,self.formula[lfo])(position, self.level[lfo]) + self.last_lfo_status[lfo] = " output {:03.2f}\tat T{:03.2f}".format(lfo_value*100.0, position) + return lfo_value + + # built-in waveshapes + # todo: more of the these, and better! + def f_sin(self, position, level): + return 0.5+(0.5*level * math.sin(position*math.pi)) + + def f_inverted_sin(self, position, level): + return self.f_sin(1.0-position, 1.0-level) + + # SequencePlugin methods def run_sequence(self, position): import time now = time.time() @@ -53,10 +91,6 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): if not self.active: return - #print("run_automation position %s!"%position) - import math - self.pc.actions.call_method_name("modulate_param_0_to_amount_continuous", 0.5+(0.5*self.level[0] * math.sin(position*math.pi))) #(now*100)%300) - self.pc.actions.call_method_name("modulate_param_1_to_amount_continuous", 0.5+(0.5*self.level[1] * math.cos(position*math.pi)/math.pi)) - self.pc.actions.call_method_name("modulate_param_2_to_amount_continuous", 0.5+(0.5*self.level[2] * math.atan(position*math.pi)/math.pi)) - self.pc.actions.call_method_name("modulate_param_3_to_amount_continuous", 0.5+(0.5*self.level[3] * math.sin(math.sin(position*math.pi)*math.pi))) + for i in range(0,4): + self.pc.actions.call_method_name("modulate_param_%s_to_amount_continuous"%i, self.getLFO(position, i))