def change_backlight_brightness(self, value): self.backlight_brightness_percent += value self.backlight_brightness_percent = clamp(self.backlight_brightness_percent, 0, 100) self.backlight_brightness = 255 * self.backlight_brightness_percent / 100 self.usersettings.change_setting_value("backlight_brightness", int(self.backlight_brightness)) self.usersettings.change_setting_value("backlight_brightness_percent", self.backlight_brightness_percent) fastColorWipe(self.ledstrip.strip, True, self)
def light_keys_in_range(self, location): fastColorWipe(self.ledstrip.strip, True, self) color_counter = 0 for i in self.multicolor: start = self.multicolor_range[int(color_counter)][0] end = self.multicolor_range[int(color_counter)][1] if start > 92: note_offset_start = 2 elif start > 55: note_offset_start = 1 else: note_offset_start = 0 if end > 92: note_offset_end = 2 elif end > 55: note_offset_end = 1 else: note_offset_end = 0 red = self.multicolor[int(color_counter)][0] green = self.multicolor[int(color_counter)][1] blue = self.multicolor[int(color_counter)][2] self.ledstrip.strip.setPixelColor(int(((start - 20) * 2 - note_offset_start)), Color(int(green), int(red), int(blue))) self.ledstrip.strip.setPixelColor(int(((end - 20) * 2 - note_offset_end)), Color(int(green), int(red), int(blue))) color_counter += 1
def change_backlight_color(self, color, value): if color == "Red": if self.backlight_red <= 255 and self.backlight_red >= 0: self.backlight_red += int(value) self.backlight_red = clamp(self.backlight_red, 0, 255) elif color == "Green": if self.backlight_green <= 255 and self.backlight_green >= 0: self.backlight_green += int(value) self.backlight_green = clamp(self.backlight_green, 0, 255) elif color == "Blue": if self.backlight_blue <= 255 and self.backlight_blue >= 0: self.backlight_blue += int(value) self.backlight_blue = clamp(self.backlight_blue, 0, 255) self.usersettings.change_setting_value("backlight_red", self.backlight_red) self.usersettings.change_setting_value("backlight_green", self.backlight_green) self.usersettings.change_setting_value("backlight_blue", self.backlight_blue) fastColorWipe(self.ledstrip.strip, True, self)
def load_midi(self, song_path): if song_path in self.is_loaded_midi.keys(): return self.is_loaded_midi.clear() self.is_loaded_midi[song_path] = True self.loading = 1 # 1 = Load.. self.is_started_midi = False # Stop current learning song self.t = threading.currentThread() try: # Load the midi file mid = mido.MidiFile('Songs/' + song_path) # Get tempo and Ticks per beat self.song_tempo = self.get_tempo(mid) self.ticks_per_beat = mid.ticks_per_beat # Assign Tracks to different channels before merging to know the message origin self.loading = 2 # 2 = Proces if len(mid.tracks ) == 2: # check if the midi file has only 2 Tracks offset = 1 else: offset = 0 for k in range(len(mid.tracks)): for msg in mid.tracks[k]: if not msg.is_meta: msg.channel = k + offset if msg.type == 'note_off': msg.velocity = 0 # Merge tracks self.loading = 3 # 3 = Merge self.song_tracks = mido.merge_tracks(mid.tracks) fastColorWipe(self.ledstrip.strip, True, self.ledsettings) self.loading = 4 # 4 = Done except: self.loading = 5 # 5 = Error! self.is_loaded_midi.clear()
def learn_midi(self): # Preliminary checks if self.is_started_midi: return if self.loading == 0: self.menu.render_message("Load song to start", "", 1500) return elif self.loading > 0 and self.loading < 4: self.is_started_midi = True # Prevent restarting the Thread while self.loading > 0 and self.loading < 4: time.sleep(0.1) if self.loading == 4: self.is_started_midi = True # Prevent restarting the Thread elif self.loading == 5: self.is_started_midi = False # Allow restarting the Thread return self.t = threading.currentThread() try: fastColorWipe(self.ledstrip.strip, True, self.ledsettings) time_prev = time.time() notes_to_press = [] start_idx = int(self.start_point * len(self.song_tracks) / 100) end_idx = int(self.end_point * len(self.song_tracks) / 100) for msg in self.song_tracks[start_idx:end_idx]: # Exit thread if learning is stopped if not self.is_started_midi: break # Get time delay tDelay = mido.tick2second( msg.time, self.ticks_per_beat, self.song_tempo * 100 / self.set_tempo) # Check notes to press if not msg.is_meta: if tDelay > 0 and ( msg.type == 'note_on' or msg.type == 'note_off' ) and notes_to_press and self.practice == 0: notes_pressed = [] while not set(notes_to_press).issubset( notes_pressed) and self.is_started_midi: for msg_in in self.midiports.inport.iter_pending(): note = int( find_between(str(msg_in), "note=", " ")) if "note_off" in str(msg_in): velocity = 0 else: velocity = int( find_between(str(msg_in), "velocity=", " ")) if velocity > 0: if note not in notes_pressed: notes_pressed.append(note) else: try: notes_pressed.remove(note) except ValueError: pass # do nothing # Turn off the pressed LEDs fastColorWipe(self.ledstrip.strip, True, self.ledsettings ) # ideally clear only pressed notes! notes_to_press.clear() # Realize time delay, consider also the time lost during computation delay = max( 0, tDelay - (time.time() - time_prev) - 0.003 ) # 0.003 sec calibratable to acount for extra time loss time.sleep(delay) time_prev = time.time() # Light-up LEDs with the notes to press if not msg.is_meta: # Calculate note position on the strip and display if msg.type == 'note_on' or msg.type == 'note_off': note_position = get_note_position( msg.note, self.ledstrip) brightness = msg.velocity / 127 if msg.channel == 1: red = int( self.hand_colorList[self.hand_colorR][0] * brightness) green = int( self.hand_colorList[self.hand_colorR][1] * brightness) blue = int( self.hand_colorList[self.hand_colorR][2] * brightness) if msg.channel == 2: red = int( self.hand_colorList[self.hand_colorL][0] * brightness) green = int( self.hand_colorList[self.hand_colorL][1] * brightness) blue = int( self.hand_colorList[self.hand_colorL][2] * brightness) self.ledstrip.strip.setPixelColor( note_position, Color(green, red, blue)) self.ledstrip.strip.show() # Save notes to press if msg.type == 'note_on' and msg.velocity > 0 and ( msg.channel == self.hands or self.hands == 0): notes_to_press.append(msg.note) # Play selected Track if ((self.hands == 1 and self.mute_hand != 2 and msg.channel == 2) or # send midi sound for Left hand (self.hands == 2 and self.mute_hand != 1 and msg.channel == 1) or # send midi sound for Right hand self.practice == 2): # send midi sound for Listen only self.midiports.playport.send(msg) except Exception as e: self.is_started_midi = False
def load_midi(self, song_path): while self.loading < 4 and self.loading > 0: time.sleep(1) if song_path in self.is_loaded_midi.keys(): return self.is_loaded_midi.clear() self.is_loaded_midi[song_path] = True self.loading = 1 # 1 = Load.. self.is_started_midi = False # Stop current learning song self.t = threading.currentThread() # Load song from cache if self.load_song_from_cache(song_path): return print("Cache not found") try: # Load the midi file mid = mido.MidiFile('Songs/' + song_path) # Get tempo and Ticks per beat self.song_tempo = self.get_tempo(mid) self.ticks_per_beat = mid.ticks_per_beat # Assign Tracks to different channels before merging to know the message origin self.loading = 2 # 2 = Proces if len(mid.tracks ) == 2: # check if the midi file has only 2 Tracks offset = 1 else: offset = 0 for k in range(len(mid.tracks)): for msg in mid.tracks[k]: if not msg.is_meta: msg.channel = k + offset if msg.type == 'note_off': msg.velocity = 0 # Merge tracks self.loading = 3 # 3 = Merge self.song_tracks = mido.merge_tracks(mid.tracks) time_passed = 0 self.notes_time.clear() for msg in mid: if not msg.is_meta: time_passed += msg.time self.notes_time.append(time_passed) fastColorWipe(self.ledstrip.strip, True, self.ledsettings) # Save to cache with open('Songs/cache/' + song_path + '.p', 'wb') as handle: cache = { 'song_tempo': self.song_tempo, 'ticks_per_beat': self.ticks_per_beat, 'notes_time': self.notes_time, 'song_tracks': self.song_tracks, } pickle.dump(cache, handle, protocol=pickle.HIGHEST_PROTOCOL) self.loading = 4 # 4 = Done except Exception as e: print(e) self.loading = 5 # 5 = Error! self.is_loaded_midi.clear()