def note2chord(chordlist): chord = [] for i in sorted(chordlist): temp = utils.val_to_note(int(i) % 12) if temp not in chord: chord.append(temp) n = 0 while n < 100: if note_to_chord(chord): return note_to_chord(chord)[0] else: random.shuffle(chord) n = n + 1
def getChords(notes): global cpt global baseChord #print(notes) chord = note_to_chord(notes) # Convert notes to chord if len(chord) == 0: # Si c'est pas un accord return # Pas de changement de couleur chord = str(chord[0]) # Si c'est un accord le passe en String #print(chord) chord = list(chord) # Si c'est un accord le passe en list """ if "/" in chord and chord[-1] != "#" : # Si accord renverse sans # a la fondamentale chord[0] = chord[-1] # La fondamentale reprend leur place elif "/" in chord and chord[-1] == "#": # Si accord renverse avec # a la fondamentale chord[0] = chord[-2] # La fondamentale et son # reprennent leur place chord[1] = chord[-1] """ if len(chord) > 1 and chord[1] == "#": # Si c'est un accord avec un # chord = chord[0] + chord[ 1] # L'accord prend comme nom sa fondamentale et son # else: chord = chord[0] # L'accord prend comme non sa fondamentale if baseChord == "" or baseChord != chord: # Si l'accord n'est pas le meme que l'ancien baseChord = chord # L'accord devient l'accord de reference print(chord) return pickColorChord(chord)
def home(): if request.method == 'GET': """return the information for <user_id>""" return myChord.pitchedCommonName if request.method == 'POST': """modify/update the information for <user_id>""" # you can use <user_id>, which is a str but could # changed to be int or whatever you want, along # with your lxml knowledge to make the required # changes if "c" in request.data: del notasActivas[:] del notasNombre[:] return str(len(notasNombre)) notasActivas.append(request.data) for nota in notasActivas: p = pitch.Pitch(nota) p = p.name if p in notasNombre: test = 1 else: notasNombre.append(p) str1 = ' '.join(notasNombre) for notas in notasNombre: print(notas) if str(note_to_chord(notasNombre)) == "[]": test = chord.Chord(notasNombre) return test.pitchedCommonName else: myChord = note_to_chord(notasNombre) print(str(myChord)) return str(myChord)
def bin_to_chord(bit_arr): notes = NOTE_INTS_ARR[bit_arr > 0] note_names = [INT_TO_NOTE[n] for n in notes] try: chrd = note_to_chord(note_names) except: return [] return chrd
def get(self): midi_chord = request.args.getlist('notes')[0].split(',') pychord_chord = note_to_chord( [note_to_name(int(i)) for i in midi_chord]) result_dict = {("chord_" + str(i)): str(pychord_chord[i]) for i in range(len(pychord_chord))} return jsonify(result_dict)
def to_chord(self): if not self.chord: note_names = self.to_note_names() chords = note_to_chord(note_names) print(chords) if len(chords): self.chord = chords[0] else: self.chord = None return self.chord
def get_chords(mode, key, seventh=False, ninth=False): retval = [] # PRINT THE CHORDS for i in range(7): chord = [] chord.append(get_note_name(get_note_by_index(mode, i), key)) chord.append(get_note_name(get_note_by_index(mode, i + 2), key)) chord.append(get_note_name(get_note_by_index(mode, i + 4), key)) # settima if seventh: chord.append(get_note_name(get_note_by_index(mode, i + 6), key)) # nona if ninth: chord.append(get_note_name(get_note_by_index(mode, i + 1), key)) retval.append(note_to_chord(chord)) return retval
def get_chord_progression_from_file(f_name, debug=False): """ Takes a file name returns a chord progression :return ChordProgression """ if debug: print("processing: {}".format(f_name)) mlt = Multitrack() try: mlt.parse_midi(filename=f_name, binarized=True) merged_mlt = mlt.get_merged_pianoroll(mode='max') except: print("unable to parse. skipping: {}".format(f_name)) return ChordProgression() # empty progression chord_progression = ChordProgression([]) last_chord_change = 0 for i, x in enumerate(merged_mlt): # print(x) notes = np.where(x) num_notes = np.sum(x) if num_notes: if num_notes > 1: chord_notes = INT_TO_NOTE[notes[0] % 12] chord_name = note_to_chord(chord_notes.tolist()) if chord_name: chord = chord_name[0] if len(chord_progression.chords ) == 0 or chord_progression.chords[-1] != chord: # print("chord: ", notes[0], chord_notes, chord_name) chord_progression.append(chord) # else: # print("note: ", notes[0]) # print(chord_progression) return chord_progression
def getChords(notes): if len(notes) > 1: # If two notes or more know the chord if len(note_to_chord(notes)) != 0: return pickColorChord(str(note_to_chord(notes)[0]))
def record_midi_menu(WIN): # the velocity with which the notes move up note_vel = 2 # list of currently pressed notes, used for drawing notes = [] # list of currently pressed notes, used for chords notes_pressed = [] # particles list particles = [] pianoKeyboard = PianoKeyboard() pianoKeyboard.init() # clear input buffer midis2events.midis2events(MIDI_INPUT.read(40), MIDI_INPUT).clear() # start time of the function start = t.perf_counter() click = False mf = None track = None channel = None running = True recording = False entering_text = False while running: # fill background color and draw keyboard over it WIN.fill(TAN) pianoKeyboard.draw(WIN, notes_pressed) # draw notes for note in notes: if note.is_pressed: note.incrementHeight(note_vel) note.drawNote(WIN) # generate particles COLOR = None if note.is_white: if note.number < 60: COLOR = COLOR1 else: COLOR = COLOR3 else: if note.number < 60: COLOR = COLOR1 else: COLOR = COLOR3 p = Particle([ pianoKeyboard.keys[note.number].x + 6, HEIGHT - WHITE_NOTE_HEIGHT ], random.randint(1, 5), [ random.randint(0, 20) / 10 - 1, random.randint(0, 20) / 10 - 2 ], 6, RED) particles.append(p) else: note.moveNoteUp(note_vel) note.drawNote(WIN) if note.rect.y + note.rect.h + 100 < 0: notes.remove(note) # remove expired particles for particle in particles: if particle.radius <= 0: particles.remove(particle) # draw top bar pygame.draw.rect(WIN, WHITE, (0, 0, WIDTH, HEIGHT // 17)) pygame.draw.rect(WIN, BLACK, (0, HEIGHT // 17, WIDTH, 2)) # draw text on bar draw_text(WIN, "Record MIDI", 25, WIDTH // 2, HEIGHT // 17 // 2, BLACK, True, True) back_button = draw_button('Main Menu', FONT_NAME, 25, BLACK, WIN, WIDTH - 5, HEIGHT // 17) if not recording: draw_text(WIN, "Press P to start recording", 20, WIDTH - 5, HEIGHT // 17 * 1.5, BLACK, True, False, True) else: draw_text(WIN, "Press P to stop recording", 20, WIDTH - 5, HEIGHT // 17 * 1.5, BLACK, True, False, True) # draw currently pressed chord name on screen if len(notes_pressed) > 0: notes_pressed_char = [] for note in notes_pressed: notes_pressed_char.append(number_to_note(note)) notes_pressed_char.sort() if len(notes_pressed_char) == 1: draw_text(WIN, notes_pressed_char[0], 25, 5, HEIGHT // 17 // 2, BLACK, True, False) elif len(notes_pressed_char) == 2 and abs(notes_pressed[0] - notes_pressed[1]) == 12: draw_text(WIN, notes_pressed_char[0] + " with perfect octave", 25, 5, HEIGHT // 17 // 2, BLACK, True, False) elif note_to_chord(notes_pressed_char): # REGEX chords = re.findall(r'<Chord: ([^>]*)', str(note_to_chord(notes_pressed_char))) text = ", ".join(chords) draw_text(WIN, "Chord: " + text, 25, 5, HEIGHT // 17 // 2, BLACK, True, False) # draw particles for particle in particles: particle.position[0] += particle.velocity[0] particle.position[1] += particle.velocity[1] particle.radius -= 0.1 pygame.draw.circle(WIN, particle.color, particle.position, particle.radius) if particle.radius <= 0: particles.remove(particle) # check for midi events from the input port for event in midis2events.midis2events(MIDI_INPUT.read(40), MIDI_INPUT): # for some reason, all events are NOTE_ON events # a NOTE_ON event with velocity 0 represents a NOTE_OFF event if event.command == midis2events.NOTE_ON: # extract data from event note_number = event.data1 velocity = event.data2 if velocity != 0: # note on print(f"ON %s %s %s" % (event.data1, velocity, t.perf_counter() - start)) if pianoKeyboard.keys[note_number].is_white: WHITE_NOTE_RECT = pygame.Rect( (pianoKeyboard.keys[note_number].x + 6, HEIGHT - WHITE_NOTE_HEIGHT), (WIDTH // NR_WHITE_NOTES - 3, 0)) note = Note(number=note_number, velocity=velocity, start_time=t.perf_counter() - start, rect=WHITE_NOTE_RECT, is_pressed=True, is_white=True) else: BLACK_NOTE_RECT = pygame.Rect( (pianoKeyboard.keys[note_number].x + 3, HEIGHT - WHITE_NOTE_HEIGHT), (WIDTH // 100 - 3, 0)) note = Note(number=note_number, velocity=velocity, start_time=t.perf_counter() - start, rect=BLACK_NOTE_RECT, is_pressed=True, is_white=False) # add note to notes list notes.append(note) # add note number to currently pressed notes list notes_pressed.append(note_number) else: # note off # search for note in notes list and set note.is_pressed to False for note in notes: if note.number == note_number and note.is_pressed: note.is_pressed = False # write note to MIDI file try: if recording: mf.addNote( track, channel, note_number, note.start_time, t.perf_counter() - start - note.start_time, note.velocity) except: print( "Something went wrong with writing the MIDI file." ) # remove note from notes_pressed list notes_pressed.remove(note_number) print("turn off note %s with start time %s" % (note.number, note.start_time)) print(f"OFF %s %s %s" % (event.data1, event.data2, t.perf_counter() - start)) # elif event.command == midis2events.NOTE_OFF: click = False for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False if event.key == pygame.K_p and recording == False: recording = True # create MIDI object mf = MIDIFile(1) # only 1 track track = 0 # the only track mf.addTrackName(track, 0, "Sample Track") mf.addTempo(track, 0, 60) channel = 0 start = t.perf_counter() elif event.key == pygame.K_p and recording == True: recording = False filename = enter_text(WIN) if filename != "": with open(filename + ".mid", 'wb') as outf: mf.writeFile(outf) if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: click = True mx, my = pygame.mouse.get_pos() if back_button.collidepoint((mx, my)) and click: running = False pygame.display.update() CLOCK.tick(FPS)
from pychord import Chord, note_to_chord chrd1 = Chord("Am7") chrd2 = Chord("C") print(chrd1) print(chrd2) print(note_to_chord(["C", "E", "G"]))
i = pygame.midi.Input(input_id) print("input MIDI:%d" % input_id) print("starting") going = True pre_status = 156 inputs = [] while going: if i.poll(): midi_events = i.read( 10 ) # midi_events = [[[status,note,velocity,channel],timestamp],...] if (midi_events[0][0][1] == 96): # C7 押下で終了 going = False elif (midi_events[0][0][0] == 156): # 鍵盤を押下したとき inputs.append(midi_events[0][0][1]) elif (midi_events[0][0][0] == 140): # 鍵盤を離したとき if (pre_status == 156): # 鍵盤を押下していたとき inputs.sort() notes = convert(inputs) notes_list = sorted(set(notes), key=notes.index) print(notes_list, note_to_chord(notes_list)) inputs = [] pre_status = midi_events[0][0][0] # 前の status を保存する i.close() pygame.midi.quit() pygame.quit() exit()
def test_find_from_components(self): self.quality_manager.set_quality("13", (0, 4, 7, 10, 14, 17, 21)) chords = note_to_chord(['C', 'E', 'G', 'Bb', 'D', 'F', 'A']) self.assertEqual(chords, [Chord("C13")])
from pychord import Chord import pychord chord_am7 = Chord("Am7") chord_am7_info = chord_am7.info() chord_am7_comp = chord_am7.components() bbb = pychord.note_to_chord(["C", "E", "G"]) print(chord_am7_info)
def serve(model_path=MODEL_OUT_PATH, in_port_name=None, out_port_name=None): if not model_path: print("FastText model is required!") if not in_port_name: print("MIDI input port name is required!") if not out_port_name: print("MIDI output port name is required!") mdl = load_mdl(model_path) INPUT_DEVICE_NAME = in_port_name OUTPUT_DEVICE_NAME = out_port_name print('MIDI ports: in: {}, out: {}'.format(INPUT_DEVICE_NAME, OUTPUT_DEVICE_NAME)) port = mido.open_output(OUTPUT_DEVICE_NAME) inport = mido.open_input(INPUT_DEVICE_NAME) current_ai_notes = set() current_human_played_notes = set() current_human_played_note = None current_human_vel = 0 last_human_played_note = None while True: r_msg = inport.receive() if r_msg.type in ['note_on', 'note_off']: note_num = INT_TO_NOTE[r_msg.note % 12] if r_msg.type == 'note_on': current_human_played_notes.add(r_msg.note) last_human_played_note = current_human_played_note current_human_played_note = r_msg.note current_human_vel = r_msg.velocity else: if r_msg.note in current_human_played_notes: stop_one_note(port, r_msg.note) current_human_played_notes.remove(r_msg.note) current_human_played_note = None current_human_vel = 0 # print(current_human_played_notes) # print(current_human_played_note, "vel: ", current_human_vel) if not current_human_played_notes: stop_all_ai_notes(port, list(current_ai_notes)) current_ai_notes = set() elif current_human_played_note and current_human_played_note != last_human_played_note: chrd_notes = [current_human_played_note] human_octave = int(max(current_human_played_notes) / 12) if len(current_human_played_notes) == 1: # chrd = Chord(chrd_notes[0]) chrd_str = INT_TO_NOTE[chrd_notes[0] % 12] human_notes_names = [chrd_str] else: human_notes = list(current_human_played_notes) human_notes_names = [INT_TO_NOTE[n % 12] for n in human_notes] chrd = note_to_chord(human_notes_names) if not chrd: chrd_str = '' else: chrd_str = str(chrd[0]) if not chrd_str or chrd_str == '</s>': continue try: next_chord = get_next_chord(mdl, chrd_str, random_neighbors=True, hypercube=False) if not next_chord: continue print("notes: {}, chord_suggestion: {}".format( human_notes_names, next_chord)) next_chord_notes = generate_notes_from_chord( next_chord, human_octave) # stop any pending AI notes stop_all_notes(port) current_ai_notes = set() # start new AI notes start_all_ai_notes(port, next_chord_notes, current_human_vel) for note in next_chord_notes: current_ai_notes.add(note) except: print("error parsing chrd_str: '{}'".format(chrd_str))
bestfreqs = freq[sortorder[-10:]] freq1 = bestfreqs[-1] freq2 = bestfreqs[-2] freq3 = bestfreqs[-3] freq4 = bestfreqs[-4] note1, octave1 = findnote(freq1, df) note2, octave2 = findnote(freq2, df) note3, octave3 = findnote(freq3, df) note4, octave4 = findnote(freq4, df) freqs = [freq1, freq2, freq3, freq4] octaves = np.asarray([octave1, octave2, octave3, octave4]) notes = np.asarray([note1, note2, note3, note4]) sortfreq = np.argsort(freqs) sortednotes = list(notes[sortfreq]) sortedoctaves = list(octaves[sortfreq]) #now need to find the root note. start by finding lowest frequency. finalnotes = list(dict.fromkeys(sortednotes)) print('this chord consists of the notes: ' + sortednotes[0] + sortedoctaves[0] + ' ' + sortednotes[1] + sortedoctaves[1] + ' ' + sortednotes[2] + sortedoctaves[2] + ' ' + sortednotes[3] + sortedoctaves[3]) print('The chord is ' + str(note_to_chord(finalnotes)))
def analyze_chunk(interval, fs, data_parts, duration, T1): # rekurzivna funkcija global current_time, k, data_chunk # current time, current position in data_parts array , data chunk to be analyzed global start, end # starting and ending position of chunk to be analyzed global once # switch global chord_prog, durations # list to store chords that are found and list to store durations #T2 = time.time() #if ((T2 - T1) > 60): #return "Failed" if (current_time >= duration or k == len(data_parts)): # basic if return "Done" if (once): # running once, to make starting interval end = start + interval once = False chunk = end - start # deo u sekundi n_intervals = round(chunk / interval) if (n_intervals > 1): for i in range(0, n_intervals): if (k != len(data_parts)): data_chunk = np.append(data_chunk, data_parts[k]) k = k + 1 else: print("Nothing found beetwen {0} and {1}".format( round(start, 1), round(end, 1))) chord_prog.append("None") durations.append(round(chunk, 1) - interval) return "Done" else: data_chunk = data_parts[k] k = k + 1 fft_and_freq = do_fft( fs, data_chunk ) # kreiranje matrice sa fft vrednostima i odgovarajucim frekvencijama notes = find_all_notes( fft_and_freq[0], fft_and_freq[1] ) # trazenje svih nota, sortiranih od one koja se cuje najvise triad_notes = [] l = 0 for note in notes: if (note != "None" and l < 3): triad_notes.append(note) l = l + 1 triad = reference_sort( triad_notes ) # pravljenje trikorda od 3 najjaca tona, sortirana po hromatskoj skali chord_list = note_to_chord( triad ) # odredjivanje koji to akord, s tim da note_to_chord funkcija vraca listu (len(a) = 0 akko nije nasao akord) if (len(chord_list) != 0): # ako nadje akord chord = chord_list[0].chord print("Chord {0} found between {1} - {2}".format( chord, round(start, 1), round(end, 1))) #print("Notes found are ", triad) if ("/" in chord): # sklanjanje "/" slash_id = chord.find("/") chord = chord[0:slash_id] else: pass current_time = current_time + chunk chord_prog.append(chord) durations.append(round(chunk, 1)) data_chunk = [] # emptying data chunk to analyzed start = end # moving start point to end end = end + interval # moving end point by 1 interval # increasing analyzed_time by analyzed time analyze_chunk(interval, fs, data_parts, duration, T1) else: data_chunk = [] # emptying data chunk to analyzed end = end + interval # moving end point by 1 interval #print("Nothing found, increasing interval to {0}".format(round(end - start, 1))) k = k - n_intervals analyze_chunk(interval, fs, data_parts, duration, T1)
def find_chord_progression(interval, fs, data, is_stereo=True): duration = len(data) / fs # duzina uzorka (s) n_parts = round(duration / interval) # broj delova data_parts = np.array_split(data, n_parts) # seckanje j = 0 start_time = 0 end_time = interval for i in range(0, n_parts): fft_and_freq = do_fft( fs, data_parts[i], is_stereo ) # kreiranje matrice sa fft vrednostima i odgovarajucim frekvencijama notes = find_all_notes( fft_and_freq[0], fft_and_freq[1] ) # trazenje svih nota, sortiranih od one koja se cuje najvise triad = reference_sort( [notes[0], notes[1], notes[2]], chrom_scale ) # pravljenje trikorda od 3 najjaca tona, sortirana po hromatskoj skali chord_list = note_to_chord( triad ) # odredjivanje koji to akord, s tim da note_to_chord funkcija vraca listu # ako su random note i funkcija ne moze da nadje akord, crashuje try: chord = chord_list[0].chord except: chord = "None" # ispisivanje tonova # print("Notes found: ", reference_sort(notes[0:3], chrom_scale)) # zbog mogucih inverzija na klaviru pojavljuju se akordi poput # C/G sto ustvari jesu tonovi C,E,G mada je G bas if ("/" in chord): slash_id = chord.find("/") chord = chord[0:slash_id] print(chord[0:slash_id], " ", start_time, " - ", end_time, "s") else: print(chord, " ", start_time, " - ", end_time, "s") # deo koji racuna trajanje svakog akorda if (i == 0): durations.append(0.0) durations[j] = durations[j] + interval chord_prog.append(chord) prev_chord = chord # print("Added 0.2s to chord: ", prev_chord, "\n") if (i != 0): if (prev_chord == chord): durations[j] = durations[j] + interval # print("Same as the last one, added 0.2s to chord: ", prev_chord, "\n") else: prev_chord = chord chord_prog.append(chord) # print("Chord changed to: ", prev_chord) j = j + 1 durations.append(0.0) durations[j] = durations[j] + interval # print("Added 0.2s to chord: ", prev_chord, "\n") start_time = round(start_time + interval, 1) end_time = round(end_time + interval, 1) if (i == n_parts - 1): k = 0 for el in durations: durations[k] = round(durations[k], 1) k = k + 1
def freeplay_menu(WIN): # the velocity with which the notes move up note_vel = 2 # list of currently pressed notes, used for drawing chords to screen notes = [] # list of currently pressed notes, used for chords notes_pressed = [] # particles list particles = [] pianoKeyboard = PianoKeyboard() pianoKeyboard.init() # clear input buffer midis2events.midis2events(MIDI_INPUT.read(40), MIDI_INPUT).clear() # start time of the function start = t.perf_counter() click = False running = True while running: # fill background color and draw keyboard over it WIN.fill(TAN) pianoKeyboard.draw(WIN, notes_pressed) # draw notes for note in notes: if note.is_pressed: note.incrementHeight(note_vel) note.drawNote(WIN) # generate particles COLOR = RED p = Particle([pianoKeyboard.keys[note.number].x + 6, HEIGHT - WHITE_NOTE_HEIGHT], random.randint(1, 5), [random.randint(0, 20) / 10 - 1, random.randint(0, 20) / 10 - 2], 6, COLOR) particles.append(p) else: note.moveNoteUp(note_vel) note.drawNote(WIN) if note.rect.y + note.rect.h + 100 < 0: notes.remove(note) # remove expired particles for particle in particles: if particle.radius <= 0: particles.remove(particle) # draw top bar pygame.draw.rect(WIN, WHITE, (0, 0, WIDTH, HEIGHT // 17)) pygame.draw.rect(WIN, BLACK, (0, HEIGHT // 17, WIDTH, 2)) # draw text on bar draw_text(WIN, "Free Play", 25, WIDTH // 2, HEIGHT // 17 // 2, BLACK, True, True) back_button = draw_button('Main Menu', FONT_NAME, 25, BLACK, WIN, WIDTH - 5, HEIGHT // 17) # draw currently pressed chord name on screen if len(notes_pressed) > 0: notes_pressed_char = [] for note in notes_pressed: notes_pressed_char.append(number_to_note(note)) notes_pressed_char.sort() if len(notes_pressed_char) == 1: draw_text(WIN, notes_pressed_char[0], 25, 5, HEIGHT // 17 // 2, BLACK, True, False) elif len(notes_pressed_char) == 2 and abs(notes_pressed[0] - notes_pressed[1]) == 12: draw_text(WIN, notes_pressed_char[0] + " with perfect octave", 25, 5, HEIGHT // 17 // 2, BLACK, True, False) else: notes_pressed_char = remove_duplicates(notes_pressed_char) if note_to_chord(notes_pressed_char): # REGEX chords = re.findall(r'<Chord: ([^>]*)', str(note_to_chord(notes_pressed_char))) text = ", ".join(chords) draw_text(WIN, "Chord: " + text, 25, 5, HEIGHT // 17 // 2, BLACK, True, False) print(remove_duplicates(["a", "b", "a", "c", "c"])) # draw particles for particle in particles: particle.position[0] += particle.velocity[0] particle.position[1] += particle.velocity[1] particle.radius -= 0.1 pygame.draw.circle(WIN, particle.color, particle.position, particle.radius) if particle.radius <= 0: particles.remove(particle) # check for midi events from the input port for event in midis2events.midis2events(MIDI_INPUT.read(40), MIDI_INPUT): # for some reason, all events are NOTE_ON events # a NOTE_ON event with velocity 0 represents a NOTE_OFF event if event.command == midis2events.NOTE_ON: # extract data from event note_number = event.data1 velocity = event.data2 if velocity != 0: # note on print(f"ON %s %s %s" % (event.data1, velocity, t.perf_counter() - start)) if pianoKeyboard.keys[note_number].is_white: WHITE_NOTE_RECT = pygame.Rect((pianoKeyboard.keys[note_number].x + 6, HEIGHT - WHITE_NOTE_HEIGHT), (WIDTH // NR_WHITE_NOTES - 3, 0)) note = Note(number=note_number, velocity=velocity, start_time=t.perf_counter() - start, rect=WHITE_NOTE_RECT, is_pressed=True, is_white=True) else: BLACK_NOTE_RECT = pygame.Rect((pianoKeyboard.keys[note_number].x + 3, HEIGHT - WHITE_NOTE_HEIGHT), (WIDTH // 100 - 3, 0)) note = Note(number=note_number, velocity=velocity, start_time=t.perf_counter() - start, rect=BLACK_NOTE_RECT, is_pressed=True, is_white=False) # add note to notes list notes.append(note) # add note number to currently pressed notes list notes_pressed.append(note_number) else: # note off # search for note in notes vector and set is_pressed to False for note in notes: if note.number == note_number and note.is_pressed: note.is_pressed = False # remove note from notes_pressed list notes_pressed.remove(note_number) print(f"OFF %s %s %s" % (event.data1, event.data2, t.perf_counter() - start)) # elif event.command == midis2events.NOTE_OFF: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: click = True mx, my = pygame.mouse.get_pos() if back_button.collidepoint((mx, my)) and click: running = False pygame.display.update() CLOCK.tick(FPS)