def generate_chord_progression(mdl, starting_chord, length, max_memory=4, random_neighbors=False): progression = ChordProgression(Chord(starting_chord)) current_chord = starting_chord memory = [] top_k = 10 if max_memory > 0: memory = [current_chord] for i in range(0, length): next_chord = current_chord # print("current_chord: ", current_chord) neighbors = mdl.get_nearest_neighbors(next_chord, top_k) neighbor_chords = [n[1] for n in neighbors] # print("\tneighbors:", neighbor_chords) # choose random neighbor if random_neighbors: processed_neighbors = np.random.choice(neighbor_chords, top_k) else: processed_neighbors = neighbor_chords if len(processed_neighbors): # choose sequential neighbors for neighbor in processed_neighbors: if neighbor != next_chord and neighbor not in memory: next_chord = neighbor memory.append(next_chord) if len(memory) >= max_memory: memory.pop(0) # remove first element # random_neighbors = np.random.choice(neighbor_chords, 1) # print("\trandom_neighbors: ", random_neighbors) # next_chord = random_neighbors[0] current_chord = next_chord if current_chord: chrd = Chord(current_chord) progression.append(chrd) return progression
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 test_append(self): cp = ChordProgression(["C", "D", "E"]) cp.append("F") self.assertEqual(len(cp), 4) self.assertEqual(cp.chords[-1], Chord("F"))