17
17
from src .articulation import Articulation
18
18
# from src.gamepad import Gamepad
19
19
20
+ GRADIENT = False
21
+
22
+ try :
23
+ from easygui import msgbox
24
+ except ImportError :
25
+ print ("The project dependencies have changed! Run the requirements setup command again!" )
26
+ sys .exit (1 )
27
+
28
+ msgbox ("test" )
29
+
20
30
with open (os .devnull , "w" ) as devnull :
21
31
# suppress pygame messages (to keep console output clean)
22
32
stdout = sys .stdout
26
36
sys .stdout = stdout
27
37
import pygame_gui
28
38
39
+ def error (err ):
40
+ msgbox (err )
41
+ sys .exit (1 )
42
+
43
+ def dependency_error ():
44
+ error ("The project dependencies have changed! Run the requirements setup command again!" )
45
+
29
46
try :
30
47
import launchpad_py as launchpad
31
48
except ImportError :
32
49
try :
33
50
import launchpad
34
51
except ImportError :
35
- error ( "The project dependencies have changed! Run the requirements setup command again!" )
52
+ dependency_error ( )
36
53
37
54
try :
38
55
import yaml
39
56
except ImportError :
40
- error ("The project dependencies have changed! Run the requirements setup command again!" )
41
-
42
- # import mido
57
+ dependency_error ()
43
58
44
59
try :
45
60
import musicpy as mp
46
61
except ImportError :
47
- error ( "The project dependencies have changed! Run the requirements setup command again!" )
62
+ dependency_error ( )
48
63
49
64
class Core :
50
65
CORE = None
@@ -150,17 +165,30 @@ def send_all_notes_off(self):
150
165
return
151
166
# for ch in range(0,15):
152
167
ch = 0
153
- self .midi_write (self .midi_out , [0xb0 | ch , 120 , 0 ], 0 )
154
- self .midi_write (self .midi_out , [0xb0 | ch , 123 , 0 ], 0 )
168
+ self .midi_write (self .midi_out , [0xb0 | ch , 120 , 0 ], 0 ) # all sounds off
169
+ self .midi_write (self .midi_out , [0xb0 | ch , 123 , 0 ], 0 ) # all notes off
155
170
156
171
def ls_color (self , x , y , col ):
157
172
"""Set LinnStrument pad color"""
158
173
if self .linn_out :
159
174
self .send_ls_cc (0 , 20 , x + 1 )
160
175
self .send_ls_cc (0 , 21 , self .board_h - y - 1 )
161
176
self .send_ls_cc (0 , 22 , col )
177
+ # time.sleep(self.options.rpn_delay)
178
+
179
+ def transform_launchpad_coord (self , idx , x , y ):
180
+ if self .launchpads [idx ].rot :
181
+ x , y = y , x
182
+ x = (8 - x - 1 )
183
+ return x , y
162
184
163
- def set_light (self , x , y , col , index = None , mark = False ): # col is [1,11], 0 resets
185
+ def untransform_launchpad_coord (self , idx , x , y ):
186
+ if self .launchpads [idx ].rot :
187
+ x = (8 - x - 1 )
188
+ x , y = y , x
189
+ return x , y
190
+
191
+ def set_light (self , x , y , col , index = None , mark = False , transform = True ): # col is [1,11], 0 resets
164
192
"""Set light to color `col` at x, y if in range and connected"""
165
193
if y < 0 or y >= self .board_h :
166
194
return
@@ -186,19 +214,23 @@ def set_light(self, x, y, col, index=None, mark=False): # col is [1,11], 0 rese
186
214
lp_col = 0
187
215
else :
188
216
lp_col = ivec3 (0 )
189
- if 0 <= x < 8 and 0 <= y < 8 :
190
- if not self .is_macro_button (x , y ):
217
+ if transform :
218
+ xx , yy = self .transform_launchpad_coord (lp .index , x , y )
219
+ else :
220
+ xx , yy = x , y
221
+ if 0 <= xx < 8 and 0 <= yy < 8 :
222
+ if not self .is_macro_button (xx , yy ):
191
223
if self .options .launchpad_colors :
192
- lp .out .LedCtrlXYByCode (x , y + 1 , lp_col )
224
+ lp .out .LedCtrlXYByCode (xx , yy + 1 , lp_col )
193
225
else :
194
- lp .out .LedCtrlXY (x , y + 1 , lp_col [0 ], lp_col [1 ], None if lp_col [2 ] == 0 else lp_col [2 ])
226
+ lp .out .LedCtrlXY (xx , yy + 1 , lp_col [0 ], lp_col [1 ], None if lp_col [2 ] == 0 else lp_col [2 ])
195
227
else :
196
228
if self .options .launchpad_colors :
197
- lp .out .LedCtrlXYByCode (x , y + 1 , 3 )
229
+ lp .out .LedCtrlXYByCode (xx , yy + 1 , 3 )
198
230
else :
199
- lp .out .LedCtrlXY (x , y + 1 , 63 , 63 , 63 )
231
+ lp .out .LedCtrlXY (xx , yy + 1 , 63 , 63 , 63 )
200
232
201
- def reset_light (self , x , y , reset_red = True ):
233
+ def reset_light (self , x , y , reset_red = True , transform = True ):
202
234
"""Reset the light at x, y"""
203
235
note = self .get_note_index (x , y , transpose = False )
204
236
@@ -223,10 +255,10 @@ def reset_light(self, x, y, reset_red=True):
223
255
except IndexError :
224
256
light_col = 7
225
257
226
- self .set_light (x , y , light_col , note )
258
+ self .set_light (x , y , light_col , note , transform = transform )
227
259
self .mark_lights [y ][x ] = False
228
260
229
- def reset_launchpad_light (self , x , y , launchpad = None ):
261
+ def reset_launchpad_light (self , x , y , launchpad = None , transform = True ):
230
262
"""Reset the launchpad light at x, y"""
231
263
note = self .get_note_index (x , 8 - y - 1 , transpose = False )
232
264
# if self.is_split():
@@ -238,18 +270,23 @@ def reset_launchpad_light(self, x, y, launchpad=None):
238
270
# else:
239
271
# light_col = self.options.lights[note]
240
272
for lp in ([launchpad ] if launchpad else self .launchpads ):
241
- self .set_launchpad_light (x , y , note )
273
+ self .set_launchpad_light (x , y , note , transform = True )
242
274
243
- def set_mark_light (self , x , y , state = True , launchpad = None ):
275
+ # transform: rotate launchpad if in rotated mode
276
+ def set_mark_light (self , x , y , state = True , launchpad = None , transform = True ):
244
277
"""Set launchpad light to touched color"""
245
278
self .mark_lights [y ][x ] = state
246
279
for lp in ([launchpad ] if launchpad else self .launchpads ):
247
280
lp_col = self .options .mark_color
248
281
if state :
249
- lp .out .LedCtrlXY (x , y , lp_col [0 ], lp_col [1 ], lp_col [2 ])
282
+ if transform :
283
+ xx , yy = self .transform_launchpad_coord (lp .index , x , y )
284
+ else :
285
+ xx , yy = x , y
286
+ lp .out .LedCtrlXY (xx , yy , lp_col [0 ], lp_col [1 ], lp_col [2 ])
250
287
251
288
# `color` below is an scale index (0, 1, 2...)
252
- def set_launchpad_light (self , x , y , color , launchpad = None ):
289
+ def set_launchpad_light (self , x , y , color , launchpad = None , transform = True ):
253
290
"""Set launchpad light to color index"""
254
291
if self .is_macro_button (x , 8 - y - 1 ):
255
292
if self .options .launchpad_colors :
@@ -275,10 +312,14 @@ def set_launchpad_light(self, x, y, color, launchpad=None):
275
312
col = self .options .mark_color / 4
276
313
277
314
for lp in ([launchpad ] if launchpad else self .launchpads ):
315
+ if transform :
316
+ xx , yy = self .transform_launchpad_coord (lp .index , x , y )
317
+ else :
318
+ xx , yy = x , y
278
319
if self .options .launchpad_colors :
279
320
lp .out .LedCtrlXYByCode (x , 8 - y , col )
280
321
else :
281
- lp .out .LedCtrlXY (x , 8 - y , col [0 ], col [1 ], col [2 ])
322
+ lp .out .LedCtrlXY (xx , 8 - yy , col [0 ], col [1 ], col [2 ])
282
323
283
324
def setup_lights (self ):
284
325
"""Set all lights"""
@@ -549,7 +590,7 @@ def next_free_note(self):
549
590
def is_mpe (self ):
550
591
return self .options .one_channel == 0
551
592
552
- def note_on (self , data , timestamp , width = None , curve = True , mpe = None , octave = 0 , transpose = 0 , force_channel = None ):
593
+ def note_on (self , data , timestamp , width = None , curve = True , mpe = None , octave = 0 , transpose = 0 , force_channel = None , bend = 0.0 ):
553
594
# if mpe is None:
554
595
# mpe = self.options.mpe
555
596
d0 = data [0 ]
@@ -709,6 +750,18 @@ def note_on(self, data, timestamp, width=None, curve=True, mpe=None, octave=0, t
709
750
self .note_set .add (midinote )
710
751
self .dirty_chord = True
711
752
753
+ if GRADIENT :
754
+ if x > 6 :
755
+ bend = (x - 6 ) - y / 2
756
+ bend *= (1 / 6 )
757
+ try :
758
+ # print(bend)
759
+ pitch_lsb , pitch_msb = compose_pitch_bend (bend , 1 / 12 )
760
+ # print(pitch_msb, pitch_lsb)
761
+ self .midi_write (self .midi_out , [0xE0 | ch , pitch_lsb , pitch_msb ], timestamp )
762
+ except Exception as e :
763
+ print (e )
764
+
712
765
if self .is_split ():
713
766
if split_chan == 0 :
714
767
# self.midi_out.write([[data, ev[1]]]
@@ -1133,6 +1186,7 @@ def cb_launchpad_in(self, lp, event, timestamp=0):
1133
1186
note = y * 8 + x
1134
1187
note += 12
1135
1188
if not self .is_macro_button (x , 8 - y - 1 ):
1189
+ # x, y = self.transform_launchpad_coord(lp.index, x, y)
1136
1190
self .note_on ([160 , note , event [2 ]], timestamp , width = 8 , transpose = lp .transpose , octave = lp .get_octave (), force_channel = self .options .launchpad_channel )
1137
1191
self .articulation .pressure (vel / 127 )
1138
1192
else :
@@ -1141,8 +1195,10 @@ def cb_launchpad_in(self, lp, event, timestamp=0):
1141
1195
x = event [0 ]
1142
1196
y = 8 - event [1 ]
1143
1197
if 0 <= x < 8 and 0 <= y < 8 :
1144
- self .reset_launchpad_light (x , y , launchpad = lp )
1198
+ # x2, y2 = self.untransform_launchpad_coord(lp.index, x, y)
1199
+ # self.reset_launchpad_light(x2, y2, launchpad=lp, transform=False)
1145
1200
if not self .is_macro_button (x , 8 - y - 1 ):
1201
+ x , y = self .transform_launchpad_coord (lp .index , x , y )
1146
1202
note = y * 8 + x
1147
1203
self .note_off ([128 , note , event [2 ]], timestamp , width = 8 , transpose = lp .transpose , octave = lp .get_octave (), force_channel = self .options .launchpad_channel )
1148
1204
else :
@@ -1154,8 +1210,10 @@ def cb_launchpad_in(self, lp, event, timestamp=0):
1154
1210
x = event [0 ]
1155
1211
y = 8 - event [1 ]
1156
1212
if 0 <= x < 8 and 0 <= y < 8 :
1157
- self .set_launchpad_light (x , y , - 1 , launchpad = lp )
1213
+ # x2, y2 = self.untransform_launchpad_coord(lp.index, x, y)
1214
+ # self.set_launchpad_light(x2, y2, -1, launchpad=lp, transform=False)
1158
1215
if not self .is_macro_button (x , 8 - y - 1 ):
1216
+ x , y = self .transform_launchpad_coord (lp .index , x , y )
1159
1217
note = y * 8 + x
1160
1218
self .note_on ([144 , note , event [2 ]], timestamp , width = 8 , transpose = lp .transpose , octave = lp .get_octave (), force_channel = self .options .launchpad_channel )
1161
1219
else :
@@ -1300,6 +1358,9 @@ def __init__(self):
1300
1358
self .options .colors = list (self .options .colors .split ("," ))
1301
1359
self .options .colors = list (map (lambda x : glm .ivec3 (get_color (x )), self .options .colors ))
1302
1360
1361
+ self .options .swap_launchpads = get_option (opts , "swap_launchpads" , self .options .swap_launchpads )
1362
+ self .options .rotate_launchpads = get_option (opts , "rotate_launchpads" , self .options .rotate_launchpads )
1363
+
1303
1364
self .options .launchpad_colors = get_option (opts , "launchpad_colors" , DEFAULT_OPTIONS .launchpad_colors )
1304
1365
if self .options .launchpad_colors :
1305
1366
self .options .launchpad_colors = list (self .options .launchpad_colors .split ("," ))
@@ -1349,6 +1410,10 @@ def __init__(self):
1349
1410
opts , "lite" , DEFAULT_OPTIONS .lite
1350
1411
)
1351
1412
1413
+ self .options .rpn_delay = get_option (
1414
+ opts , "rpn_delay" , DEFAULT_OPTIONS .rpn_delay
1415
+ )
1416
+
1352
1417
# bend the velocity curve, examples: 0.5=sqrt, 1.0=default, 2.0=squared
1353
1418
self .options .velocity_curve = get_option (
1354
1419
opts , "velocity_curve" , DEFAULT_OPTIONS .velocity_curve
@@ -1544,6 +1609,7 @@ def __init__(self):
1544
1609
pygame .display .set_caption (TITLE )
1545
1610
self .icon = pygame .image .load ('icon.png' )
1546
1611
pygame .display .set_icon (self .icon )
1612
+ pygame .display .set_allow_screensaver (True )
1547
1613
# if FOCUS:
1548
1614
# pygame.mouse.set_visible(0)
1549
1615
# pygame.event.set_grab(True)
@@ -1780,8 +1846,11 @@ def __init__(self):
1780
1846
self .launchpads += [Launchpad (self , lp , "lpx" , num_launchpads , self .options .octave_separation )]
1781
1847
num_launchpads += 1
1782
1848
1783
- if self .launchpads :
1784
- print ('Launchpads:' , len (self .launchpads ))
1849
+ # if self.launchpads:
1850
+ # launchpad_count = len(self.launchpads)
1851
+ # print('Launchpads:', launchpad_count)
1852
+ # if launchpad_count >= 2 and self.options.swap_launchpads:
1853
+ # self.launchpads = self.launchpads[::-1]
1785
1854
1786
1855
self .done = False
1787
1856
@@ -1823,6 +1892,8 @@ def __init__(self):
1823
1892
self .setup_rpn ()
1824
1893
# self.test()
1825
1894
1895
+ # msgbox("Welcome to midimech!\n\nThis project is still in development and some features are experimental. Feel free to play around and report any bugs to flipcoder. Thanks!", "midimech")
1896
+
1826
1897
def midi_mode_rpn (self , on = True ):
1827
1898
if on :
1828
1899
self .rpn (0 , 1 if self .is_mpe () else 0 )
@@ -1875,7 +1946,7 @@ def rpn(self, num, value):
1875
1946
self .midi_write (self .linn_out , [176 , 38 , value_lsb ])
1876
1947
self .midi_write (self .linn_out , [176 , 101 , 127 ])
1877
1948
self .midi_write (self .linn_out , [176 , 100 , 127 ])
1878
- time .sleep (0.05 )
1949
+ time .sleep (self . options . rpn_delay )
1879
1950
1880
1951
def mpe_rpn (self , on = True ):
1881
1952
"""Sets up MPE settings (except MIDI mode)"""
@@ -2354,7 +2425,7 @@ def render(self):
2354
2425
2355
2426
self .screen .surface .fill ((0 , 0 , 0 ))
2356
2427
b = 2 # border
2357
- sz = self .screen_w / self . board_w
2428
+ sz = self .scale . x
2358
2429
y = 0
2359
2430
rad = int (sz // 2 - 8 )
2360
2431
0 commit comments