forked from gluon/AbletonLive10.1_MIDIRemoteScripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
automation.py
144 lines (112 loc) · 4.93 KB
/
automation.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
#Embedded file name: /Users/versonator/Jenkins/live/output/Live/mac_64_static/Release/python-bundle/MIDI Remote Scripts/Push2/automation.py
from __future__ import absolute_import, print_function, unicode_literals
from itertools import ifilter
from Live import DeviceParameter
from ableton.v2.base import liveobj_valid, listenable_property, listens
from ableton.v2.control_surface import InternalParameterBase, ParameterInfo, PitchParameter
from pushbase.automation_component import AutomationComponent as AutomationComponentBase
class StepAutomationParameter(InternalParameterBase):
def __init__(self, parameter = None, *a, **k):
assert liveobj_valid(parameter)
super(StepAutomationParameter, self).__init__(name=parameter.name, *a, **k)
self._parameter = parameter
self._value = self._parameter.value
@listenable_property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = value
@property
def max(self):
return self._parameter.max
@property
def min(self):
return self._parameter.min
@property
def display_value(self):
return self._parameter.str_for_value(self.value)
@property
def canonical_parent(self):
return self._parameter.canonical_parent
@property
def original_parameter(self):
return self._parameter
@property
def is_quantized(self):
return self._parameter.is_quantized
@property
def value_items(self):
return self._parameter.value_items
@property
def automation_state(self):
return self._parameter.automation_state
def make_automation_parameter(parameter_info):
wrapped_parameter = None
if parameter_info and liveobj_valid(parameter_info.parameter):
parameter = parameter_info.parameter
if isinstance(parameter, PitchParameter):
parameter = parameter.integer_value_host
wrapped_parameter = ParameterInfo(parameter=StepAutomationParameter(parameter=parameter), name=parameter_info.name, default_encoder_sensitivity=parameter_info.default_encoder_sensitivity, fine_grain_encoder_sensitivity=parameter_info.fine_grain_encoder_sensitivity)
return wrapped_parameter
class AutomationComponent(AutomationComponentBase):
ENCODER_SENSITIVITY_FACTOR = 0.5
def __init__(self, *a, **k):
self._parameter_infos = []
super(AutomationComponent, self).__init__(*a, **k)
self._drum_pad_selected = False
@staticmethod
def parameter_is_automateable(parameter):
return liveobj_valid(parameter) and isinstance(parameter, (DeviceParameter.DeviceParameter, PitchParameter))
@property
def deviceType(self):
device_type = u'default'
device = self.device
if liveobj_valid(device):
device = self.parameter_provider.device()
device_type = device.class_name if liveobj_valid(device) else device_type
return device_type
@listenable_property
def device(self):
device = None
if hasattr(self.parameter_provider, u'device'):
device = self.parameter_provider.device()
return device
def _on_parameter_provider_changed(self, provider):
self.notify_device()
self.__on_device_changed.subject = provider if getattr(self.parameter_provider, u'device', None) is not None else None
@listenable_property
def parameters(self):
return map(lambda info: (info.parameter if info else None), self._parameter_infos)
@property
def parameter_infos(self):
return self._parameter_infos
def set_drum_pad_selected(self, value):
if self._drum_pad_selected != value:
self._drum_pad_selected = value
self.notify_can_automate_parameters()
@listenable_property
def can_automate_parameters(self):
return self._can_automate_parameters() and not self._drum_pad_selected
def update(self):
super(AutomationComponent, self).update()
if self.is_enabled():
self._rebuild_parameter_list()
self._update_parameter_values()
def _update_parameters(self):
self._rebuild_parameter_list()
super(AutomationComponent, self)._update_parameters()
def _rebuild_parameter_list(self):
self._parameter_infos = map(make_automation_parameter, self._parameter_infos_to_use()) if self.is_enabled() else []
def _update_parameter_values(self):
for info in ifilter(lambda p: p is not None, self._parameter_infos):
if len(self._selected_time) > 0:
wrapped_parameter = info.parameter
wrapped_parameter.value = self.parameter_to_value(wrapped_parameter.original_parameter)
self.notify_parameters()
def _parameter_for_index(self, parameters, index):
if parameters[index]:
return parameters[index].original_parameter
@listens(u'device')
def __on_device_changed(self):
self.notify_device()