예제 #1
0
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
예제 #2
0
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
예제 #3
0
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()
예제 #4
0
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
예제 #5
0
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()
예제 #6
0
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)
예제 #7
0
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()
예제 #8
0
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
예제 #9
0
 def playfcn():
     play_progression([numeral], st.KEY, Ioctave=Ioctave)
     play_wait()
     fluidsynth.play_Note(tone)
예제 #10
0
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
예제 #11
0
def play_cadence():
    play_progression(st.CADENCE, st.KEY, Iup=st.I, bpm=st.BPM)
    play_wait()