diff --git a/data_centre/data.py b/data_centre/data.py index f3871fb..07d977f 100644 --- a/data_centre/data.py +++ b/data_centre/data.py @@ -467,7 +467,7 @@ class Data(object): display_modes.append(["SHADERS",'NAV_SHADERS']) if self.settings['shader']['USE_SHADER_BANK']['value'] == 'enabled' and ["SHADERS",'NAV_SHADERS'] in display_modes: display_modes.append(["SHDR_BNK",'PLAY_SHADER']) - display_modes.append(["MOD_BNK",["NAV_MOD","PLAY_SHADER"]]) ## allow override, but fall back to PLAY_SHADER controls + display_modes.append(["SHDR_MOD",["NAV_MOD","PLAY_SHADER"]]) ## allow override, but fall back to PLAY_SHADER controls if self.settings['detour']['TRY_DEMO']['value'] == 'enabled': display_modes.append(["FRAMES",'NAV_DETOUR']) if self.settings['system'].setdefault('USE_PLUGINS', diff --git a/display_centre/display.py b/display_centre/display.py index 1923d5b..d46e95b 100644 --- a/display_centre/display.py +++ b/display_centre/display.py @@ -91,7 +91,7 @@ class Display(object): self._load_shaders() elif self.data.display_mode == 'SHDR_BNK': self._load_shader_bank() - elif self.data.display_mode == 'MOD_BNK': + elif self.data.display_mode == 'SHDR_MOD': self._load_modulation_bank() elif self.data.display_mode == 'FRAMES': self._load_detour() @@ -102,7 +102,7 @@ class Display(object): for plugin in self.data.plugins.get_plugins(DisplayPlugin): if plugin.is_handled(self.data.display_mode): self._load_plugin_page(self.data.display_mode, plugin) - self.display_text.tag_add("DISPLAY_MODE", 4.18, 4.28) + self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29) self.display_text.tag_add("COLUMN_NAME", 5.0, 6.0) @@ -464,7 +464,7 @@ class Display(object): if convert: value = (value * 2.0) - 1.0 # convert 0 to 1 to -1 to +1 output = u"" - if value==0.0: + if value==0.0 or (value>=-0.02 and value<=0.02): output+=u"\u23f9" # stopped elif value<=-0.5: output+=u"\u00AB" # fast reverse diff --git a/json_objects/keypad_action_mapping.json b/json_objects/keypad_action_mapping.json index a2120e0..2f991de 100644 --- a/json_objects/keypad_action_mapping.json +++ b/json_objects/keypad_action_mapping.json @@ -35,7 +35,8 @@ "NAV_DETOUR": ["toggle_detour_play"], "PLAY_SHADER": ["toggle_shaders", "toggle_shader_speed"], "NAV_LFO": ["toggle_lfo_active"], - "NAV_SND": ["toggle_sound_react_active"] + "NAV_SND": ["toggle_sound_react_active"], + "NAV_QKSH": ["qksh_toggle_display_live"] }, "d": { "DEFAULT": ["switch_to_next_player", "toggle_player_mode"], diff --git a/plugins/LFOModulation.py b/plugins/LFOModulation.py index dc779d4..85d1b6b 100644 --- a/plugins/LFOModulation.py +++ b/plugins/LFOModulation.py @@ -36,11 +36,11 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): display.display_text.insert(END, "ACTIVE" if self.active else "not active") - display.display_text.insert(END, "\tSpeed: {:03.2f}\n\n".format(self.speed)) + display.display_text.insert(END, "\tSpeed: {:4.2f}% {}\n\n".format(self.speed*100, display.get_speed_indicator(self.speed/2.0, convert=False))) 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, "lfo {} level: {:4.2f}% {}\t".format(lfo,value*100,display.get_bar(value))) + display.display_text.insert(END, "{}\t{}\n".format(self.last_lfo_status[lfo], display.get_bar(self.last_lfo_value[lfo]))) display.display_text.insert(END, "\t%s\n" % self.formula[lfo]) @@ -69,16 +69,19 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): formula = [ "f_sin", "f_double_cos", - "f_sin", - "f_double_cos" + "f_invert_sin", + #"f_invert_double_cos", + "f_linear" ] # run the formula for the stored lfo configuration last_lfo_status = [None]*MAX_LFOS # for displaying status + last_lfo_value = [None]*MAX_LFOS #lfo_speed = [1.0]*MAX_LFOS def getLFO(self, position, lfo): lfo_value = getattr(self,self.formula[lfo])(position, self.level[lfo]) - self.last_lfo_status[lfo] = " sent {:03.1f}%".format(lfo_value*100.0) + self.last_lfo_value[lfo] = lfo_value + self.last_lfo_status[lfo] = "sent {:03.1f}%".format(lfo_value*100.0) return lfo_value # built-in waveshapes @@ -92,9 +95,17 @@ class LFOModulationPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): return value + def f_invert_sin(self, position, level): + return 1.0 - self.f_sin(position, level) + def f_double_cos(self, position, level): return self.f_sin(math.cos(position*math.pi), level) - #return self.f_sin(math.acos(position), level) + + def f_invert_double_cos(self, position, level): + return 1.0 - self.f_double_cos(position, level) + + def f_linear(self, position, level): + return position * level # SequencePlugin methods def run_sequence(self, position): diff --git a/plugins/ShaderLoopRecordPlugin.py b/plugins/ShaderLoopRecordPlugin.py index f2a0bf4..b9760a8 100644 --- a/plugins/ShaderLoopRecordPlugin.py +++ b/plugins/ShaderLoopRecordPlugin.py @@ -72,8 +72,9 @@ class ShaderLoopRecordPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): status+="\n" display.display_text.insert(END, status) - display.display_text.insert(END, ("Position:\t{:03.2f}%\t[{:15s}]".format(self.position,("#"*int(self.position*15))))) - display.display_text.insert(END, (" Speed: {:03.2f}%\n".format(self.speed*100))) + display.display_text.insert(END, ("Position:\t{:3.0f}%\t[{:12s}]".format(self.position*100.0,("#"*int(self.position*12))))) + #display.display_text.insert(END, (" Speed: {:03.2f}%\n".format(self.speed*100))) + display.display_text.insert(END, (" Speed:{} {:3.0f}%\n".format(display.get_speed_indicator(self.speed/2,convert=False),self.speed*100))) if self.speed==0.0: display.display_text.insert(END, ("Duration:\tinfinity!\n")) else: diff --git a/plugins/ShaderQuickPresetPlugin.py b/plugins/ShaderQuickPresetPlugin.py index 154bfa3..cd7c905 100644 --- a/plugins/ShaderQuickPresetPlugin.py +++ b/plugins/ShaderQuickPresetPlugin.py @@ -6,6 +6,7 @@ from plugins.frame_manager import Frame class ShaderQuickPresetPlugin(ActionsPlugin,DisplayPlugin): #,SequencePlugin): MAX_PRESETS = 8 + display_live_on = False def __init__(self, plugin_collection): super().__init__(plugin_collection) @@ -38,8 +39,12 @@ class ShaderQuickPresetPlugin(ActionsPlugin,DisplayPlugin): #,SequencePlugin): ( r"switch_to_preset_([0-%i])"%self.MAX_PRESETS, self.switch_to_preset ), ( r"select_preset_([0-%i])"%self.MAX_PRESETS, self.select_preset ), ( r"clear_current_preset", self.clear_current_preset ), + ( r"qksh_toggle_display_live", self.toggle_display_live ) ] + def toggle_display_live(self): + self.display_live_on = not self.display_live_on + # DisplayPlugin methods def get_display_modes(self): return ['QUIKSHDR',['NAV_QKSH','PLAY_SHADER']] @@ -48,7 +53,7 @@ class ShaderQuickPresetPlugin(ActionsPlugin,DisplayPlugin): #,SequencePlugin): 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, "ShaderQuickPresetPlugin!") + display.display_text.insert(END, u"ShaderQuickPresetPlugin") #display.display_text.insert(END, " status = "Selected:" @@ -61,16 +66,23 @@ class ShaderQuickPresetPlugin(ActionsPlugin,DisplayPlugin): #,SequencePlugin): status += "_" else: status += "=" - display.display_text.insert(END, " [" + status + "]\n\n") + display.display_text.insert(END, " [" + status + "]\n") # display a basic summary of each preset """for i,preset in enumerate(self.presets): display.display_text.insert(END, "%s\n" % preset.get_active_shader_names()) #display.display_text.insert(END, "%s: %s %s %s" % """ + if self.display_live_on: + display.display_text.insert(END, "Showing LIVE\n") + else: + display.display_text.insert(END, "Showing stored preset slot %s\n" % self.selected_preset) + ## show a summary of the selected preset if self.selected_preset is not None: - for line in self.presets[self.selected_preset].get_frame_summary(): + # TODO: switch to display current settings + #for line in self.pc.fm.get_live_frame().get_frame_summary(): + for line in (self.presets[self.selected_preset] if not self.display_live_on else self.pc.fm.get_live_frame()).get_frame_summary(): display.display_text.insert(END, "%s\n" % line) def store_next_preset(self): diff --git a/plugins/SoundReactPlugin.py b/plugins/SoundReactPlugin.py index 424a20a..b58cf15 100644 --- a/plugins/SoundReactPlugin.py +++ b/plugins/SoundReactPlugin.py @@ -110,14 +110,15 @@ class SoundReactPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): display.display_text.insert(END, "ACTIVE\n" if self.active else "not active\n") #display.display_text.insert(END, "\tSpeed: {:03.2f}\n\n".format(self.speed)) - + for sourcename in sorted(self.sources): - value = self.display_values.get(sourcename) or "{:03.2f}%".format(self.values.get(sourcename,0)*100) or "None" - value += "\t" + value = "{:8}:\t".format(sourcename) for i,level in enumerate(self.levels[sourcename]): g = "ABCD"[i]+'%s '%self.pc.display.get_bar(level) value += g - display.display_text.insert(END, "{}:\t{}\n".format(sourcename,value)) + value += "\t" + value += self.display_values.get(sourcename) or "{:4.2f}%".format(self.values.get(sourcename,0)*100) or "None" + display.display_text.insert(END,value + "\n") """display.display_text.insert(END, "%s\n" %self.last_lfo_status[lfo]) display.display_text.insert(END, "\t%s\n" % self.formula[lfo])""" @@ -176,8 +177,12 @@ class SoundReactPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): bars="#"*int(50*value) if self.DEBUG: print("energy:\t\t%05d %s\t(converted to %s)"%(peak,bars,value)) - g = self.pc.display.get_bar(value) - self.display_values['energy'] = "{} g{:03.2f} t{:03.2f} d{:03.2f}".format(g, self.config['energy']['gain'], self.config['energy']['threshold'], self.config['energy'].setdefault('triggerthreshold',0.15)) + self.display_values['energy'] = "{} gn:{} trsh:{} trg:{}".format( + self.pc.display.get_bar(value), + self.pc.display.get_bar(self.config['energy']['gain']), + self.pc.display.get_bar(self.config['energy']['threshold']), + self.pc.display.get_bar(self.config['energy'].setdefault('triggerthreshold',0.15)) + ) return value diff --git a/plugins/frame_manager.py b/plugins/frame_manager.py index d8fbb0d..20e065a 100644 --- a/plugins/frame_manager.py +++ b/plugins/frame_manager.py @@ -99,47 +99,51 @@ class Frame: if self.get('selected_shader_slots') is None: return ['-']*3 if self.get('selected_shader') is not None: - return [ shader['name'] for shader in self.get('selected_shader') ] - return [ self.pc.data.shader_bank_data[layer][x].get('name') if x is not None else '-'\ + return [ shader['name'].strip() for shader in self.get('selected_shader') ] + return [ self.pc.data.shader_bank_data[layer][x].get('name').strip() if x is not None else '-'\ for layer,x in enumerate(self.f.get('selected_shader_slots',[None]*3)) ] def get_frame_summary(self): summary = [] - not_shown = [] + not_shown = {} + # list the recorded shader info in compact format names = self.get_active_shader_names() for layer in range(0,3): # number of shader layers s = "%s " % layer s += "[" - for i in range(10): # number of shader slots per layer - selected = (i==self.get('selected_shader_slots',[-1]*3)[layer]) or\ - (self.get('selected_shader') is not None and self.pc.data.shader_bank_data[layer][i]['name'] == self.get('selected_shader')[layer]['name']) - - if selected: - s += "#" - else: - s += "-" + s += self.pc.display.get_compact_indicators([\ + (i==self.get('selected_shader_slots',[-1]*3)[layer]) or\ + (self.get('selected_shader') is not None and self.pc.data.shader_bank_data[layer][i]['name'] == self.get('selected_shader')[layer]['name'])\ + for i in range(10)\ + ]) s += "]" - if self.get('selected_shader'): - s += self.get('selected_shader')[layer].get('name') + if self.get('layer_active_status') is not None: s += " %s " % (self.f.get('layer_active_status',['-']*3)[layer]) - if self.get('shader_speeds') is not None: - s += self.pc.display.get_bar(self.f.get('shader_speeds',[0.0]*3)[layer]) + + if self.get('selected_shader'): + s += "{:14.14}".format(self.get('selected_shader')[layer].get('name').replace('.frag','').strip()) + s += " " + self.get_shader_param_summary(layer) + " " - s += "{:10s}".format(names[layer]) + + if self.get('shader_speeds') is not None: + s += self.pc.display.get_speed_indicator(self.get('shader_speeds',[0.0]*3)[layer]) + summary.append(s) - + # handle summarising the rest of the recorded shader info, two-to-a-line where possible count = 0 line = "" for key,d in sorted(self.f.items()): - if key in ["layer_active_status","shader_params","shader_speeds","selected_shader_slots"]: - # skip this as dealt with above + if key in ["selected_shader","layer_active_status","shader_params","shader_speeds","selected_shader_slots"]: + # skip these as dealt with above pass elif key in ["WJSendPlugin"]: - not_shown.append(key) + # tends to be heavy so save it for later + # TODO: ask plugin to format the data for summary? + not_shown[key] = d else: line += "%s: %s" % (key, d) count += 1 @@ -151,8 +155,9 @@ class Frame: if line != "": summary.append(line) + # add 'not shown' items if len(not_shown)>0: - summary.append(','.join(not_shown)) + summary.append(','.join(not_shown.keys())) return summary @@ -190,11 +195,6 @@ class Frame: self.pc.shaders.selected_shader_list[self.pc.data.shader_layer] = preset.f.get('selected_shader')[layer].copy() self.pc.shaders.load_selected_shader() - """for layer, slot in enumerate(preset.f.get('selected_shader',[])): - if slot is not None: - self.pc.shaders.selected_shader_list[self.pc.data.shader_layer] = slot - self.pc.shaders.load_selected_shader()""" - for (layer, active) in enumerate(preset.f.get('layer_active_status',[])): # print ("got %s layer with status %s " % (layer,active)) if active=='▶':