forked from xot/ElectraOne
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCCInfo.py
101 lines (84 loc) · 3.79 KB
/
CCInfo.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
# CCInfo
# - class to store information about a CC control
#
# Part of ElectraOne.
#
# Ableton Live MIDI Remote Script for the Electra One
#
# Author: Jaap-henk Hoepman (info@xot.nl)
#
# Distributed under the MIT License, see LICENSE
# Boolean flag values indicating 7bit or 14bit CC parameters
IS_CC7 = False
IS_CC14 = True
# dummy CC parameter value to represent an unmapped CC
UNMAPPED_CC = -1
from .config import MIDI_EFFECT_CHANNEL, UNMAPPED_ID
class CCInfo:
"""Class storing the channel and parameter number of a CC mapping, and
whether the associated controller on the E1 is 14bit (or not, in
which case it is 7bit). Also records the index of that controller in
the E1 preset.
"""
def __init__(self, v):
"""Initialise with a tuple
(control_id, MIDI_channel, is_cc14?, CC_parameter_no).
Where is_cc14? is IS_CC7 when the parameter is 7bit, IS_CC14 if 14bit.
Constructing from a tuple instead of a list of parameters, to allow
Devices.py to contain plain tuples in the cc_map.
control_id is either an integer (for plain controls) or a tuple
(control_id,value_id) for controls that are part of an ADSR or
similar.
"""
assert type(v) is tuple, f'{v} should be tuple but is {type(v)}'
(self._control_id, self._midi_channel, self._is_cc14, self._cc_no) = v
if type(self._control_id) is int:
assert self._control_id in range(-1,443), f'Control index {self._control_id} out of range.'
else:
assert type(self._control_id) is tuple, f'{self._control_id} should be an integer or a tuple.'
(cid,vid) = self._control_id
assert cid in range(-1,443), f'Control index {cid} out of range.'
assert vid in range(1,11), f'Value index {vid} out of range.'
assert self._midi_channel in range(1,17), f'MIDI channel {self._midi_channel} out of range.'
assert self._is_cc14 in [IS_CC7,IS_CC14], f'CC14 flag {self._is_cc14} out of range.'
assert self._cc_no in range(-1,128), f'CC parameter number {self._cc_no} out of range.'
def __repr__(self):
"""Return a string representation of CCInfo as a tuple of its values.
"""
return f'({self._control_id},{self._midi_channel},{self._is_cc14},{self._cc_no})'
def get_midi_channel(self):
"""Return the MIDI channel this object is mapped to (undefined if not mapped)
- result: channel; int (1..16)
"""
return self._midi_channel
def is_cc14(self):
"""Return whether the object represents a 7 or 14 bit CC parameter
(undefiend when not mapped).
- result: IC_CC14/True if 14 bit; ID_CC7/False if 7 bit; bool
"""
return self._is_cc14
def get_cc_no(self):
"""Return the CC parameter number of this object.
- result: the CC parameter number (-1 if not mapped); int (-1..127)
"""
return self._cc_no
def get_control_id(self):
"""Return the E1 preset control id of this object; always returned as a tuple!.
- result: the control id (-1,dc) if not mapped; tuple (int,int)
"""
if type(self._control_id) is int:
return (self._control_id,0)
else:
return self._control_id
def set_control_id(self,id):
"""Set the E1 preset control id of this object.
- id: value to set control id to; int
"""
self._control_id = id
def is_mapped(self):
"""Return whether object is mapped to a CC parameter at all.
- result: whether mapped or not ; bool
"""
return self._cc_no != UNMAPPED_CC
# CCInfo object for an unmapped parameter
UNMAPPED_CCINFO = CCInfo((UNMAPPED_ID,MIDI_EFFECT_CHANNEL,IS_CC7,UNMAPPED_CC))