mirror of
https://github.com/cyberboy666/r_e_c_u_r.git
synced 2025-12-12 11:20:15 +01:00
tidy up LFOModulation to make it easier to add selectable formulas later
This commit is contained in:
@@ -1,12 +1,17 @@
|
|||||||
|
import math
|
||||||
import data_centre.plugin_collection
|
import data_centre.plugin_collection
|
||||||
from data_centre.plugin_collection import ActionsPlugin, SequencePlugin, DisplayPlugin
|
from data_centre.plugin_collection import ActionsPlugin, SequencePlugin, DisplayPlugin
|
||||||
|
|
||||||
class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
|
class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
|
||||||
disabled = False
|
disabled = False
|
||||||
|
|
||||||
|
MAX_LFOS = 4
|
||||||
|
|
||||||
|
# active = True (toggle_lfo_active) to enable sending of modulation
|
||||||
active = False
|
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
|
stop_flag = False
|
||||||
pause_flag = False
|
pause_flag = False
|
||||||
@@ -17,6 +22,8 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
|
|||||||
|
|
||||||
self.pc.shaders.root.after(1000, self.run_automation)
|
self.pc.shaders.root.after(1000, self.run_automation)
|
||||||
|
|
||||||
|
|
||||||
|
# DisplayPlugin methods
|
||||||
def get_display_modes(self):
|
def get_display_modes(self):
|
||||||
return ['LFOMODU','NAV_LFO']
|
return ['LFOMODU','NAV_LFO']
|
||||||
|
|
||||||
@@ -24,18 +31,23 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
|
|||||||
from tkinter import Text, END
|
from tkinter import Text, END
|
||||||
#super(DisplayPlugin).show_plugin(display, display_mode)
|
#super(DisplayPlugin).show_plugin(display, display_mode)
|
||||||
display.display_text.insert(END, '{} \n'.format(display.body_title))
|
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):
|
for lfo,value in enumerate(self.level):
|
||||||
display.display_text.insert(END, "{} level: {:03.2f}%\n".format(i,value))
|
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
|
@property
|
||||||
def parserlist(self):
|
def parserlist(self):
|
||||||
return [
|
return [
|
||||||
( r"^set_lfo_modulation_([0-3])_level$", self.set_lfo_modulation_level ),
|
( r"^set_lfo_modulation_([0-3])_level$", self.set_lfo_modulation_level ),
|
||||||
( r"^toggle_lfo_active$", self.toggle_lfo_active )
|
( r"^toggle_lfo_active$", self.toggle_lfo_active )
|
||||||
|
# TODO: changing formulas and LFO modes, speed
|
||||||
]
|
]
|
||||||
|
|
||||||
def set_lfo_modulation_level(self, slot, value):
|
def set_lfo_modulation_level(self, slot, value):
|
||||||
@@ -44,6 +56,32 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
|
|||||||
def toggle_lfo_active(self):
|
def toggle_lfo_active(self):
|
||||||
self.active = not self.active
|
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):
|
def run_sequence(self, position):
|
||||||
import time
|
import time
|
||||||
now = time.time()
|
now = time.time()
|
||||||
@@ -53,10 +91,6 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
|
|||||||
|
|
||||||
if not self.active:
|
if not self.active:
|
||||||
return
|
return
|
||||||
#print("run_automation position %s!"%position)
|
|
||||||
|
|
||||||
import math
|
for i in range(0,4):
|
||||||
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_%s_to_amount_continuous"%i, self.getLFO(position, i))
|
||||||
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)))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user