4747 error ("The project dependencies have changed! Run the requirements setup command again!" )
4848
4949class Core :
50+ CORE = None
5051
5152 def rotate_mode (self , notes : str , mode : int ):
5253 """Rotates a mode string (see: scales.yaml strings with x and .)"""
@@ -135,7 +136,7 @@ def set_light(self, x, y, col, index=None, mark=False): # col is [1,11], 0 rese
135136 return
136137
137138 if not index :
138- index = self .get_note_index (x , y )
139+ index = self .get_note_index (x , y , transpose = False )
139140
140141 self .mark_lights [y ][x ] = mark
141142 if self .linn_out :
@@ -169,8 +170,8 @@ def set_light(self, x, y, col, index=None, mark=False): # col is [1,11], 0 rese
169170
170171 def reset_light (self , x , y , reset_red = True ):
171172 """Reset the light at x, y"""
172- note = self .get_note_index (x , y )
173- # print(note)
173+ note = self .get_note_index (x , y , transpose = False )
174+
174175 if self .is_split ():
175176 split_chan = self .channel_from_split (x , self .board_h - y - 1 )
176177 if split_chan :
@@ -197,7 +198,7 @@ def reset_light(self, x, y, reset_red=True):
197198
198199 def reset_launchpad_light (self , x , y , launchpad = None ):
199200 """Reset the launchpad light at x, y"""
200- note = self .get_note_index (x , 8 - y - 1 )
201+ note = self .get_note_index (x , 8 - y - 1 , transpose = False )
201202 # if self.is_split():
202203 # split_chan = self.channel_from_split(x, self.board_h - y - 1)
203204 # if split_chan:
@@ -270,28 +271,30 @@ def reset_lights(self):
270271 # except IndexError:
271272 # pass
272273
273- def xy_to_midi (self , x , y ):
274+ def xy_to_midi (self , x , y , transpose = True ):
274275 """x, y coordinate to midi note based on layout (this can be improved)"""
275276 y = self .board_h - y - 1
276277 column_offset = self .options .column_offset
277278 row_offset = self .options .row_offset
278279 xx = x + self .options .base_offset
279- r = row_offset * y + column_offset * xx
280+ r = row_offset * y + ( column_offset * ( xx + self . position . x ))
280281 r += 24
281282 if self .flipped :
282283 r += 7
284+ r += self .tonic if transpose else 0
283285 # print(x, y, r)
284286 return r
285287
286288 def get_note_index (self , x , y , transpose = True ):
287289 """Get the note index (0-11) for a given x, y"""
288290 y += self .flipped
289- x += self .transpose
291+ x += self .position . x
290292 column_offset = self .options .column_offset
291293 row_offset = self .options .row_offset
292294 y = self .board_h - y - 1
293295 x += self .options .base_offset
294- return (row_offset * y + column_offset * x ) % len (NOTES )
296+ tr = self .tonic if transpose else 0
297+ return (row_offset * y + column_offset * x + tr ) % len (NOTES )
295298 # ofs = (self.board_h - y) // 2 + BASE_OFFSET
296299 # step = 2 if WHOLETONE else 1
297300 # tr = self.tonic if transpose else 0
@@ -307,7 +310,7 @@ def get_note(self, x, y, transpose=True):
307310 def get_color (self , x , y ):
308311 """Get color for x, y"""
309312 # return NOTE_COLORS[get_note_index(x, y)]
310- note = self .get_note_index (x , y )
313+ note = self .get_note_index (x , y , transpose = False )
311314 # note = (note - self.tonic) % 12
312315 # if self.is_split():
313316 # split_chan = self.channel_from_split(x, self.board_h - y - 1)
@@ -448,11 +451,11 @@ def get_octave(self, x, y):
448451 # if self.flipped:
449452 # if self.tonic % 2 == 0:
450453 # y -= 1
451- # octave = int(x + 4 + self.transpose + y * 2.5) // 6
454+ # octave = int(x + 4 + self.position.x + y * 2.5) // 6
452455 # else:
453456 if self .tonic % 2 :
454457 y -= 1
455- octave = int (x + 4 + self .transpose + y * 2.5 ) // 6
458+ octave = int (x + 4 + self .position . x + y * 2.5 ) // 6
456459 return octave
457460
458461 def held_note_count (self ):
@@ -574,9 +577,12 @@ def note_on(self, data, timestamp, width=None, curve=True, mpe=None, octave=0, t
574577 x = col
575578 midinote = row_offset * y + column_offset * x
576579 midinote += 32
577- midinote += 12 * octave
578580 if self .flipped :
579581 midinote += 7
582+ visual_midinote = midinote
583+ midinote += 12 * (octave + self .octave )
584+ midinote += self .options .column_offset * self .position .x
585+ midinote += transpose + self .tonic
580586
581587 # print(x, y, midinote)
582588 # return
@@ -604,7 +610,7 @@ def note_on(self, data, timestamp, width=None, curve=True, mpe=None, octave=0, t
604610 # data[1] += (self.octave + self.octave_base + octave) * 12
605611 # data[1] += transpose
606612 # data[1] += BASE_OFFSET
607- # midinote = data[1] - 24 + self.transpose * 2
613+ # midinote = data[1] - 24 + self.position.x * 2
608614 col_full = x + (left_width if within_hardware_split else 0 )
609615
610616 # figure out if note is on left or right side
@@ -626,8 +632,8 @@ def note_on(self, data, timestamp, width=None, curve=True, mpe=None, octave=0, t
626632 data [1 ] = midinote
627633
628634 if not aftertouch :
629- self .mark (midinote - 24 , 1 , only_row = row )
630- # data[1] += self.out_octave * 12 + self.transpose * 2
635+ self .mark (visual_midinote - 24 , 1 , only_row = row )
636+ # data[1] += self.out_octave * 12 + self.position.x * 2
631637 # if self.flipped:
632638 # data[1] += 7
633639
@@ -760,7 +766,7 @@ def note_off(self, data, timestamp, width=None, mpe=None, octave=0, transpose=0,
760766 # data[1] += (self.octave + self.octave_base + octave) * 12
761767 # data[1] += BASE_OFFSET
762768 # data[1] += transpose
763- # midinote = data[1] - 24 + self.transpose * 2
769+ # midinote = data[1] - 24 + self.position.x * 2
764770
765771 row = data [1 ] // width
766772 col = data [1 ] % width
@@ -773,9 +779,12 @@ def note_off(self, data, timestamp, width=None, mpe=None, octave=0, transpose=0,
773779 x = col
774780 midinote = row_offset * y + column_offset * x
775781 midinote += 32
776- midinote += 12 * octave
777782 if self .flipped :
778783 midinote += 7
784+ visual_midinote = midinote
785+ midinote += 12 * (octave + self .octave )
786+ midinote += self .options .column_offset * self .position .x
787+ midinote += transpose + self .tonic
779788 # print('off', x, y, midinote)
780789
781790 col_full = x + (left_width if within_hardware_split else 0 )
@@ -794,8 +803,8 @@ def note_off(self, data, timestamp, width=None, mpe=None, octave=0, transpose=0,
794803
795804 data [1 ] = midinote
796805
797- self .mark (midinote - 24 , 0 , only_row = y )
798- # data[1] += self.out_octave * 12 + self.transpose * 2
806+ self .mark (visual_midinote - 24 , 0 , only_row = y )
807+ # data[1] += self.out_octave * 12 + self.position.x * 2
799808 # if self.flipped:
800809 # data[1] += 7
801810
@@ -1087,7 +1096,7 @@ def cb_launchpad_in(self, lp, event, timestamp=0):
10871096 note = y * 8 + x
10881097 note += 12
10891098 if not self .is_macro_button (x , 8 - y - 1 ):
1090- self .note_on ([160 , note , event [2 ]], timestamp , width = 8 , octave = lp .octave_separation , force_channel = self .options .launchpad_channel )
1099+ self .note_on ([160 , note , event [2 ]], timestamp , width = 8 , transpose = lp . transpose , octave = lp .get_octave () , force_channel = self .options .launchpad_channel )
10911100 self .articulation .pressure (vel / 127 )
10921101 else :
10931102 self .macro (x , 8 - y - 1 , vel / 127 )
@@ -1098,7 +1107,7 @@ def cb_launchpad_in(self, lp, event, timestamp=0):
10981107 self .reset_launchpad_light (x , y , launchpad = lp )
10991108 if not self .is_macro_button (x , 8 - y - 1 ):
11001109 note = y * 8 + x
1101- self .note_off ([128 , note , event [2 ]], timestamp , width = 8 , octave = lp .octave_separation , force_channel = self .options .launchpad_channel )
1110+ self .note_off ([128 , note , event [2 ]], timestamp , width = 8 , transpose = lp . transpose , octave = lp .get_octave () , force_channel = self .options .launchpad_channel )
11021111 else :
11031112 self .macro (x , 8 - y - 1 , False )
11041113 else : # note on
@@ -1108,23 +1117,12 @@ def cb_launchpad_in(self, lp, event, timestamp=0):
11081117 self .set_launchpad_light (x , y , - 1 , launchpad = lp )
11091118 if not self .is_macro_button (x , 8 - y - 1 ):
11101119 note = y * 8 + x
1111- self .note_on ([144 , note , event [2 ]], timestamp , width = 8 , octave = lp .octave_separation , force_channel = self .options .launchpad_channel )
1120+ self .note_on ([144 , note , event [2 ]], timestamp , width = 8 , transpose = lp . transpose , octave = lp .get_octave () , force_channel = self .options .launchpad_channel )
11121121 else :
11131122 self .macro (x , 8 - y - 1 , True )
11141123 else :
11151124 # Launchpad X buttons
1116- if lp .mode == 'lpx' :
1117- if x == 0 :
1118- self .octave += 1
1119- self .clear_marks (use_lights = False )
1120- elif x == 1 :
1121- self .octave -= 1
1122- self .clear_marks (use_lights = False )
1123- elif x == 2 :
1124- self .move_board (- 1 )
1125- elif x == 3 :
1126- self .move_board (1 )
1127- # elif x == 4:
1125+ lp .button (x , 8 - y - 1 )
11281126
11291127 # uses raw events (Launchpad X)
11301128 # def cb_launchpad_in(self, event, timestamp=0):
@@ -1212,6 +1210,8 @@ def sig(self, signal, frame):
12121210 self .quit ()
12131211
12141212 def __init__ (self ):
1213+ Core .CORE = self
1214+
12151215 signal .signal (signal .SIGINT , self .sig )
12161216 signal .signal (signal .SIGTERM , self .sig )
12171217
@@ -1448,7 +1448,8 @@ def __init__(self):
14481448 - 2
14491449 ) # this is for both the visualizer and the keyboard simulator marking atm
14501450 self .octave_base = - 2
1451- self .transpose = 0
1451+ # self.position.x = 0
1452+ self .position = glm .ivec2 (0 , 0 ) # only x is used right now
14521453 self .rotated = False # transpose -3 whole steps
14531454 self .flipped = False # vertically shift +1
14541455 self .config_save_timer = 1.0
@@ -1710,31 +1711,27 @@ def __init__(self):
17101711 lp = launchpad .LaunchpadPro ()
17111712 if lp .Check (0 ):
17121713 if lp .Open (0 ):
1713- self .launchpads += [Launchpad (lp , "pro" , 0 )]
1714+ self .launchpads += [Launchpad (self , lp , "pro" , 0 )]
17141715 if launchpad .LaunchpadProMk3 ().Check (0 ):
17151716 lp = launchpad .LaunchpadProMk3 ()
17161717 if lp .Open (0 ):
1717- self .launchpads += [Launchpad (lp , "promk3" , 0 )]
1718+ self .launchpads += [Launchpad (self , lp , "promk3" , 0 )]
17181719 if launchpad .LaunchpadLPX ().Check (1 ):
17191720 lp = launchpad .LaunchpadLPX ()
17201721 if lp .Open (1 ):
1721- self .launchpads += [Launchpad (lp , "lpx" , 0 )]
1722+ self .launchpads += [Launchpad (self , lp , "lpx" , 0 )]
17221723 if launchpad .LaunchpadLPX ().Check (3 ):
17231724 lp = launchpad .LaunchpadLPX ()
17241725 if lp .Open (3 ): # second
1725- self .launchpads += [Launchpad (lp , "lpx" , 1 , self .options .octave_separation )]
1726+ self .launchpads += [Launchpad (self , lp , "lpx" , 1 , self .options .octave_separation )]
17261727
17271728 if self .launchpads :
17281729 print ('Launchpads:' , len (self .launchpads ))
17291730
17301731 self .done = False
17311732
17321733 for lp in self .launchpads :
1733- if lp .mode == "lpx" :
1734- lp .out .LedCtrlXY (0 , 0 , 0 , 0 , 63 )
1735- lp .out .LedCtrlXY (1 , 0 , 0 , 0 , 63 )
1736- lp .out .LedCtrlXY (2 , 0 , 63 , 0 , 63 )
1737- lp .out .LedCtrlXY (3 , 0 , 63 , 0 , 63 )
1734+ lp .set_lights ()
17381735
17391736 # if self.launchpad:
17401737 # # use the alternate colors
@@ -1899,18 +1896,19 @@ def move_board(self, val):
18991896
19001897 aval = abs (val )
19011898 if aval > 1 : # more than one shift
1902- sval = sign (val )
1903- for rpt in range (aval ):
1904- self .move_board (sval )
1905- self .transpose += sval
1899+ assert False
1900+ # sval = sign(val)
1901+ # for rpt in range(aval):
1902+ # self.move_board(sval)
1903+ # self.position.x += sval
19061904 elif val == 1 : # shift right (add column left)
19071905 for y in range (len (self .board )):
19081906 self .board [y ] = [0 ] + self .board [y ][:- 1 ]
1909- self .transpose += val
1907+ self .position . x += val
19101908 elif val == - 1 : # shift left (add column right)
19111909 for y in range (len (self .board )):
19121910 self .board [y ] = self .board [y ][1 :] + [0 ]
1913- self .transpose += val
1911+ self .position . x += val
19141912 self .dirty = self .dirty_lights = True
19151913
19161914 def quit (self ):
@@ -2008,16 +2006,23 @@ def is_split(self):
20082006 return self .split_state and self .split_out
20092007
20102008 def set_tonic (self , val ):
2011- odd = (self .tonic % 2 == 1 )
2009+ self .send_all_notes_off ()
2010+
20122011 self .tonic = val
2013- new_odd = (self .tonic % 2 == 1 )
2014- if odd != new_odd :
2015- self .flipped = not self .flipped
2016- if new_odd :
2017- self .transpose = (self .tonic // 2 - 3 ) % 6
2018- self .transpose -= 6
2019- else :
2020- self .transpose = (self .tonic // 2 ) % 6
2012+ # print('val', val)
2013+ # odd = (self.tonic % 2 == 1)
2014+ # self.tonic = val
2015+ # print('new tonic', self.tonic)
2016+ # new_odd = (self.tonic % 2 == 1)
2017+ # # if odd != new_odd:
2018+ # # self.flipped = not self.flipped
2019+ # if new_odd:
2020+ # self.position.x = (self.tonic // 2 - 3) % 6
2021+ # self.position.x -= 6
2022+ # else:
2023+ # self.position.x = (self.tonic // 2) % 6
2024+ # print('new pos', self.position.x)
2025+
20212026 self .dirty = self .dirty_lights = True
20222027
20232028 def logic (self , dt ):
@@ -2127,10 +2132,10 @@ def logic(self, dt):
21272132 # self.dirty = True
21282133 elif ev .ui_element == self .btn_rotate :
21292134 if self .rotated :
2130- self .transpose += 3
2135+ self .position . x += 3
21312136 self .rotated = False
21322137 else :
2133- self .transpose -= 3
2138+ self .position . x -= 3
21342139 self .rotated = True
21352140 self .dirty = self .dirty_lights = True
21362141 self .clear_marks (use_lights = False )
@@ -2300,7 +2305,7 @@ def render(self):
23002305 x = 0
23012306 for cell in row :
23022307 # write text
2303- note = self .get_note (x , y , False )
2308+ note = self .get_note (x , y , True )
23042309
23052310 split_chan = self .channel_from_split (x , y )
23062311
0 commit comments