Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
847 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import Live | ||
|
||
from _Framework.ButtonElement import * | ||
|
||
class ConfigurableButtonElement(ButtonElement): | ||
__module__ = __name__ | ||
__doc__ = ' Special button class that can be configured with custom on- and off-values ' | ||
|
||
def __init__(self, is_momentary, msg_type, channel, identifier, vel = 127): | ||
ButtonElement.__init__(self, is_momentary, msg_type, channel, identifier) | ||
if vel != 0: | ||
self._on_value = vel #127 for Launchpad #0=off, 1=green, 2=green blink, 3=red, 4=red blink, 5=yellow, 6=yellow blink, 7-127=green | ||
else: | ||
self._on_value = 127 | ||
self._note = identifier | ||
self._off_value = 0 #4 for Launchpad, 0 for APC40/20 | ||
self._blink_on = None | ||
self._last_active_value = 0 | ||
self._blinking = False | ||
self._led_on = 0 | ||
self._is_enabled = True | ||
self._is_notifying = False | ||
self._force_next_value = False | ||
self._pending_listeners = [] | ||
self.count = 0 | ||
|
||
def note_on(self): | ||
if (self.count > 1): | ||
self.count = 0 | ||
else: | ||
None | ||
if (self.count == 1): | ||
self.turn_on() | ||
else: | ||
self.turn_off() | ||
|
||
def set_on_off_values(self, on_value, off_value): | ||
assert (on_value in range(128)) | ||
assert (off_value in range(128)) | ||
self._last_sent_value = -1 | ||
self._on_value = on_value | ||
self._off_value = off_value | ||
|
||
def set_force_next_value(self): | ||
self._force_next_value = True | ||
|
||
def set_enabled(self, enabled): | ||
self._is_enabled = enabled | ||
|
||
#def turn_on(self): | ||
#self.send_value(self._on_value) | ||
|
||
#def turn_off(self): | ||
#self.send_value(self._off_value) | ||
|
||
def reset(self): | ||
self.send_value(0) #4 for Launchpad, 0 for APC40/20 | ||
|
||
def add_value_listener(self, callback, identify_sender = False): | ||
if (not self._is_notifying): | ||
ButtonElement.add_value_listener(self, callback, identify_sender) | ||
else: | ||
self._pending_listeners.append((callback, identify_sender)) | ||
|
||
def receive_value(self, value): | ||
self._is_notifying = True | ||
ButtonElement.receive_value(self, value) | ||
|
||
self._is_notifying = False | ||
for listener in self._pending_listeners: | ||
self.add_value_listener(listener[0], listener[1]) | ||
|
||
self._pending_listeners = [] | ||
|
||
def send_value(self, value, force = False): | ||
ButtonElement.send_value(self, value, (force or self._force_next_value)) | ||
self._last_active_value = value | ||
self._force_next_value = False | ||
|
||
def install_connections(self, install_translation_callback, install_mapping_callback, install_forwarding_callback): | ||
if self._is_enabled: | ||
ButtonElement.install_connections(self, install_translation_callback, install_mapping_callback, install_forwarding_callback) | ||
elif self._msg_channel != self._original_channel or self._msg_identifier != self._original_identifier: | ||
install_translation_callback(self._msg_type, self._original_identifier, self._original_channel, self._msg_identifier, self._msg_channel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from _Framework.ModeSelectorComponent import ModeSelectorComponent | ||
from ConfigurableButtonElement import ConfigurableButtonElement | ||
from K_MixUtility import K_MixUtility | ||
from MIDI import * | ||
|
||
class DeviceSelector(ModeSelectorComponent, K_MixUtility): | ||
"""Class that selects between modes""" | ||
|
||
def __init__(self,mixer,device): | ||
ModeSelectorComponent.__init__(self) | ||
self._mixer = mixer | ||
self._device = device | ||
self.set_mode_toggle(self.button(CHANNEL,FINE_BUTTON)) | ||
#self.update() | ||
|
||
def set_mode_toggle(self, button): | ||
#if not (button == None or isinstance(button, ConfigurableButtonElement)): | ||
# raise AssertionError | ||
if self._mode_toggle != None: | ||
self._mode_toggle.remove_value_listener(self._toggle_value) | ||
#self._mode_toggle.remove_value_listener(self._mode_release) | ||
self._mode_toggle = button | ||
self._mode_toggle != None and self._mode_toggle.add_value_listener(self._toggle_value) | ||
#self._mode_toggle.add_value_listener(self._mode_release) | ||
self.set_mode(0) | ||
|
||
def number_of_modes(self): | ||
return 2 | ||
|
||
def on_enabled_changed(self): | ||
self.update() | ||
''' | ||
def set_mode(self, mode): | ||
if mode < self.number_of_modes(): | ||
self._mode_index = mode | ||
self.update() | ||
''' | ||
|
||
def _toggle_value(self, value): | ||
index = self._mode_index | ||
if value != 0: | ||
if index == 0: | ||
self.set_mode(1) | ||
self._mixer.setup(False) | ||
self._device.setup(True) | ||
if index == 1: | ||
self.set_mode(0) | ||
self._device.setup(False) | ||
self._mixer.setup(True) | ||
if value == 0: | ||
if index == 1: | ||
self._mode_toggle.send_value(1) | ||
|
||
def _mode_release(self, value): | ||
if value == 0: | ||
index = self._mode_index | ||
if index == 1: | ||
self._mode_toggle.send_value(1) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
from _Framework.DeviceComponent import DeviceComponent | ||
from K_MixUtility import K_MixUtility | ||
from MIDI import * | ||
from _Framework.Debug import debug_print | ||
from _Framework.SubjectSlot import subject_slot, subject_slot_group, Subject | ||
|
||
|
||
def device_to_appoint(device): | ||
appointed_device = device | ||
if device != None and device.can_have_drum_pads and not device.has_macro_mappings and len(device.chains) > 0 and device.view.selected_chain != None and len(device.view.selected_chain.devices) > 0: | ||
appointed_device = device_to_appoint(device.view.selected_chain.devices[0]) | ||
return appointed_device | ||
|
||
|
||
class Device_Mode(DeviceComponent,K_MixUtility): | ||
def __init__(self, parent, *a, **k): | ||
super(Device_Mode, self).__init__(*a, **k) | ||
self.encoders = [] | ||
self._device_left_button = None | ||
self._device_right_button = None | ||
self.selected_device = None | ||
self.parent = parent | ||
self.track = None | ||
self._active = False | ||
|
||
def make_button_slot(name): | ||
return self.register_slot(None, getattr(self, '_%s_value' % name), 'value') | ||
|
||
for index in range(8): | ||
self.encoders.append(self.encoder(CHANNEL, SLIDERS[index])) | ||
|
||
|
||
self._device_left_slot = make_button_slot('device_left') | ||
self._device_right_slot = make_button_slot('device_right') | ||
|
||
def set_device_left_button(self, button): | ||
if button != None: | ||
if button != self._device_left_button: | ||
self._device_left_button = button | ||
self._device_left_slot.subject = button | ||
|
||
def set_device_right_button(self, button): | ||
if button != None: | ||
if button != self._device_right_button: | ||
self._device_right_button = button | ||
self._device_right_slot.subject = button | ||
|
||
def _device_right_value(self, value): | ||
if value == 127: | ||
count = 0 | ||
for device in self.song().view.selected_track.devices: | ||
if device == self.song().view.selected_track.view.selected_device: | ||
index = count | ||
count = count + 1 | ||
if index + 1 == len(self.song().view.selected_track.devices): | ||
index = -1 | ||
self.song().appointed_device = device_to_appoint(self.song().view.selected_track.devices[index + 1]) | ||
self.song().view.select_device(self.song().view.selected_track.devices[index + 1], False) | ||
if self.selected_device != self.song().view.selected_track.view.selected_device: | ||
self.selected_device = self.song().view.selected_track.view.selected_device | ||
self.set_device(self.selected_device) | ||
|
||
def _device_left_value(self, value): | ||
if value == 127: | ||
count = 0 | ||
for device in self.song().view.selected_track.devices: | ||
if device == self.song().view.selected_track.view.selected_device: | ||
index = count | ||
count = count + 1 | ||
self.song().appointed_device = device_to_appoint(self.song().view.selected_track.devices[index - 1]) | ||
self.song().view.select_device(self.song().view.selected_track.devices[index - 1], False) | ||
if self.selected_device != self.song().view.selected_track.view.selected_device: | ||
self.selected_device = self.song().view.selected_track.view.selected_device | ||
self.set_device(self.selected_device) | ||
|
||
def log_message(self, *message): | ||
""" Writes the given message into Live's main log file """ | ||
message = '(%s) %s' % (self.__class__.__name__, ' '.join(map(str, message))) | ||
console_message = 'LOG: ' + message | ||
if debug_print != None: | ||
debug_print(console_message) | ||
else: | ||
print console_message | ||
if self.parent._c_instance: | ||
self.parent._c_instance.log_message(message) | ||
|
||
def on_selected_track_changed(self): | ||
track = self.song().view.selected_track | ||
device_count = track.devices | ||
self.log_message(len(device_count)) | ||
if len(device_count) != 0: | ||
if self.selected_device != self.song().view.selected_track.devices[0]: | ||
self.song().view.select_device(self.song().view.selected_track.devices[0]) | ||
self.selected_device = self.song().view.selected_track.devices[0] | ||
self.parent.mixer.on_selected_track_changed() | ||
self.set_device(self.selected_device) | ||
|
||
def on_selected_device_changed(self): | ||
if self.selected_device != self.song().view.selected_track.view.selected_device: | ||
self.selected_device = self.song().view.selected_track.view.selected_device | ||
self.set_device(self.selected_device) | ||
|
||
def setup(self, as_enabled): | ||
if self.selected_device != self.song().view.selected_track.view.selected_device: | ||
self.selected_device = self.song().view.selected_track.view.selected_device | ||
self.set_device(self.selected_device) | ||
self.set_parameter_controls(None) | ||
|
||
for slider in range(8): | ||
self.encoders[slider].send_value(0) | ||
#device = DeviceComponent() | ||
#self.set_device_component(device) | ||
#device.set_parameter_controls(self._sliders) | ||
if as_enabled: | ||
if self._active == False: | ||
self.set_parameter_controls(None) | ||
for slider in range(8): | ||
self.encoders[slider].send_value(0) | ||
self.set_parameter_controls(self.encoders) | ||
self.set_device_left_button(self.button(CHANNEL, HEADPHONE_BUTTON)) | ||
self.set_device_right_button(self.button(CHANNEL,TRIM_BUTTON)) | ||
self.set_bank_nav_buttons(self.button(CHANNEL, EQ_BUTTON), self.button(CHANNEL, GATE_BUTTON)) | ||
self._active = True | ||
self.update() | ||
else: | ||
if self._active == True: | ||
self.set_parameter_controls(None) | ||
for slider in range(8): | ||
self.encoders[slider].send_value(0) | ||
self.set_device_left_button(None) | ||
self.set_device_right_button(None) | ||
self.set_bank_nav_buttons(None, None) | ||
self._active = False | ||
self.update() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from __future__ import with_statement | ||
|
||
import Live | ||
import time | ||
import math | ||
|
||
from _Framework.Debug import debug_print | ||
from _Framework.ControlSurface import ControlSurface | ||
from _Framework.MixerComponent import MixerComponent | ||
from _Framework.SubjectSlot import subject_slot, subject_slot_group, Subject | ||
from K_MixSession import K_MixSession | ||
from SendModeSelector import SendModeSelector | ||
from VUModeSelector import VUModeSelector | ||
from DeviceSelector import DeviceSelector | ||
from Device_Mode import Device_Mode | ||
from Mix_Mode import Mix_Mode | ||
from K_MixUtility import K_MixUtility | ||
from MIDI import * | ||
|
||
|
||
class K_Mix(ControlSurface,K_MixUtility): | ||
'''Our K Mix Class''' | ||
|
||
def __init__(self, c_instance): | ||
ControlSurface.__init__(self, c_instance) | ||
with self.component_guard(): | ||
self.setup_mixer() | ||
self.setup_device() | ||
self.setup_send_selector() | ||
self.setup_VU_selector() | ||
self.setup_device_selector() | ||
self.setup_session() | ||
self.set_highlighting_session_component(self.session) | ||
|
||
self.register_slot(self.song().view.selected_track.view, self._on_selected_device_changed, 'selected_device') | ||
|
||
def log_message(self, *message): | ||
#""" Writes the given message into Live's main log file """ | ||
message = '(%s) %s' % (self.__class__.__name__, ' '.join(map(str, message))) | ||
console_message = 'LOG: ' + message | ||
if debug_print != None: | ||
debug_print(console_message) | ||
else: | ||
print console_message | ||
if self._c_instance: | ||
self._c_instance.log_message(message) | ||
|
||
def setup_session(self): | ||
self.session = K_MixSession(8, 6, self) | ||
self.session.set_offsets(0,0) | ||
self.session.set_mixer(self.mixer) | ||
self.session.update() | ||
|
||
def setup_device(self): | ||
self.device = Device_Mode(self) | ||
|
||
def setup_mixer(self): | ||
self.mixer = Mix_Mode(8,8,self) | ||
self.mixer.setup_master(True) | ||
|
||
def setup_send_selector(self): | ||
self.send_selector = SendModeSelector(self.mixer) | ||
|
||
def setup_device_selector(self): | ||
self.device_selector = DeviceSelector(self.mixer,self.device) | ||
|
||
def setup_VU_selector(self): | ||
self.VU_selector = VUModeSelector(self.mixer) | ||
|
||
def _on_selected_device_changed(self): | ||
self.device.on_selected_device_changed() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from _Framework.SessionComponent import SessionComponent | ||
from K_MixUtility import K_MixUtility | ||
from MIDI import * | ||
from _Framework.Debug import debug_print | ||
|
||
class K_MixSession(SessionComponent, K_MixUtility): | ||
def __init__(self, num_tracks, num_scenes,parent): | ||
SessionComponent.__init__(self, num_tracks, num_scenes) | ||
self.sends = ROTARIES[1:] | ||
self.setup(num_scenes) | ||
self.parent = parent | ||
|
||
def setup(self,num_scenes): | ||
self.set_scene_bank_buttons( | ||
self.button(CHANNEL, STOP_BUTTON), | ||
self.button(CHANNEL, RECORD_BUTTON)) | ||
|
||
self.set_track_bank_buttons( | ||
self.button(CHANNEL, PLAY_BUTTON), | ||
self.button(CHANNEL, REWIND_BUTTON)) | ||
|
||
for scenes in range(num_scenes): | ||
self.scene(scenes).set_launch_button(self.button(CHANNEL, SCENE_LAUNCH_BUTTONS[scenes])) | ||
|
||
def on_track_list_changed(self): | ||
super(K_MixSession,self).on_track_list_changed() | ||
|
||
def log_message(self, *message): | ||
#""" Writes the given message into Live's main log file """ | ||
message = '(%s) %s' % (self.__class__.__name__, ' '.join(map(str, message))) | ||
console_message = 'LOG: ' + message | ||
if debug_print != None: | ||
debug_print(console_message) | ||
else: | ||
print console_message | ||
if self.parent._c_instance: | ||
self.parent._c_instance.log_message(message) |
Oops, something went wrong.