-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAPC40_MkII.py
192 lines (171 loc) · 14.5 KB
/
APC40_MkII.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.17 (default, Sep 30 2020, 13:38:04)
# [GCC 7.5.0]
# Embedded file name: C:\ProgramData\Ableton\Live 101 Suite\Resources\MIDI Remote Scripts\APC40_MkIIx\APC40_MkII.py
# Compiled at: 2019-06-18 01:26:52
from __future__ import absolute_import, print_function, unicode_literals
from functools import partial
from _Framework.ButtonMatrixElement import ButtonMatrixElement
from _Framework.ComboElement import ComboElement, DoublePressElement, MultiElement
from _Framework.ControlSurface import OptimizedControlSurface
from _Framework.Layer import Layer
from _Framework.ModesComponent import ModesComponent, ImmediateBehaviour, DelayMode, AddLayerMode
from _Framework.Resource import PrioritizedResource
from _Framework.SessionRecordingComponent import SessionRecordingComponent
from _Framework.SessionZoomingComponent import SessionZoomingComponent
from _Framework.ClipCreator import ClipCreator
from _Framework.Util import recursive_map
from _APC.APC import APC
from _APC.DeviceComponent import DeviceComponent
from _APC.DeviceBankButtonElement import DeviceBankButtonElement
from _APC.DetailViewCntrlComponent import DetailViewCntrlComponent
from _APC.ControlElementUtils import make_button, make_encoder, make_slider, make_ring_encoder, make_pedal_button
from _APC.SkinDefault import make_rgb_skin, make_default_skin, make_stop_button_skin, make_crossfade_button_skin
from . import Colors
from .BankToggleComponent import BankToggleComponent
from .MixerComponent import MixerComponent
from .QuantizationComponent import QuantizationComponent
from .TransportComponent import TransportComponent
from .CustomSessionComponent import CustomSessionComponent
NUM_TRACKS = 8
NUM_SCENES = 5
class APC40_MkII(APC, OptimizedControlSurface):
def __init__(self, *a, **k):
super(APC40_MkII, self).__init__(*a, **k)
self._color_skin = make_rgb_skin()
self._default_skin = make_default_skin()
self._stop_button_skin = make_stop_button_skin()
self._crossfade_button_skin = make_crossfade_button_skin()
with self.component_guard():
self._create_controls()
self._create_bank_toggle()
self._create_session()
self._create_mixer()
self._create_transport()
self._create_device()
self._create_view_control()
self._create_quantization_selection()
self._create_recording()
self._session.set_mixer(self._mixer)
self.set_highlighting_session_component(self._session)
self.set_device_component(self._device)
def _with_shift(self, button):
return ComboElement(button, modifiers=[self._shift_button])
def _create_controls(self):
make_on_off_button = partial(make_button, skin=self._default_skin)
def make_color_button(*a, **k):
button = make_button(skin=self._color_skin, *a, **k)
button.is_rgb = True
button.num_delayed_messages = 2
return button
def make_matrix_button(track, scene):
return make_color_button(0, 32 + track - NUM_TRACKS * scene, name=b'%d_Clip_%d_Button' % (track, scene))
def make_stop_button(track):
return make_button(track, 52, name=b'%d_Stop_Button' % track, skin=self._stop_button_skin)
self._shift_button = make_button(0, 98, name=b'Shift_Button', resource_type=PrioritizedResource)
self._bank_button = make_on_off_button(0, 103, name=b'Bank_Button')
self._left_button = make_button(0, 97, name=b'Bank_Select_Left_Button')
self._right_button = make_button(0, 96, name=b'Bank_Select_Right_Button')
self._up_button = make_button(0, 94, name=b'Bank_Select_Up_Button')
self._down_button = make_button(0, 95, name=b'Bank_Select_Down_Button')
self._stop_buttons = ButtonMatrixElement(rows=[[ make_stop_button(track) for track in xrange(NUM_TRACKS) ]])
self._stop_all_button = make_button(0, 81, name=b'Stop_All_Clips_Button')
self._scene_launch_buttons_raw = [ make_color_button(0, scene + 82, name=b'Scene_%d_Launch_Button' % scene) for scene in xrange(NUM_SCENES) ]
self._scene_launch_buttons = ButtonMatrixElement(rows=[
self._scene_launch_buttons_raw])
self._matrix_rows_raw = [ [ make_matrix_button(track, scene) for track in xrange(NUM_TRACKS) ] for scene in xrange(NUM_SCENES) ]
self._session_matrix = ButtonMatrixElement(rows=self._matrix_rows_raw)
self._pan_button = make_on_off_button(0, 87, name=b'Pan_Button')
self._sends_button = make_on_off_button(0, 88, name=b'Sends_Button', resource_type=PrioritizedResource)
self._user_button = make_on_off_button(0, 89, name=b'User_Button')
self._mixer_encoders = ButtonMatrixElement(rows=[[ make_ring_encoder(48 + track, 56 + track, name=b'Track_Control_%d' % track) for track in xrange(NUM_TRACKS) ]])
self._volume_controls = ButtonMatrixElement(rows=[[ make_slider(track, 7, name=b'%d_Volume_Control' % track) for track in xrange(NUM_TRACKS) ]])
self._master_volume_control = make_slider(0, 14, name=b'Master_Volume_Control')
self._prehear_control = make_encoder(0, 47, name=b'Prehear_Volume_Control')
self._crossfader_control = make_slider(0, 15, name=b'Crossfader')
self._raw_select_buttons = [ make_on_off_button(channel, 51, name=b'%d_Select_Button' % channel) for channel in xrange(NUM_TRACKS) ]
self._arm_buttons = ButtonMatrixElement(rows=[[ make_on_off_button(channel, 48, name=b'%d_Arm_Button' % channel) for channel in xrange(NUM_TRACKS) ]])
self._solo_buttons = ButtonMatrixElement(rows=[[ make_on_off_button(channel, 49, name=b'%d_Solo_Button' % channel) for channel in xrange(NUM_TRACKS) ]])
self._mute_buttons = ButtonMatrixElement(rows=[[ make_on_off_button(channel, 50, name=b'%d_Mute_Button' % channel) for channel in xrange(NUM_TRACKS) ]])
self._crossfade_buttons = ButtonMatrixElement(rows=[[ make_button(channel, 66, name=b'%d_Crossfade_Button' % channel, skin=self._crossfade_button_skin) for channel in xrange(NUM_TRACKS) ]])
self._select_buttons = ButtonMatrixElement(rows=[
self._raw_select_buttons])
self._master_select_button = make_on_off_button(channel=0, identifier=80, name=b'Master_Select_Button')
self._send_select_buttons = ButtonMatrixElement(rows=[[ ComboElement(button, modifiers=[self._sends_button]) for button in self._raw_select_buttons ]])
self._quantization_buttons = ButtonMatrixElement(rows=[[ ComboElement(button, modifiers=[self._shift_button]) for button in self._raw_select_buttons ]])
self._metronome_button = make_on_off_button(0, 90, name=b'Metronome_Button')
self._play_button = make_on_off_button(0, 91, name=b'Play_Button')
self._record_button = make_on_off_button(0, 93, name=b'Record_Button')
self._session_record_button = make_on_off_button(0, 102, name=b'Session_Record_Button')
self._nudge_down_button = make_button(0, 100, name=b'Nudge_Down_Button')
self._nudge_up_button = make_button(0, 101, name=b'Nudge_Up_Button')
self._tap_tempo_button = make_button(0, 99, name=b'Tap_Tempo_Button')
self._tempo_control = make_encoder(0, 13, name=b'Tempo_Control')
self._device_controls = ButtonMatrixElement(rows=[[ make_ring_encoder(16 + index, 24 + index, name=b'Device_Control_%d' % index) for index in xrange(8) ]])
self._device_control_buttons_raw = [ make_on_off_button(0, 58 + index) for index in xrange(8) ]
self._device_bank_buttons = ButtonMatrixElement(rows=[[ DeviceBankButtonElement(button, modifiers=[self._shift_button]) for button in self._device_control_buttons_raw ]])
self._device_prev_bank_button = self._device_control_buttons_raw[2]
self._device_prev_bank_button.name = b'Device_Prev_Bank_Button'
self._device_next_bank_button = self._device_control_buttons_raw[3]
self._device_next_bank_button.name = b'Device_Next_Bank_Button'
self._device_on_off_button = self._device_control_buttons_raw[4]
self._device_on_off_button.name = b'Device_On_Off_Button'
self._device_lock_button = self._device_control_buttons_raw[5]
self._device_lock_button.name = b'Device_Lock_Button'
self._prev_device_button = self._device_control_buttons_raw[0]
self._prev_device_button.name = b'Prev_Device_Button'
self._next_device_button = self._device_control_buttons_raw[1]
self._next_device_button.name = b'Next_Device_Button'
self._clip_device_button = self._device_control_buttons_raw[6]
self._clip_device_button.name = b'Clip_Device_Button'
self._detail_view_button = self._device_control_buttons_raw[7]
self._detail_view_button.name = b'Detail_View_Button'
self._foot_pedal_button = DoublePressElement(make_pedal_button(64, name=b'Foot_Pedal'))
self._shifted_matrix = ButtonMatrixElement(rows=recursive_map(self._with_shift, self._matrix_rows_raw))
self._shifted_scene_buttons = ButtonMatrixElement(rows=[[ self._with_shift(button) for button in self._scene_launch_buttons_raw ]])
def _create_bank_toggle(self):
self._bank_toggle = BankToggleComponent(is_enabled=False, layer=Layer(bank_toggle_button=self._bank_button))
def _create_session(self):
def when_bank_on(button):
return self._bank_toggle.create_toggle_element(on_control=button)
def when_bank_off(button):
return self._bank_toggle.create_toggle_element(off_control=button)
self._session = CustomSessionComponent(NUM_TRACKS, NUM_SCENES, auto_name=True, is_enabled=False, enable_skinning=True, layer=Layer(track_bank_left_button=when_bank_off(self._left_button), track_bank_right_button=when_bank_off(self._right_button), scene_bank_up_button=when_bank_off(self._up_button), scene_bank_down_button=when_bank_off(self._down_button), page_left_button=when_bank_on(self._left_button), page_right_button=when_bank_on(self._right_button), page_up_button=when_bank_on(self._up_button), page_down_button=when_bank_on(self._down_button), stop_track_clip_buttons=self._stop_buttons, stop_all_clips_button=self._stop_all_button, scene_launch_buttons=self._scene_launch_buttons, clip_launch_buttons=self._session_matrix))
clip_color_table = Colors.LIVE_COLORS_TO_MIDI_VALUES.copy()
clip_color_table[16777215] = 119
self._session.set_rgb_mode(clip_color_table, Colors.RGB_COLOR_TABLE)
self._session_zoom = SessionZoomingComponent(self._session, name=b'Session_Overview', enable_skinning=True, is_enabled=False, layer=Layer(button_matrix=self._shifted_matrix, nav_left_button=self._with_shift(self._left_button), nav_right_button=self._with_shift(self._right_button), nav_up_button=self._with_shift(self._up_button), nav_down_button=self._with_shift(self._down_button), scene_bank_buttons=self._shifted_scene_buttons))
self._session.set_delete_button(self._nudge_down_button)
self._session.set_copy_button(self._nudge_up_button)
def _create_mixer(self):
self._mixer = MixerComponent(NUM_TRACKS, auto_name=True, is_enabled=False, invert_mute_feedback=True, layer=Layer(volume_controls=self._volume_controls, arm_buttons=self._arm_buttons, solo_buttons=self._solo_buttons, mute_buttons=self._mute_buttons, shift_button=self._shift_button, track_select_buttons=self._select_buttons, prehear_volume_control=self._prehear_control, crossfader_control=self._crossfader_control, crossfade_buttons=self._crossfade_buttons))
self._mixer.master_strip().layer = Layer(volume_control=self._master_volume_control, select_button=self._master_select_button)
self._encoder_mode = ModesComponent(name=b'Encoder_Mode', is_enabled=False)
self._encoder_mode.default_behaviour = ImmediateBehaviour()
self._encoder_mode.add_mode(b'pan', [
AddLayerMode(self._mixer, Layer(pan_controls=self._mixer_encoders))])
self._encoder_mode.add_mode(b'sends', [
AddLayerMode(self._mixer, Layer(send_controls=self._mixer_encoders)),
DelayMode(AddLayerMode(self._mixer, Layer(send_select_buttons=self._send_select_buttons)))])
self._encoder_mode.add_mode(b'user', [
AddLayerMode(self._mixer, Layer(user_controls=self._mixer_encoders))])
self._encoder_mode.layer = Layer(pan_button=self._pan_button, sends_button=self._sends_button, user_button=self._user_button)
self._encoder_mode.selected_mode = b'pan'
def _create_transport(self):
self._transport = TransportComponent(name=b'Transport', is_enabled=False, layer=Layer(shift_button=self._shift_button, play_button=self._play_button, stop_button=ComboElement(self._play_button, modifiers=[
self._shift_button]), record_button=self._record_button, metronome_button=self._metronome_button, tap_tempo_button=self._tap_tempo_button, nudge_down_button=self._with_shift(self._nudge_down_button), nudge_up_button=self._with_shift(self._nudge_up_button), tempo_encoder=self._tempo_control), play_toggle_model_transform=lambda v: v)
def _create_device(self):
self._device = DeviceComponent(name=b'Device', is_enabled=False, layer=Layer(parameter_controls=self._device_controls, bank_buttons=self._device_bank_buttons, bank_prev_button=self._device_prev_bank_button, bank_next_button=self._device_next_bank_button, on_off_button=self._device_on_off_button, lock_button=self._device_lock_button), device_selection_follows_track_selection=True)
def _create_view_control(self):
self._view_control = DetailViewCntrlComponent(name=b'View_Control', is_enabled=False, layer=Layer(device_nav_left_button=self._prev_device_button, device_nav_right_button=self._next_device_button, device_clip_toggle_button=self._clip_device_button, detail_toggle_button=self._detail_view_button))
self._view_control.device_clip_toggle_button.pressed_color = b'DefaultButton.On'
def _create_quantization_selection(self):
self._quantization_selection = QuantizationComponent(name=b'Quantization_Selection', is_enabled=False, layer=Layer(quantization_buttons=self._quantization_buttons))
def _create_recording(self):
record_button = MultiElement(self._session_record_button, self._foot_pedal_button.single_press)
self._session_recording = SessionRecordingComponent(ClipCreator(), self._view_control, name=b'Session_Recording', is_enabled=False, layer=Layer(new_button=self._foot_pedal_button.double_press, record_button=record_button, _uses_foot_pedal=self._foot_pedal_button))
def get_matrix_button(self, column, row):
return self._matrix_rows_raw[row][column]
def _product_model_id_byte(self):
return 41