def resolve_chord_tone(chord, tone, Ioctave): # play_progression([numeral], st.KEY, Ioctave=Ioctave) if st.ALTERNATIVE_CHORD_TONE_RESOLUTION == 1: fluidsynth.play_NoteContainer(chord) play_wait() fluidsynth.play_Note(tone) play_wait() root = chord[0] interval = NoteContainer([root, tone]) fluidsynth.play_NoteContainer(interval) elif st.ALTERNATIVE_CHORD_TONE_RESOLUTION == 2: fluidsynth.play_NoteContainer(chord) play_wait() tone_idx = [x for x in chord].index(tone) if tone_idx == 0: arpeggiate() elif tone_idx == 1: arpeggiate(invert=[1, 0, 2]) elif tone_idx == 2: arpeggiate(descending=True) else: raise Exception("This chord tone resolutions mode is only " "implemented for triads.") # fluidsynth.play_Note(Iup_note) # Iup_note = Note(st.KEY) # Iup_note.octave += 1 # fluidsynth.play_Note(Iup_note) else: fluidsynth.play_NoteContainer(chord) play_wait() fluidsynth.play_Note(tone) play_wait() arpeggiate() # sets NEWQUESTION = False
def arpeggiate(invert=False, descending=False, chord=None, bpm=None, durations=None): if not bpm: bpm = st.BPM # if not delay: # delay = st.DELAY/2 if chord: pass elif st.CURRENT_MODE.name in ['single_chord', 'chord_tone']: chord = st.CURRENT_Q_INFO["chord"] elif st.CURRENT_MODE.name in ['interval']: chord = st.CURRENT_Q_INFO["interval"] else: print("Arpeggiation not available in {} mode.".format(st.CURRENT_MODE)) return arpeggiation = [x for x in chord] if invert: arpeggiation = [arpeggiation[i] for i in invert] elif descending: arpeggiation.reverse() # Play easy_play(arpeggiation, durations, bpm) play_wait() # play wait
def eval_progression(ans, prog, prog_strums): try: int(ans) answers = [x for x in ans] except: answers = ans.split(" ") answers_correct = [] for i, answer in enumerate(answers): try: correct_numeral = prog[i] tmp = progressions.to_chords([correct_numeral], st.KEY)[0] root = NoteContainer(tmp)[0].name user_correct = eval_single_chord(answer, correct_numeral, root) print(user_correct) answers_correct.append(user_correct) except IndexError: print("too many answers") if len(answers) < len(prog): print("too few answers") print("Progression:", " ".join(prog_strums)) print("Your answer: ", " ".join(answers)) print("Correct Answer:", " ".join([str(st.NUMERALS.index(x) + 1) for x in prog])) if all(answers_correct): st.SCORE += 1 print("Good Job!") print() else: print("It's ok, you'll get 'em next time.") print() # time.sleep(st.DELAY) play_wait()
def new_question_single_chord(): # Choose new chord+octave/Progression # Single chord mode if st.NEWQUESTION: if st.COUNT: print("score: {} / {} = {:.2%}".format(st.SCORE, st.COUNT, st.SCORE / st.COUNT)) st.COUNT += 1 # Pick random chord/octave numeral, chord, Ioctave = random_chord() # store question info st.CURRENT_Q_INFO = { 'numeral': numeral, 'chord': chord, 'Ioctave': Ioctave } else: numeral = st.CURRENT_Q_INFO['numeral'] chord = st.CURRENT_Q_INFO['chord'] Ioctave = st.CURRENT_Q_INFO['Ioctave'] # Play chord play_progression([numeral], st.KEY, Ioctave=Ioctave) # Request user's answer ans = getch("Enter 1-7 or root of chord: ").strip() if ans in menu_commands: menu_commands[ans].action() else: if isvalidnote(ans): if eval_single_chord(ans, numeral, chord[0].name): st.SCORE += 1 print("Yes!", chordname(chord, numeral)) if st.RESOLVE_WHEN_CORRECT: resolve_with_chords(numeral, key=st.KEY, Ioctave=Ioctave, numerals=st.NUMERALS, bpm=st.BPM * 2) play_wait() else: print("No!", chordname(chord, numeral)) if st.RESOLVE_WHEN_INCORRECT: resolve_with_chords(numeral, key=st.KEY, Ioctave=Ioctave, numerals=st.NUMERALS, bpm=st.BPM * 2) play_wait() else: print("User input not understood. Please try again.") return
def eval_interval(ans, interval, diatonic): try: int(ans) answers = [x for x in ans] except: answers = ans.split(" ") def parse_answer(ans): try: return int(ans) % 8 except: try: note_name = ans[0].upper() + ans[1:] # capitalize for mingus return diatonic.note2num(Note(ans)) except: return "Err" user_answers = [parse_answer(ans) for ans in answers] correct_answers = [diatonic.note2num(x) for x in interval] if len(answers) < len(interval): print("too few answers") if len(answers) > len(interval): print("too many answers") print("Your answer: ", " ".join([str(x) for x in user_answers])) print("Correct Answer:", " ".join([str(x) for x in correct_answers])) ###debug (safe to delete) try: semitone_distance = int(interval[1]) - int(interval[0]) except: print() print(interval) print() raise ###end of debug (safe to delete) semitone_distance = int(interval[1]) - int(interval[0]) names = ['8', '2b', '2','3b', '3', '4', '5b', '5', '6b', '6', '7b', '7'] print("Interval:", names[semitone_distance % 12]) if all([x == y for x, y in zip(user_answers, correct_answers)]): st.SCORE += 1 print("Good Job!") print() else: print("It's ok, you'll get 'em next time.") print() play_wait()
def new_question_rn(game_settings): gst = game_settings if st.NEWQUESTION: if st.COUNT: print("score: {} / {} = {:.2%}".format(st.SCORE, st.COUNT, st.SCORE / st.COUNT)) st.COUNT += 1 # Find random melody/progression try: previous_note = st.CURRENT_Q_INFO['notes'][-1] except: previous_note = None notes = gst.scale.bounded_random_notes(gst.low, gst.high, gst.max_int, gst.notes_per_phrase, previous_note) # store question info st.CURRENT_Q_INFO = {'notes': notes} else: notes = st.CURRENT_Q_INFO['notes'] # Play melody/progression # start_time = time.time() # i0 = len(HISTORY) if gst.single_notes: easy_play(notes, bpm=gst.bpm) else: easy_play([gst.scale.root2chord(n, gst.chord_type) for n in notes], bpm=gst.bpm) # def midi_listen(notes): # i0 = len(HISTORY) # quarter_notes_per_second = 4*gst.bpm/60 # time.sleep(gst.notes_per_phrase*quarter_notes_per_second) # # play_wait(notes, bpm=gst.bpm) # return HISTORY[i0:] # Request user's answer if isinstance(gst.listener, MidiListener): user_response = \ gst.listener.listen(num_notes=gst.notes_per_phrase) user_response_notes = parse_midi_input(user_response) eval_rn(user_response_notes, notes, gst) play_wait(3, bpm=gst.bpm) elif isinstance(gst.listener, MicListener): user_response_notes = gst.listener.listen(notes, (gst.low, gst.high), mingus_range=True) eval_rn(user_response_notes, notes, gst) else: play_wait(3, bpm=gst.bpm)
def eval_interval_name(user_answer, interval, diatonic): semitone_distance = int(interval[1]) - int(interval[0]) names = ['8', '2b', '2', '3b', '3', '4', '5b', '5', '6b', '6', '7b', '7'] correct_answer = names[semitone_distance % 12] user_answer = user_answer.strip() print("Your answer: ", user_answer) print("Correct Answer:", correct_answer) note_nums = [diatonic.note2degree(x) for x in interval] print("Interval Notes:", " ".join([str(x) for x in note_nums])) if user_answer == correct_answer: st.SCORE += 1 print("Good Job!") print() else: print("It's ok, you'll get 'em next time.") print() play_wait()
def intro(play_cadence=True): print("\n" + "~" * 20 + "\n") # List menu_commands print("Note: At any time enter") for mc in menu_commands.values(): print(mc.input_description, "to", mc.description) print("\n" + "-" * 10 + "\n") # Display key if st.KEY == st.KEY.lower(): print("KEY:", st.KEY.upper(), "min") else: print("KEY:", st.KEY, "Maj") print("-" * 10) # Play cadence if play_cadence: play_progression(st.CADENCE, st.KEY, Iup=st.I) play_wait() # time.sleep(st.DELAY) # time.sleep(st.DELAY) return
def playfcn(): play_progression([numeral], st.KEY, Ioctave=Ioctave) play_wait() fluidsynth.play_Note(tone)
def new_question_chord_tone(): if st.NEWQUESTION: if st.COUNT: print("score: {} / {} = {:.2%}".format(st.SCORE, st.COUNT, st.SCORE / st.COUNT)) st.COUNT += 1 # Pick random chord/octave numeral, chord, Ioctave = random_chord() # Pick a random tone in the chord tone = random.choice(chord) # store question info st.CURRENT_Q_INFO = { 'numeral': numeral, 'chord': chord, 'Ioctave': Ioctave, 'tone': tone } else: numeral = st.CURRENT_Q_INFO['numeral'] chord = st.CURRENT_Q_INFO['chord'] Ioctave = st.CURRENT_Q_INFO['Ioctave'] tone = st.CURRENT_Q_INFO['tone'] # Play chord, then tone def playfcn(): play_progression([numeral], st.KEY, Ioctave=Ioctave) play_wait() fluidsynth.play_Note(tone) p = Process(target=playfcn()) p.start() # Request user's answer mes = ("Which tone did you hear?\n" "Enter {}, or {}: ".format( ", ".join([str(t) for t in st.TONES[:-1]]), st.TONES[-1])) ans = getch(mes).strip() p.terminate() if ans in menu_commands: menu_commands[ans].action() else: try: ans = int(ans) except: print("User input not understood. Please try again.") st.NEWQUESTION = False if ans in st.TONES: tone_idx = [n for n in chord].index(tone) correct_ans = st.TONES[tone_idx] if ans == correct_ans: st.SCORE += 1 print("Yes! The {} tone of".format(correct_ans), chordname(chord, numeral)) if st.ARPEGGIATE_WHEN_CORRECT: resolve_chord_tone(chord, tone, Ioctave) play_wait() st.NEWQUESTION = True else: print("No! The {} tone of".format(correct_ans), chordname(chord, numeral)) if st.ARPEGGIATE_WHEN_INCORRECT: resolve_chord_tone(chord, tone, Ioctave) play_wait() st.NEWQUESTION = True # secret option elif ans in [8, 9, 0]: tone_idx = [8, 9, 0].index(ans) for num in st.NUMERALS: tmp = progressions.to_chords([num], st.KEY)[0] num_chord = NoteContainer(tmp) play_progression([num], st.KEY, Ioctave=Ioctave) play_wait() fluidsynth.play_Note(num_chord[tone_idx]) play_wait() play_wait() st.NEWQUESTION = False else: print("User input not understood. Please try again.") st.NEWQUESTION = False return
def play_cadence(): play_progression(st.CADENCE, st.KEY, Iup=st.I, bpm=st.BPM) play_wait()