Esempio n. 1
0
 def give_up(self, _o=None):
     if self.m_t.q_status == self.QSTATUS_WRONG:
         if len(self.m_t.m_question) == 1:
             s = utils.int_to_intervalname(self.m_t.m_question[0], False, True)
         else:
             s = "+".join([utils.int_to_intervalname(q, True, True) for q in self.m_t.m_question])
         self.g_flashbar.push(s)
         self.m_t.give_up()
         self.std_buttons_give_up()
         self.g_input.mark_note(int(self.m_t.m_tonika + self.m_t.m_question[0]), 2)
Esempio n. 2
0
 def give_up(self, _o=None):
     if self.m_t.q_status == self.QSTATUS_WRONG:
         if len(self.m_t.m_question) == 1:
             s = utils.int_to_intervalname(self.m_t.m_question[0], False, True)
         else:
             s = "+".join([utils.int_to_intervalname(q, True, True) for q in self.m_t.m_question])
         self.g_flashbar.push(s)
         self.m_t.give_up()
         self.std_buttons_give_up()
         self.g_input.mark_note(int(self.m_t.m_tonika + self.m_t.m_question[0]), 2)
Esempio n. 3
0
    def export_training_set(self, export_data, export_dir, output_format,
                            name_track_by_question):
        """
        This function requires a program that can create WAV files
        from MIDI files and MP3 files from WAV.
        """
        def delay(n, tempo):
            """
            tempo is a dict of two integers
            """
            track = mpd.Track()
            track.set_bpm(*tempo)  # self.get_int('config/default_bpm'))
            track.note(mpd.Rat(n, 4), 80, 0)
            soundcard.synth.play_track(track)
        track_idx = 0
        num = sum([x['count'] for x in export_data])
        # MainWin will set this to True if the user want to cancel
        # the export.
        self.m_abort_export = False
        report = reportlib.Report()
        report.append(reportlib.Heading(1, "Exported exercises"))
        table = reportlib.Table()
        report.append(table)
        for lesson_info in export_data:
            filename = lesson_info['filename']
            module = lessonfile.infocache.get(filename, 'module')
            if module not in self.m_teachers:
                self.create_teacher(module)
            p = self.m_teachers[module].lessonfileclass()
            p.parse_file(lessonfile.uri_expand(filename))
            for c in range(lesson_info['count']):
                trackname = "track-%i"
                if module == 'idbyname':
                    p.select_random_question()
                    if p.header.lesson_heading:
                        s = p.header.lesson_heading
                    else:
                        s = p.header.title
                    table.append_row("%i" % track_idx,
                                     p.get_question().name,
                                     s)
                    if name_track_by_question:
                        trackname = "%s-%%i" % p.get_name()
                    soundcard.start_export(os.path.join(
                            export_dir, "%s.mid" % trackname % track_idx))
                    for n in range(lesson_info.get('repeat', 1)):
                        p.play_question()
                        if n != lesson_info.get('repeat', 1) - 1:
                            if 'delay' in lesson_info:
                                delay(lesson_info['delay'], p.get_tempo())
                    soundcard.end_export()
                elif module in ('melodicinterval', 'harmonicinterval'):
                    t = self.m_teachers[module]
                    t.set_lessonfile(filename)
                    t.start_practise()
                    t.new_question("c", "c''")
                    t.q_status = t.QSTATUS_SOLVED
                    try:
                        table.append_row("%i" % track_idx, "%s" % utils.int_to_intervalname(t.m_interval))
                        if name_track_by_question:
                            trackname = "%%i-%s.mid" % utils.int_to_intervalname(t.m_interval)
                    except AttributeError:
                        table.append_row("%i" % track_idx, "%s" % (" + ".join([utils.int_to_intervalname(q, False, True) for q in t.m_question])))
                        if name_track_by_question:
                            trackname = "%%i-%s.mid" % ("+".join([utils.int_to_intervalname(q, False, True) for q in t.m_question]))
                    soundcard.start_export(os.path.join(
                            export_dir, "%s.mid" % trackname % track_idx))
                    for n in range(lesson_info.get('repeat', 1)):
                        t.play_question()
                        if n != lesson_info.get('repeat', 1) - 1:
                            if 'delay' in lesson_info:
                                delay(lesson_info['delay'],
                                    (self.get_int('config/default_bpm'), 4))
                    soundcard.end_export()
                else:
                    logging.warning("export_training_set:ignoring exercise with module='%s'", module)
#####

                def do_convert(from_format, to_format):
                    """
                    Return False if we think the convert failed.
                    """
                    app_cfg_name = "app/%s_to_%s_cmd" % (from_format, to_format)
                    if from_format == 'midi':
                        from_ext = 'mid'
                    else:
                        from_ext = from_format
                    to_ext = to_format
                    if not cfg.get_string(app_cfg_name):
                        solfege.win.display_error_message2("Config variable not defined", "The missing or empty variable was '%s'" % app_cfg_name)
                        return False
                    try:
                        inout = {
                            'in': os.path.join(export_dir,
                                    "%s.%s" % (trackname % track_idx, from_ext)),
                            'out': os.path.join(export_dir,
                                    "%s.%s" % (trackname % track_idx, to_ext))}
                        opts = cfg.get_string(app_cfg_name + '_options').split(" ")
                        opts = [x % inout for x in opts]
                        # For some reasong setting the executable arg does
                        # not work for Python 2.5.2
                        try:
                            subprocess.call(
                                [cfg.get_string(app_cfg_name)] + opts)
                        except OSError as e:
                            raise osutils.BinaryForMediaConvertorException(app_cfg_name,
                                cfg.get_string(app_cfg_name), e)

                        if os.path.exists(os.path.join(export_dir, "%s.%s" % (trackname % track_idx, to_ext))):
                            os.remove(os.path.join(export_dir, "%s.%s" % (trackname % track_idx, from_ext)))
                        else:
                            # This means that the program failed to generate
                            # the WAV file. We set output_format to 'midi'
                            # because we don't want to display this error for
                            # every single file.
                            output_format = 'midi'
                            solfege.win.display_error_message2("External program must have failed", "The file in %(from)s format was not generated from the %(to)s file as expected. Please check your setup in the preferences window (CTRL-F12)." % {'to': to_format.upper(), 'from': from_format.upper()})
                    except (TypeError, KeyError):
                        solfege.win.display_error_message2("%(from)s to %(to)s config error", "There was a format string error. Will not generate WAV files. Please check the app/midi_to_wav_cmd config variable." % {'from': from_format, 'to': to_format})
                        output_format = 'midi'
                    return True
#####
                if output_format in ('mp3', 'wav', 'ogg'):
                    do_convert('midi', 'wav')
                if output_format in ('mp3', 'ogg'):
                    if not do_convert('wav', output_format):
                        output_format = 'wav'
                track_idx += 1
                yield 1.0 * track_idx / num
                if self.m_abort_export:
                    del self.m_abort_export
                    return
        reportlib.HtmlReport(report, os.path.join(export_dir, "toc.html"))
Esempio n. 4
0
 def click_on_interval(self, mouse_button, interval, midi_int):
     """The key bindings are also directed here.
     """
     if mouse_button == 3 and not solfege.app.m_test_mode \
             and self.get_int('number_of_intervals') == 1:
         if not self.m_t.m_tonika:
             return
         i = mpd.Interval()
         if (not midi_int  # buttons interface does not set midi_int. And
                 # since it assumes all intervals go up, we have
                 # to check and set the direction.
                 and self.m_t.m_question[0] < 0):
             i.set_from_int(-interval)
         else:
             i.set_from_int(interval)
         n = self.m_t.m_tonika + i
         track = utils.new_track()
         track.note(4, self.m_t.m_tonika.semitone_pitch())
         track.note(4, n.semitone_pitch())
         soundcard.synth.play_track(track)
         return
     if mouse_button not in (1, self.keyboard_accel):
         return
     if solfege.app.m_test_mode and self.m_t.q_status == self.QSTATUS_NO:
         self.g_flashbar.flash(_("Click 'Start test' to begin."))
         return
     if solfege.app.m_test_mode:
         self.g_new.hide()
     if self.m_t.q_status == self.QSTATUS_NO:
         self.g_flashbar.flash(_("Click 'New interval' to begin."))
         return
     if midi_int:
         # midi_int is only set when we use some of the instrument widgets,
         # not when we use the buttons interface.
         utils.play_note(4, midi_int)
     if self.m_t.q_status == self.QSTATUS_GIVE_UP:
         return
     if self.m_t.q_status == self.QSTATUS_SOLVED:
         self.g_flashbar.flash(
             _("You have already identified this interval"))
         return
     if not (mpd.interval.min_interval < interval <=
             mpd.interval.max_interval):
         self.g_flashbar.flash(
             _("Ignoring intervals greater than double octave."))
         self.g_input.forget_last_tone()
         return
     self.m_answer.append(interval)
     d = self.m_t.m_question[len(self.m_answer) - 1]
     md = d / abs(d)
     if self.g_input.know_directions():
         md = 1
     if not self.msg:
         self.msg = utils.int_to_intervalname(interval * md, 1, 1) + "+ ..."
     else:
         self.msg = self.msg[:-4]
         self.msg = self.msg + utils.int_to_intervalname(
             interval * md, 1, 1) + "+ ..."
     self.g_flashbar.push(self.msg)
     if len(self.m_answer) == self.m_number_of_intervals_in_question:
         if self.m_t.guess_answer(self.m_answer,
                                  self.g_input.know_directions()):
             self.g_flashbar.clear()
             self.g_flashbar.flash(_("Correct"))
             self.std_buttons_answer_correct()
         else:
             self.g_flashbar.clear()
             self.g_flashbar.flash(_("Wrong"))
             if self.get_bool(
                     "config/auto_repeat_question_if_wrong_answer"):
                 self.m_t.play_question()
             self.std_buttons_answer_wrong()
         self.m_answer = []
         self.g_input.set_first_note(self.m_t.m_tonika)
         self.msg = ""
     if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete():
         self.do_test_complete()
         return
Esempio n. 5
0
 def key_to_pretty_name(self, key):
     return utils.int_to_intervalname(int(key), 1, 0)
Esempio n. 6
0
 def key_to_pretty_name(self, key):
     return utils.int_to_intervalname(int(key), 1, 0)
Esempio n. 7
0
 def click_on_interval(self, mouse_button, interval, midi_int):
     """The key bindings are also directed here.
     """
     if mouse_button == 3 and not solfege.app.m_test_mode \
             and self.get_int('number_of_intervals') == 1:
         if not self.m_t.m_tonika:
             return
         i = mpd.Interval()
         if (not midi_int # buttons interface does not set midi_int. And
                          # since it assumes all intervals go up, we have
                          # to check and set the direction.
             and self.m_t.m_question[0] < 0):
             i.set_from_int(-interval)
         else:
             i.set_from_int(interval)
         n = self.m_t.m_tonika + i
         track = utils.new_track()
         track.note(4, self.m_t.m_tonika.semitone_pitch())
         track.note(4, n.semitone_pitch())
         soundcard.synth.play_track(track)
         return
     if mouse_button not in (1, self.keyboard_accel):
         return
     if solfege.app.m_test_mode and self.m_t.q_status == self.QSTATUS_NO:
         self.g_flashbar.flash(_("Click 'Start test' to begin."))
         return
     if solfege.app.m_test_mode:
         self.g_new.hide()
     if self.m_t.q_status == self.QSTATUS_NO:
         self.g_flashbar.flash(_("Click 'New interval' to begin."))
         return
     if midi_int:
         # midi_int is only set when we use some of the instrument widgets,
         # not when we use the buttons interface.
         utils.play_note(4, midi_int)
     if self.m_t.q_status == self.QSTATUS_GIVE_UP:
         return
     if self.m_t.q_status == self.QSTATUS_SOLVED:
         self.g_flashbar.flash(_("You have already identified this interval"))
         return
     if not (-17 < interval < 17):
         self.g_flashbar.flash(_("Ignoring intervals greater than major tenth."))
         self.g_input.forget_last_tone()
         return
     self.m_answer.append(interval)
     d = self.m_t.m_question[len(self.m_answer)-1]
     md = d / abs(d)
     if self.g_input.know_directions():
         md = 1
     if not self.msg:
         self.msg = utils.int_to_intervalname(interval * md, 1, 1) + "+ ..."
     else:
         self.msg = self.msg[:-4]
         self.msg = self.msg + utils.int_to_intervalname(interval * md, 1, 1) + "+ ..."
     self.g_flashbar.push(self.msg)
     if len(self.m_answer) == self.m_number_of_intervals_in_question:
         if self.m_t.guess_answer(self.m_answer,
                                  self.g_input.know_directions()):
             self.g_flashbar.clear()
             self.g_flashbar.flash(_("Correct"))
             self.std_buttons_answer_correct()
         else:
             self.g_flashbar.clear()
             self.g_flashbar.flash(_("Wrong"))
             if self.get_bool("config/auto_repeat_question_if_wrong_answer"):
                 self.m_t.play_question()
             self.std_buttons_answer_wrong()
         self.m_answer = []
         self.g_input.set_first_note(self.m_t.m_tonika)
         self.msg = ""
     if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete():
         self.do_test_complete()
         return
Esempio n. 8
0
    def export_training_set(self, export_data, export_dir, output_format,
                            name_track_by_question):
        """
        This function requires a program that can create WAV files
        from MIDI files and MP3 files from WAV.
        """
        def delay(n, tempo):
            """
            tempo is a dict of two integers
            """
            track = mpd.Track()
            track.set_bpm(*tempo)  #self.get_int('config/default_bpm'))
            track.note(mpd.Rat(n, 4), 80, 0)
            soundcard.synth.play_track(track)

        track_idx = 0
        num = sum([x['count'] for x in export_data])
        # MainWin will set this to True if the user want to cancel
        # the export.
        self.m_abort_export = False
        report = reportlib.Report()
        report.append(reportlib.Heading(1, "Exported exercises"))
        table = reportlib.Table()
        report.append(table)
        for lesson_info in export_data:
            filename = lesson_info['filename']
            module = lessonfile.infocache.get(filename, 'module')
            if module not in self.m_teachers:
                self.create_teacher(module)
            p = self.m_teachers[module].lessonfileclass()
            p.parse_file(lessonfile.uri_expand(filename))
            for c in range(lesson_info['count']):
                trackname = "track-%i"
                if module == 'idbyname':
                    p.select_random_question()
                    if p.header.lesson_heading:
                        s = p.header.lesson_heading
                    else:
                        s = p.header.title
                    table.append_row("%i" % track_idx,
                                     p.get_question().name, s)
                    if name_track_by_question:
                        trackname = "%s-%%i" % p.get_name()
                    soundcard.start_export(
                        os.path.join(export_dir,
                                     "%s.mid" % trackname % track_idx))
                    for n in range(lesson_info.get('repeat', 1)):
                        p.play_question()
                        if n != lesson_info.get('repeat', 1) - 1:
                            if 'delay' in lesson_info:
                                delay(lesson_info['delay'], p.get_tempo())
                    soundcard.end_export()
                elif module in ('melodicinterval', 'harmonicinterval'):
                    t = self.m_teachers[module]
                    t.set_lessonfile(filename)
                    t.start_practise()
                    t.new_question("c", "c''")
                    t.q_status = t.QSTATUS_SOLVED
                    try:
                        table.append_row(
                            "%i" % track_idx,
                            "%s" % utils.int_to_intervalname(t.m_interval))
                        if name_track_by_question:
                            trackname = "%%i-%s.mid" % utils.int_to_intervalname(
                                t.m_interval)
                    except AttributeError:
                        table.append_row(
                            "%i" % track_idx, "%s" % (" + ".join([
                                utils.int_to_intervalname(q, False, True)
                                for q in t.m_question
                            ])))
                        if name_track_by_question:
                            trackname = "%%i-%s.mid" % ("+".join([
                                utils.int_to_intervalname(q, False, True)
                                for q in t.m_question
                            ]))
                    soundcard.start_export(
                        os.path.join(export_dir,
                                     "%s.mid" % trackname % track_idx))
                    for n in range(lesson_info.get('repeat', 1)):
                        t.play_question()
                        if n != lesson_info.get('repeat', 1) - 1:
                            if 'delay' in lesson_info:
                                delay(lesson_info['delay'],
                                      (self.get_int('config/default_bpm'), 4))
                    soundcard.end_export()
                else:
                    logging.warning(
                        "export_training_set:ignoring exercise with module='%s'",
                        module)
#####

                def do_convert(from_format, to_format):
                    """
                    Return False if we think the convert failed.
                    """
                    app_cfg_name = "app/%s_to_%s_cmd" % (from_format,
                                                         to_format)
                    if from_format == 'midi':
                        from_ext = 'mid'
                    else:
                        from_ext = from_format
                    to_ext = to_format
                    if not cfg.get_string(app_cfg_name):
                        solfege.win.display_error_message2(
                            "Config variable not defined",
                            "The missing or empty variable was '%s'" %
                            app_cfg_name)
                        return False
                    try:
                        inout = {
                            'in':
                            os.path.join(
                                export_dir,
                                "%s.%s" % (trackname % track_idx, from_ext)),
                            'out':
                            os.path.join(
                                export_dir,
                                "%s.%s" % (trackname % track_idx, to_ext))
                        }
                        opts = cfg.get_string(app_cfg_name +
                                              '_options').split(" ")
                        opts = [x % inout for x in opts]
                        # For some reasong setting the executable arg does
                        # not work for Python 2.5.2
                        try:
                            subprocess.call([cfg.get_string(app_cfg_name)] +
                                            opts)
                        except OSError, e:
                            raise osutils.BinaryForMediaConvertorException(
                                app_cfg_name, cfg.get_string(app_cfg_name), e)

                        if os.path.exists(
                                os.path.join(
                                    export_dir, "%s.%s" %
                                    (trackname % track_idx, to_ext))):
                            os.remove(
                                os.path.join(
                                    export_dir, "%s.%s" %
                                    (trackname % track_idx, from_ext)))
                        else:
                            # This means that the program failed to generate
                            # the WAV file. We set output_format to 'midi'
                            # because we don't want to display this error for
                            # every single file.
                            output_format = 'midi'
                            solfege.win.display_error_message2(
                                "External program must have failed",
                                "The file in %(from)s format was not generated from the %(to)s file as expected. Please check your setup in the preferences window (CTRL-F12)."
                                % {
                                    'to': to_format.upper(),
                                    'from': from_format.upper()
                                })
                    except (TypeError, KeyError):
                        solfege.win.display_error_message2(
                            "%(from)s to %(to)s config error",
                            "There was a format string error. Will not generate WAV files. Please check the app/midi_to_wav_cmd config variable."
                            % {
                                'from': from_format,
                                'to': to_format
                            })
                        output_format = 'midi'
                    return True
#####

                if output_format in ('mp3', 'wav', 'ogg'):
                    do_convert('midi', 'wav')
                if output_format in ('mp3', 'ogg'):
                    if not do_convert('wav', output_format):
                        output_format = 'wav'
                track_idx += 1
                yield 1.0 * track_idx / num
                if self.m_abort_export:
                    del self.m_abort_export
                    return