def test_determine(self): self.assertEqual(['C ionian'], scales.determine([ 'C', 'D', 'E', 'F', 'G', 'A', 'B', ])) self.assertEqual(['C aeolian', 'C natural minor'], scales.determine(scales.natural_minor('C')))
def determine_note_scale(note): """Determine to which scale this note can belong. For minor scales, the seventh degree only has two notes""" result = [] for s in scales.determine([note]): if "harmonic minor" in s or "natural minor" in s: result.append(s.split()[0].lower()) elif "major" in s and "harmonic" not in s: result.append(s.split()[0]) return set(result)
def scale_practice(): minutes_to_practice = pyip.inputInt( prompt="How many minutes do you want to practice? ", min=1) seconds_between = pyip.inputFloat( prompt="How many rest seconds you want between scales? ", min=1) start_time = time() while (True): chosen_scale = choice(scales_content['scales'])['scale'] determined_scale = scales.determine(chosen_scale) if determined_scale: print(f"\t{chosen_scale} - {determined_scale[0]}") else: print(f"\t{chosen_scale}") sleep(seconds_between) if (time() - start_time) >= minutes_to_practice * 60: break
def generate_melody(with_chords, repetitions=1): use_custom_scale = pyip.inputYesNo( prompt="Do you want to use a custom scale? (y/n) ") possible_chords = [] if use_custom_scale == "yes": scale_input = input( """Insert the notes from the scale separated by a space, do not use flats, only sharps. \t\tExample: C D E F# A\n""") chosen_scale = scale_input.upper().split() for x in range(len(chosen_scale) + 1): combinations_object = combinations(chosen_scale, x) combinations_list = list(combinations_object) possible_chords += combinations_list for _ in range(len(chosen_scale) + 1): del possible_chords[0] get_random_scale = False use_custom_scale = True else: get_random_scale = True use_custom_scale = False try: determined_scale = scales.determine(chosen_scale)[0] except: determined_scale = "" amount_of_notes = pyip.inputInt( prompt="How many notes do you want for this melody? ", min=1) if with_chords: chords_each_x = pyip.inputInt( prompt="How many notes you want between chords? ", min=1) chord_in_note = [x for x in range(0, amount_of_notes, chords_each_x)] for _ in range(repetitions): melody_name = generate_random_name() melody_path = f"Melodies/{melody_name}" os.mkdir(melody_path) track = 0 channel = 0 time = 0 duration = 1 tempo = 120 volume = 100 midi_melody = MIDIFile(1) midi_melody.addTempo(track, time, tempo) if get_random_scale: chosen_scale = choice(scales_content["scales"]) possible_chords = chosen_scale["chords"] chosen_scale = chosen_scale["scale"] ly_string = r'''\version "2.20.0" \header{title = "PLACEHOLDER_NAME" subtitle = "PLACEHOLDER_SUBTITLE" tagline = ##f} \score { { ''' ly_string = ly_string.replace("PLACEHOLDER_NAME", melody_name) ly_string = ly_string.replace( "PLACEHOLDER_SUBTITLE", f"{str(chosen_scale)} - {determined_scale}") print( f"\nGenerating melody with scale: {chosen_scale} - {determined_scale}\n" ) print(f"\t****{melody_name}****") all_parts = [] for i in range(amount_of_notes): if with_chords: if i in chord_in_note: if i != 0: time += duration chosen_chord = choice(possible_chords) chosen_chord = chosen_chord[:3] try: determined_chord = chords.determine( list(chosen_chord))[0] except: determined_chord = "" ly_string += "\n< " for note in chosen_chord: ly_string += f"{note_to_ly(note)}' " note_midi_value = int(Note(note)) + 12 midi_melody.addNote(track, channel, note_midi_value, time, duration, volume) ly_string += ">\n\n" all_parts.append( f"\n\t{chosen_chord} - {determined_chord}\n") chosen_note = choice(chosen_scale) ly_string += f"{note_to_ly(chosen_note)}4' " note_midi_value = int(Note(chosen_note)) + 12 midi_melody.addNote(track, channel, note_midi_value, time + duration, duration, volume) time += duration all_parts.append(f"\t{chosen_note}") ly_string += """} \layout { } \midi { } }""" with open(f"{melody_path}/{melody_name}.txt", "w") as f: for part in all_parts: f.write(f"{part}\n") print(part) with open(f"{melody_path}/{melody_name}_pond.ly", "w") as f: f.write(ly_string) with open(f"{melody_path}/{melody_name}.mid", "wb") as f: midi_melody.writeFile(f)
def test_determine(self): self.assertEqual(["C ionian"], scales.determine(["C", "D", "E", "F", "G", "A", "B"])) self.assertEqual(["C aeolian", "C natural minor"], scales.determine(scales.natural_minor("C")))
def main(hMidi, file): c2 = MidiFileIn.MIDI_to_Composition(file) out_dir = 'out' tra = Track() notes = list() bars = [] for x in c2: if (x.__class__.__name__ == "Composition"): for track in x.tracks: i = 0 for bar in track.bars: notesB = [] if len(bar.get_note_names()) == 0: bar.empty() bar.place_rest(1) tra + bar notesB.append(None) bars.append(notesB) i = i + 1 continue tra + bar for y in bar: if (len(NoteContainer(y[-1]).get_note_names()) > 0): notes.append( NoteContainer(y[-1]).get_note_names()[0]) notesB.append((y[2][0].name, y[2][0].octave)) bars.append(notesB) i = i + 1 bars = bars[:-1] tra.bars = tra.bars[:-1] bpm = c2[1] ### DESCOBRIR TONALIDADE MELODIA -> 1o GRAU ### key_and_mode = scales.determine(notes)[0] if key_and_mode != None: key = key_and_mode.split(" ")[0] mode = key_and_mode.split(" ")[1] score = converter.parse(file) parse = score.analyze('key') keym = parse.tonic.name modem = parse.mode flag = False if mode == ('harmonic' or 'minor'): key = keys.relative_major(key.lower()) mode = 'major' flag = True elif mode != modem: Flag = True scores = { 'I': { 0: 0.5, 1: -0.2, 2: 0, 3: 0, 4: 0.35, 5: 0, 6: 0, 7: 0.35, 8: 0, 9: 0, 10: 0, 11: 0.1 }, 'ii': { 0: 0, 1: 0.1, 2: 0.5, 3: -0.2, 4: 0, 5: 0, 6: 0.35, 7: 0, 8: 0, 9: 0.35, 10: 0, 11: 0 }, 'iii': { 0: 0, 1: 0, 2: 0, 3: 0.1, 4: 0.5, 5: -0.2, 6: 0, 7: 0, 8: 0.35, 9: 0, 10: 0, 11: 0.35 }, 'IV': { 0: 0.35, 1: 0, 2: 0, 3: 0, 4: 0.1, 5: 0.5, 6: -0.2, 7: 0, 8: 0, 9: 0.35, 10: 0, 11: 0 }, 'V': { 0: 0, 1: 0, 2: 0.35, 3: 0, 4: 0, 5: 0, 6: 0.1, 7: 0.5, 8: -0.2, 9: 0, 10: 0, 11: 0.35 }, 'vi': { 0: 0, 1: 0.35, 2: 0, 3: 0, 4: 0.35, 5: 0, 6: 0, 7: 0, 8: 0.1, 9: 0.5, 10: -0.2, 11: 0 }, 'vii': { 0: -0.2, 1: 0, 2: 0, 3: 0.35, 4: 0, 5: 0, 6: 0.35, 7: 0, 8: 0, 9: 0, 10: 0.11, 11: 0.5 } } scoresMin = { 'I': { 0: 0, 1: 0.35, 2: 0, 3: 0, 4: 0.35, 5: 0, 6: 0, 7: 0, 8: 0.1, 9: 0.5, 10: -0.2, 11: 0 }, 'ii': { 0: -0.2, 1: 0, 2: 0, 3: 0.35, 4: 0, 5: 0, 6: 0.35, 7: 0, 8: 0, 9: 0, 10: 0.11, 11: 0.5 }, 'iii': { 0: 0.5, 1: -0.2, 2: 0, 3: 0, 4: 0.35, 5: 0, 6: 0, 7: 0.35, 8: 0, 9: 0, 10: 0, 11: 0.1 }, 'IV': { 0: 0, 1: 0.1, 2: 0.5, 3: -0.2, 4: 0, 5: 0, 6: 0.35, 7: 0, 8: 0, 9: 0.35, 10: 0, 11: 0 }, 'V': { 0: 0, 1: 0, 2: 0, 3: 0.1, 4: 0.5, 5: -0.2, 6: 0, 7: 0, 8: 0.35, 9: 0, 10: 0, 11: 0.35 }, 'vi': { 0: 0.35, 1: 0, 2: 0, 3: 0, 4: 0.1, 5: 0.5, 6: -0.2, 7: 0, 8: 0, 9: 0.35, 10: 0, 11: 0 }, 'vii': { 0: 0, 1: 0, 2: 0.35, 3: 0, 4: 0, 5: 0, 6: 0.1, 7: 0.5, 8: -0.2, 9: 0, 10: 0, 11: 0.35 } } if flag: scores = scoresMin modeToPass = '******' if flag else 'major' chords = Harmonizer.harmonize(bars, key, scores, (4, 4), modeToPass) label1 = Label(hMidi.root, text='Harmonizando!') label1.config(font=('helvetica', 14)) hMidi.canvas1.create_window(200, 100, window=label1) pg = Progressbar(hMidi.root, orient=HORIZONTAL, length=100, mode='determinate') pg['maximum'] = 230 pg['value'] = 0 hMidi.pg = pg hMidi.canvas1.create_window(200, 140, window=pg) hMidi.updt('') label4 = Label(hMidi.root, textvariable=hMidi.labelText) hMidi.canvas1.create_window(200, 160, window=label4) hMidi.update(0) fluidsynth.init("Sounds/soundfont.sf2", "alsa") button1 = Button( text='Ouvir resultado', command=lambda: hMidi.play(tra, chords, bpm, scores, bars, key, mode, modeToPass, tra, file, out_dir), bg='brown', fg='white', font=('helvetica', 9, 'bold')) hMidi.canvas1.create_window(200, 200, window=button1) if hMidi.exp: if not os.path.exists(out_dir): os.makedirs(out_dir) Harmonizer.export(tra, progressions.to_chords(chords, key), key, (4, 4), bpm, file) if hMidi.sheet: if not os.path.exists(out_dir): os.makedirs(out_dir) Harmonizer.to_Sheet(bars, progressions.to_chords(chords, key), tra, key, mode, file, out_dir, hMidi.name, hMidi.author)