1
1
# The MIT License
2
- #
2
+ #
3
3
# Copyright (c) 2018-2021 Olivier Jacques
4
- #
4
+ #
5
5
# Synthesia Kontrol: an app to light the keys of Native Instruments
6
6
# Komplete Kontrol MK2 keyboard, driven by Synthesia
7
7
8
+ import time
8
9
import hid
9
10
import mido
10
- import time
11
- import sys
12
11
13
12
NATIVE_INSTRUMENTS = 0x17cc
14
13
INSTR_ADDR = 0x1620
15
14
NB_KEYS = 61
16
15
MODE = "MK2"
17
16
17
+
18
18
def init ():
19
19
"""Connect to the keyboard, switch all lights off"""
20
20
global bufferC # Buffer with the full key/lights mapping
21
21
global device
22
22
23
23
print ("Opening Keyboard device..." )
24
- device = hid .device ()
24
+ device = hid .device ()
25
25
try :
26
26
device .open (NATIVE_INSTRUMENTS , INSTR_ADDR )
27
27
except Exception as e :
28
28
print ("Error: " + str (e ))
29
29
quit ()
30
30
31
- device .write ([0xa0 ])
32
-
31
+ # Write 3 bytes to the device: 0xa0, 0x00, 0x00
32
+ # Thanks to @xample for investigating this
33
+ device .write ([0xa0 , 0x00 , 0x00 ])
34
+
33
35
bufferC = [0x00 ] * 249
34
36
notes_off ()
35
37
36
38
return True
37
39
40
+
38
41
def notes_off ():
39
42
"""Turn off lights for all notes"""
40
43
@@ -46,26 +49,28 @@ def notes_off():
46
49
elif (MODE == "MK1" ):
47
50
device .write ([0x82 ] + bufferC )
48
51
else :
49
- print ("Error: unsupported mode - should be MK1 or MK2" )
52
+ print ("Error: unsupported mode - should be MK1 or MK2" )
50
53
quit ()
51
54
55
+
52
56
def accept_notes (port ):
53
57
"""Only let note_on and note_off messages through."""
54
58
for message in port :
55
59
if message .type in ('note_on' , 'note_off' ):
56
60
yield message
57
61
if message .type == 'control_change' and message .channel == 0 and message .control == 16 :
58
62
if (message .value & 4 ):
59
- print ("User is playing" )
63
+ print ("User is playing" )
60
64
if (message .value & 1 ):
61
- print ("Playing Right Hand" )
65
+ print ("Playing Right Hand" )
62
66
if (message .value & 2 ):
63
- print ("Playing Left Hand" )
67
+ print ("Playing Left Hand" )
64
68
notes_off ()
65
69
70
+
66
71
def CoolDemoSweep (loopcount ):
67
72
speed = 0.01
68
- for loop in range (0 ,loopcount ):
73
+ for loop in range (0 , loopcount ):
69
74
# Forward
70
75
for x in range (0 , NB_KEYS - 3 ):
71
76
if (MODE == "MK2" ):
@@ -97,30 +102,31 @@ def CoolDemoSweep(loopcount):
97
102
device .write (bufferC )
98
103
time .sleep (speed )
99
104
notes_off ()
100
-
105
+
106
+
101
107
def LightNote (note , status , channel , velocity ):
102
108
"""Light a note ON or OFF"""
103
109
104
- #bufferC[0] = 0x81 # For Komplete Kontrol MK2
110
+ # bufferC[0] = 0x81 # For Komplete Kontrol MK2
105
111
offset = OFFSET
106
112
key = (note + offset )
107
113
108
114
if key < 0 or key >= NB_KEYS :
109
- return
115
+ return
110
116
111
117
# Determine color
112
118
if (MODE == "MK2" ):
113
- left = 0x2d # Blue
114
- left_thumb = 0x2f # Lighter Blue
115
- right = 0x1d # Green
119
+ left = 0x2d # Blue
120
+ left_thumb = 0x2f # Lighter Blue
121
+ right = 0x1d # Green
116
122
right_thumb = 0x1f # Lighter Green
117
123
elif (MODE == "MK1" ):
118
- left = [0x00 ] + [0x00 ] + [0xFF ] # Blue
119
- left_thumb = [0x00 ] + [0x00 ] + [0x80 ] # Lighter Blue
120
- right = [0x00 ] + [0xFF ] + [0x00 ] # Green
124
+ left = [0x00 ] + [0x00 ] + [0xFF ] # Blue
125
+ left_thumb = [0x00 ] + [0x00 ] + [0x80 ] # Lighter Blue
126
+ right = [0x00 ] + [0xFF ] + [0x00 ] # Green
121
127
right_thumb = [0x00 ] + [0x80 ] + [0x00 ] # Lighter Green
122
128
else :
123
- print ("Error: unsupported mode - should be MK1 or MK2" )
129
+ print ("Error: unsupported mode - should be MK1 or MK2" )
124
130
quit ()
125
131
126
132
default = right
@@ -167,66 +173,68 @@ def LightNote(note, status, channel, velocity):
167
173
else :
168
174
device .write ([0x82 ] + bufferC )
169
175
176
+
170
177
if __name__ == '__main__' :
171
178
"""Main: connect to keyboard, open midi input port, listen to midi"""
172
- print ("Select your keyboard (1, 2, 3, ...) and press 'Enter':" )
173
- print (" 1-Komplete Kontrol S61 MK2" )
174
- print (" 2-Komplete Kontrol S88 MK2" )
175
- print (" 3-Komplete Kontrol S49 MK2" )
176
- print (" 4-Komplete Kontrol S61 MK1" )
177
- print (" 5-Komplete Kontrol S88 MK1" )
178
- print (" 6-Komplete Kontrol S49 MK1" )
179
- print (" 7-Komplete Kontrol S25 MK1" )
179
+ print ("Select your keyboard (1, 2, 3, ...) and press 'Enter':" )
180
+ print (" 1-Komplete Kontrol S61 MK2" )
181
+ print (" 2-Komplete Kontrol S88 MK2" )
182
+ print (" 3-Komplete Kontrol S49 MK2" )
183
+ print (" 4-Komplete Kontrol S61 MK1" )
184
+ print (" 5-Komplete Kontrol S88 MK1" )
185
+ print (" 6-Komplete Kontrol S49 MK1" )
186
+ print (" 7-Komplete Kontrol S25 MK1" )
180
187
keyboard = input ()
181
-
188
+
182
189
# Customize here for new keyboards
183
190
# Pull requests welcome!
184
191
if keyboard == "1" :
185
192
MODE = "MK2"
186
- INSTR_ADDR = 0x1620 # KK S61 MK2
193
+ INSTR_ADDR = 0x1620 # KK S61 MK2
187
194
NB_KEYS = 61
188
195
OFFSET = - 36
189
196
elif keyboard == "2" :
190
197
MODE = "MK2"
191
- INSTR_ADDR = 0x1630 # KK S88 MK2
198
+ INSTR_ADDR = 0x1630 # KK S88 MK2
192
199
NB_KEYS = 88
193
200
OFFSET = - 21
194
201
elif keyboard == "3" :
195
202
MODE = "MK2"
196
- INSTR_ADDR = 0x1610 # KK S49 MK2
203
+ INSTR_ADDR = 0x1610 # KK S49 MK2
197
204
NB_KEYS = 49
198
205
OFFSET = - 36
199
206
elif keyboard == "4" :
200
207
MODE = "MK1"
201
- INSTR_ADDR = 0x1360 # KK S61 MK1
208
+ INSTR_ADDR = 0x1360 # KK S61 MK1
202
209
NB_KEYS = 61
203
210
OFFSET = - 36
204
211
elif keyboard == "5" :
205
212
MODE = "MK1"
206
- INSTR_ADDR = 0x1410 # KK S88 MK1
213
+ INSTR_ADDR = 0x1410 # KK S88 MK1
207
214
NB_KEYS = 88
208
215
OFFSET = - 21
209
216
elif keyboard == "6" :
210
217
MODE = "MK1"
211
- INSTR_ADDR = 0x1350 # KK S49 MK1
218
+ INSTR_ADDR = 0x1350 # KK S49 MK1
212
219
NB_KEYS = 49
213
220
OFFSET = - 36
214
221
elif keyboard == "7" :
215
222
MODE = "MK1"
216
- INSTR_ADDR = 0x1340 # KK S25 MK1
223
+ INSTR_ADDR = 0x1340 # KK S25 MK1
217
224
NB_KEYS = 25
218
225
OFFSET = - 21
219
226
else :
220
- print ("Got '" + keyboard + "' - please type a number which corresponds to your keyboard, then Enter" )
227
+ print ("Got '" + keyboard +
228
+ "' - please type a number which corresponds to your keyboard, then Enter" )
221
229
quit ()
222
-
223
- print ("Connecting to Komplete Kontrol Keyboard" )
230
+
231
+ print ("Connecting to Komplete Kontrol Keyboard" )
224
232
connected = init ()
225
233
portName = ""
226
234
if connected :
227
235
print ("Connected to Komplete Kontrol!" )
228
236
CoolDemoSweep (2 ) # Happy dance
229
- print ("Opening LoopBe input port" )
237
+ print ("Opening LoopBe input port" )
230
238
ports = mido .get_input_names ()
231
239
for port in ports :
232
240
print (" Found MIDI port " + port + "..." )
@@ -236,8 +244,9 @@ def LightNote(note, status, channel, velocity):
236
244
print ("Error: can't find 'LoopBe' midi port. Please install LoopBe1 from http://www.nerds.de/en/download.html (Windows) or name your IAC midi device 'LoopBe' (on Mac)." )
237
245
exit (1 )
238
246
239
- print ("Listening to Midi on LoopBe midi port" )
247
+ print ("Listening to Midi on LoopBe midi port" )
240
248
with mido .open_input (portName ) as midiPort :
241
249
for message in accept_notes (midiPort ):
242
250
print ('Received {}' .format (message ))
243
- LightNote (message .note , message .type , message .channel , message .velocity )
251
+ LightNote (message .note , message .type ,
252
+ message .channel , message .velocity )
0 commit comments