예제 #1
0
 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)
예제 #2
0
    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
예제 #3
0
    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)
예제 #4
0
    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()
예제 #5
0
    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
예제 #6
0
    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()