Merge branch 'feature_plugins' of https://github.com/langolierz/r_e_c_u_r into feature_plugins

This commit is contained in:
langolierz
2020-03-01 19:17:33 +00:00
8 changed files with 85 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
# Auto-generated Actions list
Sat 29 Feb 16:00:23 UTC 2020
Sat 29 Feb 17:41:32 UTC 2020
for branch=feature_plugins
@@ -238,6 +238,7 @@ for branch=feature_plugins
* wj_select_previous_command (from WJSendPlugin)
* wj_select_next_argument (from WJSendPlugin)
* wj_select_previous_argument (from WJSendPlugin)
* wj_reset_modulation (from WJSendPlugin)
----

View File

@@ -175,6 +175,21 @@ class Actions(object):
if self.video_driver.current_player.show_toggle_on == self.video_driver.next_player.show_toggle_on:
self.video_driver.next_player.toggle_show()
def set_display_mode(self, display_mode):
mapmodes = {
'shader': 'SHADERS',
'shader_bank': 'SHDR_BNK'
}
if display_mode in mapmodes:
display_mode = mapmodes[display_mode]
display_mode = display_mode.upper()
display_modes = self.data.get_display_modes_list(with_nav_mode=True)
for i,dm in enumerate(display_modes):
if display_mode in dm:
self.data.display_mode = display_modes[i][0]
self.data.control_mode = display_modes[i][1]
def cycle_display_mode(self):
display_modes = self.data.get_display_modes_list(with_nav_mode=True)
@@ -1019,6 +1034,7 @@ class Actions(object):
( r"^select_shader_modulation_slot_([0-3])$", self.shaders.select_shader_modulation_slot ),
( r"^set_shader_speed_layer_offset_([0-2])_amount$", self.shaders.set_speed_offset_to_amount ),
( r"^set_shader_speed_layer_([0-2])_amount$", self.shaders.set_speed_layer_to_amount ),
( r"^set_display_mode_([a-zA-Z_]*)$", self.set_display_mode )
}
def detect_types(self, args):

View File

@@ -57,6 +57,7 @@ class Data(object):
### state data
self.auto_repeat_on = True
self.function_on = False
self.is_display_held = False
self.display_mode = "SAMPLER"
self.control_mode = 'PLAYER'
self.bank_number = 0
@@ -92,7 +93,8 @@ class Data(object):
self.shader_bank_data = [self.create_empty_shader_bank() for i in range(3)]
if os.path.isfile(self.PATH_TO_DATA_OBJECTS + self.SHADER_BANK_DATA_JSON):
self.shader_bank_data = self._read_json(self.SHADER_BANK_DATA_JSON)
self.settings = self.default_settings = self._read_json(self.DEFAULT_SETTINGS_JSON)
self.settings = self._read_json(self.DEFAULT_SETTINGS_JSON)
self.default_settings = self.settings.copy()
if os.path.isfile(self.PATH_TO_DATA_OBJECTS + self.SETTINGS_JSON):
self.settings = self._read_json(self.SETTINGS_JSON)

View File

@@ -209,7 +209,10 @@ sudo cp -R * /usr/local/
- install node-osc `npm install node-osc --save` (do we need this ?)
- install osc-js `npm install node-osc --save`
install serial package : `pip3 install pyserial`
### install some plugin packages:
- install serial package : `pip3 install pyserial`
- install pyaudio : `sudo apt-get install python3-pyaudio`
# wjhat follows is info, not instructions for setup:

View File

@@ -60,7 +60,8 @@
"DEFAULT": ["set_the_shader_param_2_layer_offset_0_continuous","set_shader_speed_layer_1_amount"],
"NAV_DETOUR": ["set_detour_end_continuous"],
"NAV_WJMX": ["wj_set_colour_T:x"],
"NAV_LFO": ["set_lfo_modulation_2_level"]
"NAV_LFO": ["set_lfo_modulation_2_level"],
"NAV_SND": ["sound_set_config_energy_triggerthreshold"]
},
"control_change 51": {
"DEFAULT": ["set_the_shader_param_3_layer_offset_0_continuous","set_shader_speed_layer_2_amount"],
@@ -152,7 +153,8 @@
"DEFAULT": ["switch_to_preset_7","select_preset_7"]
},
"note_on 81": {
"DEFAULT": ["","reset_selected_modulation"]
"DEFAULT": ["","reset_selected_modulation"],
"NAV_WJMX": ["","wj_reset_modulation"]
},
"note_on 82": {
"DEFAULT": ["toggle_shader_layer_0","select_shader_modulation_slot_0"]
@@ -282,7 +284,7 @@
"DEFAULT": ["send_serial_macro_0","send_serial_macro_1"]
},
"note_on 93": {
"DEFAULT": ["smooth_selected_clip","send_random_settings"]
"DEFAULT": ["set_display_mode_settings","set_display_mode_shader"]
}
}

View File

@@ -4,6 +4,9 @@ from data_centre.plugin_collection import ActionsPlugin, SequencePlugin, Display
import pyaudio
import numpy as np
from random import randint
from statistics import mean
#import matplotlib.pyplot as plt
np.set_printoptions(suppress=True) # don't use scientific notationn
@@ -91,13 +94,14 @@ class SoundReactPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
#display.display_text.insert(END, "\nLevels:%s\n\n" % self.levels)
display.display_text.insert(END, "\n\n\n")
energy_history = []
def run_sequence(self, position):
# position is irrelvant for this plugin, we just want to run continuously
if not self.active:
return
data = np.fromstring(self.stream.read(self.CHUNK, exception_on_overflow = False),dtype=np.int16)
previous_value = {}
for sourcename in self.sources:
value = self.sources[sourcename](data)
@@ -107,8 +111,24 @@ class SoundReactPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
for slot,level in enumerate(self.levels.get(sourcename,[])):
if level>0.0 and self.values.get(sourcename)!=self.last_values.get(sourcename):
self.pc.actions.call_method_name("modulate_param_%s_to_amount_continuous"%slot, self.values[sourcename])
previous_value[sourcename] = self.last_values.get(sourcename) or value
self.last_values[sourcename] = self.values[sourcename]
if sourcename is 'energy' and self.last_values.get('energy') is not None:
diff = abs(self.last_values.get('energy',value)-previous_value.get(sourcename,value)) #mean(self.energy_history))
if len(self.energy_history)>5: #self.duration:
meandiff = abs(diff-mean(self.energy_history[:int(len(self.energy_history)/2)]))
#print (" diff is %s, meandiff %s" % (diff, meandiff))
if meandiff>=self.config['energy'].get('triggerthreshold',0.15):
self.energy_history = []
print ("\n>>>>>>Triggering dynamic change for meandiff %s?\n" % meandiff)
#self.pc.actions.call_method_name("load_slot_%s_into_next_player"%randint(0,9))
self.energy_history.append(diff) #self.values.get(sourcename,0.0))
#print("logging %s" % diff) #self.values.get(sourcename,0.0))
config.setdefault('energy',{})['gain'] = 0.5 # how much to multiply signal by
config.setdefault('energy',{})['threshold'] = 0.5 # subtract from post-gain signal (hence ignore all values below)
GAIN_MULT = 1.0
@@ -128,7 +148,7 @@ class SoundReactPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
if self.DEBUG: print("energy:\t\t%05d %s\t(converted to %s)"%(peak,bars,value))
bar = u"_\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588"
g = '%s'%bar[int(value*(len(bar)-1))]
self.display_values['energy'] = "{} g{:03.2f} t{:03.2f}".format(g, self.config['energy']['gain'], self.config['energy']['threshold'])
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))
return value
@@ -142,8 +162,8 @@ class SoundReactPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin):
freqPeak = freq[np.where(fft==np.max(fft))[0][0]]+1
if freqPeak<400:
return False
value = freqPeak/16000
value = value**16/16
value = freqPeak/2000 # ?
#value = (value**16)
if self.DEBUG: print("peak frequency:\t%d\tHz\t(converted to %s)"%(freqPeak,value))
self.display_values['peakfreq'] = ("%d Hz\t"%freqPeak) + "{:03.2f}".format(value)

View File

@@ -53,7 +53,7 @@ class WJSendPlugin(ActionsPlugin, SequencePlugin, DisplayPlugin, ModulationRecei
def save_presets(self):
for cmd,struct in self.commands.items():
self.presets.setdefault('modulation_levels',{})[cmd] = struct.get('modulation',[])
self.presets.setdefault('modulation_levels',{})[cmd] = struct.get('modulation',[{},{},{},{}])
self.pc.update_json(self.PRESET_FILE_NAME, self.presets)
def quit_plugin(self):
@@ -106,9 +106,10 @@ class WJSendPlugin(ActionsPlugin, SequencePlugin, DisplayPlugin, ModulationRecei
# so that they update with the new modulation value
to_send = {}
for queue,cmd in sorted(self.command_by_queue.items(),reverse=True):
if cmd.get('modulation') is not None:
#if self.DEBUG: print("\tparam %s, checking modulation %s" % (param, cmd.get('modulation')))
if len(cmd.get('modulation')[param])>0:
cmd.setdefault('modulation',[{},{},{},{}])
if self.DEBUG: print("\tparam %s, checking modulation %s" % (param, cmd.get('modulation')))
if len(cmd['modulation'][param])>0:
if self.DEBUG: print("\tParam %s has modulation! sending update of values? %s" %
(param, [cmd['arguments'][y] for y in cmd['arg_names'] ]))
#self.send_buffered(cmd['queue'], cmd['form'], [x for x in [ cmd['arguments'][y] for y in cmd['arg_names'] ] ], record=False)
@@ -138,7 +139,7 @@ class WJSendPlugin(ActionsPlugin, SequencePlugin, DisplayPlugin, ModulationRecei
for arg_name in cmd['arg_names']:
indicator = " " if cmd['arg_names'].index(arg_name)!=self.selected_argument_index else ">"
output += "%s%s: "%(indicator,arg_name)
for slot,mods in enumerate(cmd.get('modulation',[{},{},{},{}])):
for slot,mods in enumerate(cmd.setdefault('modulation',[{},{},{},{}])):
#if arg_name in mods:
v = mods.get(arg_name,0.0)
g = '%s'%bar[int(v*(len(bar)-1))]
@@ -274,9 +275,14 @@ class WJSendPlugin(ActionsPlugin, SequencePlugin, DisplayPlugin, ModulationRecei
( r"^wj_select_next_command$", self.select_next_command ),
( r"^wj_select_previous_command$", self.select_previous_command ),
( r"^wj_select_next_argument$", self.select_next_argument ),
( r"^wj_select_previous_argument$", self.select_previous_argument )
( r"^wj_select_previous_argument$", self.select_previous_argument ),
( r"^wj_reset_modulation$", self.reset_modulation_levels )
]
def reset_modulation_levels(self):
for cmd,struct in self.commands.items():
struct['modulation'] = [{},{},{},{}]
def set_modulation_command_argument_level(self, command_name, argument_name, slot, level):
if self.DEBUG: print("set_modulation_command_argument_level(%s, %s, %s, %s)" % (command_name, argument_name, slot, level))
if not argument_name: self.commands[command_name]['arg_names'][0] #argument_name = 'v'
@@ -324,6 +330,7 @@ class WJSendPlugin(ActionsPlugin, SequencePlugin, DisplayPlugin, ModulationRecei
def modulate_arguments(self, command, args):
args = args.copy()
#if self.DEBUG: print("modulate_arguments passed %s and\n\t%s" % (command,args))
# TODO: rewrite this so that it combines multiple inputs and averages them
for slot in range(0,4):
modlevels = command.get('modulation',[{},{},{},{}])[slot]
#if self.DEBUG: print("\tfor modulate_arguments for slot %s got modlevels: %s" % (slot, modlevels))
@@ -366,7 +373,7 @@ class WJSendPlugin(ActionsPlugin, SequencePlugin, DisplayPlugin, ModulationRecei
'form': 'VMM:{:02X}',
'arg_names': [ 'v' ],
'arguments': { 'v': 127 },
'modulation': [ { 'v': 1.0 }, {}, {}, {} ]
#'modulation': [ { 'v': 1.0 }, {}, {}, {} ]
},
'back_colour': {
'name': 'Back colour/matte HSV',

View File

@@ -21,11 +21,15 @@ class NumpadInput(object):
def on_key_press(self, event):
numpad = list(string.ascii_lowercase[0:19])
if event.char is 'h': # DISP button
self.data.is_display_held = True
if event.char is '.' or event.char is 'z':
self.actions.quit_the_program()
if event.char is 's':
event.char = self.on_0_key_press()
elif event.char in numpad:
if event.char in numpad:
self.run_action_for_mapped_key(event.char)
else:
print('{} is not in keypad map'.format(event.char))
@@ -35,8 +39,13 @@ class NumpadInput(object):
if event.char in numpad:
self.check_key_release_settings(event.char)
if event.char is 'h':
self.data.is_display_held = False
def on_mouse_move(self, event):
if self.data.settings['user_input']['MOUSE_INPUT']['value'] != 'enabled':
if self.data.settings['user_input'].setdefault(
'MOUSE_INPUT',
self.data.default_settings.get('MOUSE_INPUT',{'value': 'enabled'})).get('value') != 'enabled':
return
if event.x > 480 or event.y > 320:
return
@@ -58,6 +67,10 @@ class NumpadInput(object):
is_function = 1
else:
is_function = 0
numbers = "jklmnopqrs"
if self.data.is_display_held and key in numbers:
return self.actions.call_method_name("set_display_mode_%s"%self.data.get_display_modes_list()[numbers.index(key)])
print('the numpad action being called is {} (mode is {})'.format(this_mapping[mode][is_function], mode))
if value != -1:
@@ -91,7 +104,7 @@ class NumpadInput(object):
if(not self.in_0_event ):
self.in_0_event = True
self.additional_0_in_event = 0
self.root.after(600, self.check_event_outcome)
self.root.after(60, self.check_event_outcome)
else:
self.additional_0_in_event = self.additional_0_in_event + 1
@@ -104,7 +117,7 @@ class NumpadInput(object):
self.run_action_for_mapped_key('n')
elif(self.additional_0_in_event == 1):
print('this doesnt happen - may not be needed')
self.root.after(600, self.second_check_event_outcome)
self.root.after(60, self.second_check_event_outcome)
def second_check_event_outcome(self):
if(self.additional_0_in_event == 1 ):