mirror of
https://github.com/cyberboy666/r_e_c_u_r.git
synced 2025-12-12 11:20:15 +01:00
Merge branch 'feature_plugins' of https://github.com/langolierz/r_e_c_u_r into feature_plugins
This commit is contained in:
@@ -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)
|
||||
|
||||
----
|
||||
|
||||
|
||||
16
actions.py
16
actions.py
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
@@ -59,6 +68,10 @@ class NumpadInput(object):
|
||||
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:
|
||||
self.actions.call_method_name(this_mapping[mode][is_function],value)
|
||||
@@ -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 ):
|
||||
|
||||
Reference in New Issue
Block a user