mirror of
https://github.com/cyberboy666/r_e_c_u_r.git
synced 2025-12-05 16:00:06 +01:00
Merge branch 'signalculture' into c_o_n_j_u_r
This commit is contained in:
34
actions.py
34
actions.py
@@ -122,7 +122,6 @@ class Actions(object):
|
||||
self.data.function_on = not self.data.function_on
|
||||
|
||||
def next_bank(self):
|
||||
|
||||
self.data.update_bank_number_by_amount(1)
|
||||
print('current bank is {} , the number of banks is {} '.format(self.data.bank_number, len(self.data.bank_data)))
|
||||
|
||||
@@ -199,30 +198,21 @@ class Actions(object):
|
||||
elif self.data.player_mode == 'next':
|
||||
self.data.player_mode = 'now'
|
||||
|
||||
def set_the_camera_colour_u_with_cc(self, amount):
|
||||
u_value = self._convert_midi_cc_value(amount, 0, 255)
|
||||
self.capture.set_colour(u_value, None)
|
||||
def set_the_camera_colour_u_continuous(self, amount):
|
||||
self.capture.set_colour(amount*255, None)
|
||||
|
||||
def set_the_camera_colour_v_with_cc(self, amount):
|
||||
v_value = self._convert_midi_cc_value(amount, 0, 255)
|
||||
self.capture.set_colour(None, v_value)
|
||||
def set_the_camera_colour_v_continuous(self, amount):
|
||||
self.capture.set_colour(None, amount*255)
|
||||
|
||||
def set_the_camera_alpha_cc(self, amount):
|
||||
alpha_amount = self._convert_midi_cc_value(amount, 0, 255)
|
||||
self.capture.set_alpha(alpha_amount)
|
||||
def set_the_camera_alpha_continuous(self, amount):
|
||||
self.capture.set_alpha(amount*255)
|
||||
|
||||
def set_the_current_video_alpha_cc(self, amount):
|
||||
alpha_amount = self._convert_midi_cc_value(amount, 0, 255)
|
||||
self.video_driver.current_player.set_alpha_value(alpha_amount)
|
||||
def set_the_current_video_alpha_continuous(self, amount):
|
||||
self.video_driver.current_player.set_alpha_value(amount*255)
|
||||
|
||||
def set_the_next_video_alpha_cc(self, amount):
|
||||
alpha_amount = self._convert_midi_cc_value(amount, 0, 255)
|
||||
self.video_driver.next_player.set_alpha_value(alpha_amount)
|
||||
def set_the_next_video_alpha_continuous(self, amount):
|
||||
self.video_driver.next_player.set_alpha_value(amount*255)
|
||||
|
||||
@staticmethod
|
||||
def _convert_midi_cc_value(cc_value, min_param, max_param):
|
||||
output_range = max_param - min_param
|
||||
return int(( cc_value / 127 ) * output_range + min_param)
|
||||
|
||||
def get_midi_status(self):
|
||||
self.message_handler.set_message('INFO', 'midi status is {}'.format(self.data.midi_status))
|
||||
@@ -233,6 +223,10 @@ class Actions(object):
|
||||
def update_capture_settings(self, setting_value):
|
||||
self.capture.update_capture_settings()
|
||||
|
||||
def change_piCapture_input(self, setting_value):
|
||||
if self.data.settings['capture']['TYPE']['value'] == 'piCaptureSd1':
|
||||
subprocess.call(['pivideo', '-s', setting_value])
|
||||
|
||||
def change_output_mode(self, setting_value):
|
||||
if setting_value == 'hdmi':
|
||||
self.change_hdmi_settings(setting_value)
|
||||
|
||||
@@ -16,6 +16,7 @@ class Data(object):
|
||||
DEFAULT_SETTINGS_JSON = 'settings_default.json'
|
||||
KEYPAD_MAPPING_JSON = 'keypad_action_mapping.json'
|
||||
MIDI_MAPPING_JSON = 'midi_action_mapping.json'
|
||||
ANALOG_MAPPING_JSON = 'analog_action_mapping.json'
|
||||
EMPTY_SLOT = dict(name='', location='', length=-1, start=-1, end=-1, rate=1)
|
||||
PATH_TO_DATA_OBJECTS = '/home/pi/r_e_c_u_r/json_objects/'
|
||||
PATH_TO_EXTERNAL_DEVICES = '/media/pi'
|
||||
@@ -51,6 +52,7 @@ class Data(object):
|
||||
|
||||
self.key_mappings = self._read_json(self.KEYPAD_MAPPING_JSON)
|
||||
self.midi_mappings = self._read_json(self.MIDI_MAPPING_JSON)
|
||||
self.analog_mappings = self._read_json(self.ANALOG_MAPPING_JSON)
|
||||
|
||||
@staticmethod
|
||||
def create_empty_bank():
|
||||
|
||||
@@ -113,7 +113,7 @@ class BrowserMenu(Menu):
|
||||
|
||||
for f in files:
|
||||
split_name = os.path.splitext(f)
|
||||
if (split_name[1] in ['.mp4', '.mkv', '.avi', '.mov']):
|
||||
if (split_name[1].lower() in ['.mp4', '.mkv', '.avi', '.mov']):
|
||||
self.menu_list.append(dict(name='{}{}'.format(indent, f), slot='-'))
|
||||
|
||||
def _is_file_in_bank_data(self, file_name):
|
||||
|
||||
@@ -27,6 +27,41 @@ PIN NO.| SYMBOL | DESCRIPTION
|
||||
|
||||
from this i should b able to work out which pins i can use for midi in and for analog-to-digital inputs (also piCapture needs some inputs too)
|
||||
|
||||
# gpio inputs for recur:
|
||||
|
||||
here are the pins needed for different parts of the recur connections:
|
||||
|
||||
note that pins 1 to 26 are covered by the lcd screen, even though not all are used by it
|
||||
|
||||
## lcd screen
|
||||
|
||||
as stated above, the screen uses the following pins:
|
||||
- 1 , 17 : 3.3v
|
||||
- 2, 4 : 5v
|
||||
- 11 : TP_IQR (for touch panel)
|
||||
- 18 : LCD_RS
|
||||
- 19 : LCD_SI
|
||||
- 21 : TP_SO (touch panel output)
|
||||
- 22 : reset
|
||||
- 23 : LCD_SCK
|
||||
- 24 : LCD_CS
|
||||
- 26 : TP_CS
|
||||
|
||||
## piCapture
|
||||
|
||||
piCapture be default will use pins 3, 5, 7 to comunicate
|
||||
|
||||
## serial-midi in
|
||||
|
||||
pin 10 (rx) is needed for midi in plus 3.3v (combined with octocoupler 6n138 etc and resistors)
|
||||
|
||||
## analog in
|
||||
|
||||
using a MCP3008 via hardware SPI, can connect up to 8 analog inputs using pins 35, 36, 38, 40 (SPI1) + 3.3v , can also connect with software SPI with any four pins if more inputs were needed. these inputs can be used for pots/sliders & gate/cv jacks. by default will react to 0-3.3v. if wanting to use larger range than this will need some kind of scaling electronics (tl074d?)
|
||||
|
||||
providing 4 pins on under the lcd screen cover can be accessed by the board (and 3.3v can be distributed) i should be able to create a circuit that connects all these inputs to the pi.
|
||||
|
||||
|
||||
[instructable]: http://www.instructables.com/id/PiMiDi-A-Raspberry-Pi-Midi-Box-or-How-I-Learned-to/
|
||||
[adafruit tft display]: https://www.adafruit.com/product/2441
|
||||
[raspi gpio]: https://www.raspberrypi.org/documentation/usage/gpio/
|
||||
|
||||
@@ -59,7 +59,7 @@ HOWEVER, i have also noticed that this lag can happen even with longer clips som
|
||||
[correct cable]: https://www.adafruit.com/product/2881
|
||||
[my cable]: https://www.aliexpress.com/item/4-poles-3-5mm-Mini-AV-Male-to-3RCA-Female-M-F-Audio-Video-Cable-Stereo/32769544207.html
|
||||
[.keymap]: /dotfiles/.keymap
|
||||
[keypad_action_mapping.json]: /json_files/keypad_action_mapping.json
|
||||
[keypad_action_mapping.json]: /json_objects/keypad_action_mapping.json
|
||||
[develop page]: /documentation/develop_docs.md
|
||||
[build]: /documentation/build_docs.md
|
||||
|
||||
|
||||
5
json_objects/analog_action_mapping.json
Normal file
5
json_objects/analog_action_mapping.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"7": {
|
||||
"DEFAULT": ["set_the_current_video_alpha_continuous"]
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"control_change 0": {
|
||||
"DEFAULT": ["set_the_current_video_alpha_cc"]
|
||||
"DEFAULT": ["set_the_current_video_alpha_continuous"]
|
||||
},
|
||||
"control_change 1": {
|
||||
"DEFAULT": ["set_the_next_video_alpha_cc"]
|
||||
"DEFAULT": ["set_the_next_video_alpha_continuous"]
|
||||
},
|
||||
"control_change 2": {
|
||||
"DEFAULT": ["set_the_camera_alpha_cc"]
|
||||
"DEFAULT": ["set_the_camera_alpha_continuous"]
|
||||
},
|
||||
"control_change 3": {
|
||||
"DEFAULT": ["set_the_camera_colour_u_with_cc"]
|
||||
"DEFAULT": ["set_the_camera_colour_u_continuous"]
|
||||
},
|
||||
"control_change 4": {
|
||||
"DEFAULT": ["set_the_camera_colour_v_with_cc"]
|
||||
"DEFAULT": ["set_the_camera_colour_v_continuous"]
|
||||
},
|
||||
"note_on 72": {
|
||||
"NAV_BROWSER": ["move_browser_selection_up"],
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
{
|
||||
"capture": {
|
||||
"TYPE": {
|
||||
"action": "update_capture_settings",
|
||||
"options": [
|
||||
"piCamera",
|
||||
"piCaptureSd1"
|
||||
],
|
||||
"value": "piCaptureSd1"
|
||||
},
|
||||
"PICAPTURE_INPUT": {
|
||||
"action": "change_piCapture_input",
|
||||
"options": [
|
||||
"auto",
|
||||
"video1",
|
||||
"video2",
|
||||
"video3",
|
||||
"svideo",
|
||||
"component"
|
||||
],
|
||||
"value": "video1"
|
||||
},
|
||||
"DEVICE": {
|
||||
"action": "update_capture_settings",
|
||||
"options": [
|
||||
@@ -87,6 +107,14 @@
|
||||
}
|
||||
},
|
||||
"other": {
|
||||
"ANALOG_INPUT": {
|
||||
"action": null,
|
||||
"options": [
|
||||
"enabled",
|
||||
"disabled"
|
||||
],
|
||||
"value": "disabled"
|
||||
},
|
||||
"DEV_MODE_RESET": {
|
||||
"action": "switch_dev_mode",
|
||||
"options": [
|
||||
@@ -227,7 +255,7 @@
|
||||
"preferred",
|
||||
"CEA 4 HDMI"
|
||||
],
|
||||
"value": "preferred"
|
||||
"value": "CEA 4 HDMI"
|
||||
},
|
||||
"COMPOSITE_PROGRESSIVE": {
|
||||
"action": "change_composite_setting",
|
||||
|
||||
@@ -11,6 +11,7 @@ from display_centre.display import Display
|
||||
from display_centre.messages import MessageHandler
|
||||
from user_input.numpad_input import NumpadInput
|
||||
from user_input.midi_input import MidiInput
|
||||
from user_input.analog_input import AnalogInput
|
||||
from video_centre.video_driver import VideoDriver
|
||||
from video_centre.capture import Capture
|
||||
import data_centre
|
||||
@@ -39,6 +40,7 @@ actions = Actions(tk, message_handler, data, video_driver, capture, display)
|
||||
|
||||
numpad_input = NumpadInput(tk, message_handler, display, actions, data)
|
||||
midi_input = MidiInput(tk, message_handler, display, actions, data)
|
||||
analog_input = AnalogInput(tk, message_handler, display, actions, data)
|
||||
|
||||
actions.check_and_set_output_mode_on_boot()
|
||||
actions.check_dev_mode()
|
||||
|
||||
69
user_input/analog_input.py
Normal file
69
user_input/analog_input.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import Adafruit_GPIO.SPI as SPI
|
||||
import Adafruit_MCP3008
|
||||
|
||||
class AnalogInput(object):
|
||||
def __init__(self, root, message_handler, display, actions, data):
|
||||
self.root = root
|
||||
self.message_handler = message_handler
|
||||
self.display = display
|
||||
self.actions = actions
|
||||
self.data = data
|
||||
self.analog_mappings = data.analog_mappings
|
||||
self.analog_delay = 50
|
||||
self.last_readings = [0,0,0,0,0,0,0,0]
|
||||
|
||||
SPI_PORT = 1
|
||||
SPI_DEVICE = 2
|
||||
self.analog_input = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))
|
||||
self.check_if_listening_enabled()
|
||||
|
||||
|
||||
def check_if_listening_enabled(self):
|
||||
if self.data.settings['other']['ANALOG_INPUT']['value'] == 'enabled':
|
||||
self.poll_analog_inputs()
|
||||
else:
|
||||
self.root.after(1000, self.check_if_listening_enabled)
|
||||
|
||||
def poll_analog_inputs(self):
|
||||
if self.data.settings['other']['ANALOG_INPUT']['value'] == 'enabled':
|
||||
for i in range(0,8):
|
||||
if str(i) in self.analog_mappings:
|
||||
this_reading = self.analog_input.read_adc(i)
|
||||
if this_reading - self.last_readings[i] > 3:
|
||||
self.run_action_for_mapped_channel(i, this_reading)
|
||||
self.last_readings[i] = this_reading
|
||||
self.root.after(self.analog_delay, self.poll_analog_inputs)
|
||||
else:
|
||||
self.check_if_listening_enabled()
|
||||
|
||||
def run_action_for_mapped_channel(self, channel, channel_value):
|
||||
this_mapping = self.analog_mappings[str(channel)]
|
||||
if self.data.control_mode in this_mapping:
|
||||
mode = self.data.control_mode
|
||||
elif 'DEFAULT' in this_mapping:
|
||||
mode = 'DEFAULT'
|
||||
|
||||
if self.data.function_on and len(this_mapping[mode]) > 1:
|
||||
method_name = this_mapping[mode][1]
|
||||
self.data.function_on = False
|
||||
else:
|
||||
method_name = this_mapping[mode][0]
|
||||
|
||||
if channel_value is not None:
|
||||
norm_channel_value = channel_value/1023
|
||||
else:
|
||||
norm_channel_value = None
|
||||
|
||||
print('the action being called is {}'.format(method_name))
|
||||
self.call_method_name(method_name, norm_channel_value)
|
||||
## not sure whether we want to update the screen in general; here - probably not most of the time ...
|
||||
#if 'cc' not in message_name:
|
||||
# self.display.refresh_display()
|
||||
|
||||
def call_method_name(self, method_name, argument=None):
|
||||
if argument is not None:
|
||||
getattr(self.actions, method_name)(argument)
|
||||
else:
|
||||
getattr(self.actions, method_name)()
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ class MidiInput(object):
|
||||
for message in self.midi_device.iter_pending():
|
||||
i = i + 1
|
||||
message_dict = message.dict()
|
||||
## only listening to midi channel 1 for now , will make it seletcable later
|
||||
if not message_dict['channel'] == 0:
|
||||
midi_channel = midi_setting = self.data.settings['midi']['CHANNEL']['value'] - 1
|
||||
if not message_dict['channel'] == midi_channel:
|
||||
pass
|
||||
## turning off noisey clock messages for now - may want to use them at some point
|
||||
elif message_dict['type'] == 'clock':
|
||||
@@ -91,9 +91,13 @@ class MidiInput(object):
|
||||
method_name = this_mapping[mode][0]
|
||||
|
||||
print('the action being called is {}'.format(method_name))
|
||||
self.call_method_name(method_name, mapped_message_value)
|
||||
## only update screen if not cc - seeing if cc can respond faster if not refreshing screen on every action
|
||||
if 'cc' not in message_name:
|
||||
if mapped_message_value is not None:
|
||||
norm_message_value = mapped_message_value/127
|
||||
else:
|
||||
norm_message_value = None
|
||||
self.call_method_name(method_name, norm_message_value)
|
||||
## only update screen if not continuous - seeing if cc can respond faster if not refreshing screen on every action
|
||||
if 'continuous' not in message_name:
|
||||
self.display.refresh_display()
|
||||
|
||||
def call_method_name(self, method_name, argument=None):
|
||||
|
||||
@@ -26,7 +26,7 @@ class Capture(object):
|
||||
if self.use_capture:
|
||||
self.update_capture_settings()
|
||||
try:
|
||||
self.device = picamera.PiCamera(resolution=self.resolution, framerate=self.framerate)
|
||||
self.device = picamera.PiCamera(resolution=self.resolution, framerate=self.framerate, sensor_mode = self.sensor_mode)
|
||||
except picamera.exc.PiCameraError as e:
|
||||
self.use_capture = False
|
||||
print('camera exception is {}'.format(e))
|
||||
@@ -37,6 +37,11 @@ class Capture(object):
|
||||
self.use_capture = self.data.settings['capture']['DEVICE']['value'] == 'enabled'
|
||||
self.resolution = self.convert_resolution_value(self.data.settings['capture']['RESOLUTION']['value'])
|
||||
self.framerate = self.convert_framerate_value(self.data.settings['capture']['FRAMERATE']['value'])
|
||||
self.capture_type = self.data.settings['capture']['TYPE']['value']
|
||||
if self.capture_type == "piCaptureSd1":
|
||||
self.sensor_mode = 6
|
||||
else:
|
||||
self.sensor_mode = 0
|
||||
##update current instance (device) if in use
|
||||
if self.device and not self.device.closed:
|
||||
self.device.image_effect = self.data.settings['capture']['IMAGE_EFFECT']['value']
|
||||
@@ -56,9 +61,20 @@ class Capture(object):
|
||||
self.is_previewing = True
|
||||
self.device.start_preview()
|
||||
self.set_preview_screen_size()
|
||||
self.set_capture_settings()
|
||||
self.device.preview.layer = self.PREVIEW_LAYER
|
||||
return True
|
||||
|
||||
def set_capture_settings(self):
|
||||
if self.capture_type == "piCaptureSd1":
|
||||
self.device.sensor_mode = 6
|
||||
self.device.awb_mode = "off"
|
||||
self.device.awb_gains = 1.0
|
||||
self.device.exposure_mode = "off"
|
||||
else:
|
||||
self.sensor_mode = 0
|
||||
|
||||
|
||||
def set_preview_screen_size(self):
|
||||
if self.data.settings['other']['DEV_MODE_RESET']['value'] == 'on':
|
||||
self.device.preview.fullscreen = False
|
||||
@@ -117,8 +133,12 @@ class Capture(object):
|
||||
def convert_raw_recording(self):
|
||||
recording_path , recording_name = self.generate_recording_path()
|
||||
try:
|
||||
mp4box_process = subprocess.Popen(['MP4Box', '-add', self.video_dir + '/raw.h264', recording_path])
|
||||
return mp4box_process , recording_name
|
||||
if self.sensor_mode == 6:
|
||||
mp4box_process = subprocess.Popen(['MP4Box', '-fps', '60', '-add', self.video_dir + '/raw.h264', recording_path])
|
||||
return mp4box_process , recording_name
|
||||
else:
|
||||
mp4box_process = subprocess.Popen(['MP4Box', '-add', self.video_dir + '/raw.h264', recording_path])
|
||||
return mp4box_process , recording_name
|
||||
except Exception as e:
|
||||
print(e)
|
||||
if hasattr(e, 'message'):
|
||||
|
||||
@@ -141,8 +141,9 @@ class VideoPlayer:
|
||||
self.set_alpha_value(255)
|
||||
|
||||
def set_alpha_value(self, amount):
|
||||
self.omx_player.set_alpha(amount)
|
||||
self.alpha = amount
|
||||
if self.omx_player:
|
||||
self.omx_player.set_alpha(amount)
|
||||
self.alpha = amount
|
||||
|
||||
def seek(self, amount):
|
||||
position = self.get_position()
|
||||
|
||||
Reference in New Issue
Block a user