예제 #1
0
    def new_question(self):
        """
        Return a true value if a new question was created otherwise false.
        """
        if self.m_timeout_handle:
            gobject.source_remove(self.m_timeout_handle)
            self.m_timeout_handle = None

        if self.get_bool('config/picky_on_new_question') \
                 and self.q_status in [self.QSTATUS_NEW, self.QSTATUS_WRONG]:
            return Teacher.ERR_PICKY

        first = self.get_list('first_interval_up')
        if self.get_string('first_interval_type') == 'melodic':
            first = first + map(lambda a: -a,
                                self.get_list('first_interval_down'))
        last = self.get_list('last_interval_up')
        if self.get_string('last_interval_type') == 'melodic':
            last = last + map(lambda a: -a,
                              self.get_list('last_interval_down'))
        if not (first and last):
            return self.ERR_CONFIGURE
        self.m_intervals = [random.choice(first), random.choice(last)]
        self.m_tonikas = [
            mpd.MusicalPitch().randomize("f", "f'"),
            mpd.MusicalPitch().randomize("f", "f'")
        ]
        self.q_status = self.QSTATUS_NEW
        return self.OK
예제 #2
0
 def new_question(self):
     """
     Return True if a new question was created.
     Return False if the variables in the lesson file made it impossible
     to create a question.
     """
     self.m_interval = random.choice(self.m_P.header.intervals)
     c = 0
     while 1:
         c += 1
         if self.m_P.header.tones[1] - self.m_P.header.tones[
                 0] < self.m_interval.get_intvalue():
             return False
         self.m_low_pitch = mpd.MusicalPitch().randomize(
             self.m_P.header.tones[0],
             self.m_P.header.tones[1] - self.m_interval.get_intvalue())
         #
         if self.m_interval.steps() == (
                 self.m_low_pitch +
                 self.m_interval).steps() - self.m_low_pitch.steps():
             # this can happen for cases like d# + aug 3
             continue
         if abs(self.m_low_pitch.m_accidental_i) <= self.m_P.header.accidentals and\
                 abs((self.m_low_pitch + self.m_interval).m_accidental_i) <= self.m_P.header.accidentals:
             break
         if c > 1000:
             return False
     self.m_answered_quality = None
     self.m_answered_number = None
     self.q_status = self.QSTATUS_NEW
     return True
예제 #3
0
    def play_users_answer(self, widget):
        if self.g_rhythm_viewer.m_data:
            melody = ""
            p = mpd.MusicalPitch()
            for k in self.g_rhythm_viewer.m_data:
                melody += " " + mpd.transpose_notename(solmisation_notenames[k], self.m_t.m_transp) + "4"

            self.m_t.play(r"\staff{ \time 1000000/4 %s }" % melody)
예제 #4
0
 def __init__(self, exname):
     abstract.Teacher.__init__(self, exname)
     self.lessonfileclass = lessonfile.HeaderLessonfile
     self.m_lessonfile_header_defaults['random_tonic'] = False
     self.m_lessonfile_header_defaults['cadence'] = 'major'
     self.m_lessonfile_defs['other'] = 'other'
     self.m_transpose = mpd.MusicalPitch()
     """To which key the question should be transposed.
     Will be set in :func:`~new_question`
     """
     self.m_statistics = ToneInKeyStatistics(self)
예제 #5
0
    def get_music_notenames(self, count_in):
        """
        Return a string with the notenames of the current question.
        Include count in if count_in == True
        """

        cadence = ""

        cadence += "<"
        cadence += mpd.transpose_notename("c''", self.m_transp) + "4 "
        cadence += mpd.transpose_notename("g'", self.m_transp) + " "
        cadence += mpd.transpose_notename("e'", self.m_transp) + " "
        cadence += mpd.transpose_notename("c", self.m_transp)
        cadence += ">"

        cadence += "<"
        cadence += mpd.transpose_notename("c''", self.m_transp) + "4 "
        cadence += mpd.transpose_notename("a'", self.m_transp) + " "
        cadence += mpd.transpose_notename("c'", self.m_transp) + " "
        cadence += mpd.transpose_notename("f", self.m_transp)
        cadence += ">"

        cadence += "<"
        cadence += mpd.transpose_notename("b'", self.m_transp) + "4 "
        cadence += mpd.transpose_notename("g'", self.m_transp) + " "
        cadence += mpd.transpose_notename("d'", self.m_transp) + " "
        cadence += mpd.transpose_notename("g", self.m_transp)
        cadence += ">"

        cadence += " "

        cadence += "<"
        cadence += mpd.transpose_notename("c''", self.m_transp) + "4 "
        cadence += mpd.transpose_notename("g'", self.m_transp) + " "
        cadence += mpd.transpose_notename("e'", self.m_transp) + " "
        cadence += mpd.transpose_notename("c", self.m_transp)
        cadence += ">"

        #s = "<b'4 g' d' g> <c''2. g' e' c>"

        melody = ""
        p = mpd.MusicalPitch()
        for k in self.m_question:
            melody += " " + mpd.transpose_notename(solmisation_notenames[k],
                                                   self.m_transp) + "4"

        if self.get_bool('play_cadence'):
            result = cadence + " " + melody
        else:
            result = melody

        return result
예제 #6
0
    def new_question(self, L, H):
        assert isinstance(L, basestring)
        assert isinstance(H, basestring)

        if self.m_timeout_handle:
            GObject.source_remove(self.m_timeout_handle)
            self.m_timeout_handle = None

        if solfege.app.m_test_mode:
            old_tonika = self.m_tonika
            if old_tonika:
                old_toptone = old_tonika + self.m_question[0]
            self.m_P.next_test_question()
            self.m_question = [self.m_P.m_test_questions[self.m_P.m_test_idx]]
            self.m_tonika = mpd.MusicalPitch()
            # Do this loop to make sure two questions in a row does not have
            # the same top or bottom tone.
            while True:
                self.m_tonika, _ignore = utils.random_tonika_and_interval(
                    L, H, self.m_question)
                if not old_tonika:
                    break
                if old_tonika != self.m_tonika and self.m_tonika + self.m_question[
                        0] != old_toptone:
                    break
            self.q_status = self.QSTATUS_NEW
            return self.OK

        if self.get_bool('config/picky_on_new_question') \
              and self.q_status in [self.QSTATUS_NEW, self.QSTATUS_WRONG]:
            return self.ERR_PICKY

        self.q_status = self.QSTATUS_NO
        last_tonika = self.m_tonika
        last_question = self.m_question
        if self.get_bool("lock-to-key"):
            # We don't have to check the validity of these two variables
            # because get_int will check that a int value is stored in the
            # database (and make it an int if it is not), and nComboBox
            # will make sure the int value is within the correct limits.
            lock_tonic = mpd.MusicalPitch.new_from_int(
                self.get_int("lock-to-key-note"))
            lock_scaletype = utils.key_data.keys()[:][self.get_int(
                "lock-to-key-scaletype")]

        def try_make_question():
            try:
                if self.get_bool("lock-to-key"):
                    self.m_tonika, i = \
                        utils.random_tonic_and_interval_in_key(L, H,
                            self.get_list('ask_for_intervals_0'),
                            lock_tonic, lock_scaletype)
                else:
                    self.m_tonika, i = utils.random_tonika_and_interval(
                        L, H, self.get_list('ask_for_intervals_0'))
            except utils.NoPossibleIntervals, e:
                raise self.ConfigureException(self.no_intervals_str % 1)

            self.m_question = [i]
            t = self.m_tonika + i
            for x in range(1, self.get_int('number_of_intervals=1')):
                interval_list = self.get_list('ask_for_intervals_%i' % x)
                if not interval_list:
                    raise self.ConfigureException(self.no_intervals_str %
                                                  (x + 1))
                if self.get_bool('lock-to-key'):
                    i = utils.random_interval_in_key(t, L, H, interval_list,
                                                     lock_tonic,
                                                     lock_scaletype)
                    if not i:
                        raise self.ConfigureException(
                            _(u"Failed to select random interval number %i because of the configuration of the exercise. Either you have enabled intervals only if one direction, or none of the intervals belong to the key selected when you enabled «Lock to key»."
                              ) % x)
                else:
                    i = utils.random_interval(
                        t, L, H, self.get_list('ask_for_intervals_%i' % x))
                    if not i:
                        raise self.ConfigureException(
                            _("Failed to select random interval number %i because of the configuration of the exercise. You should select some intervals going in both directions."
                              ) % x)
                self.m_question.append(i)
                t = t + i
예제 #7
0
    def new_question(self, L, H):
        """
        Return values:
        OK: new question created, all ok
        ERR_NO_INTERVALLS: no new question because no intervals are selected
        ERR_PICKY: you have to solve this question before you are allowed to create new
        """
        if self.m_timeout_handle:
            GObject.source_remove(self.m_timeout_handle)
            self.m_timeout_handle = None

        if solfege.app.m_test_mode:
            old_tonika = self.m_tonika
            if old_tonika:
                old_toptone = old_tonika + self.m_interval
            self.m_P.next_test_question()
            self.m_interval = self.m_P.m_test_questions[self.m_P.m_test_idx]
            # FIXME use tone pitch range from preferences window.
            self.m_tonika = mpd.MusicalPitch()
            # Do this loop to make sure two questions in a row does not have
            # the same top or bottom tone.
            while True:
                self.m_tonika.randomize("f", "f'")
                if not old_tonika:
                    break
                if old_tonika != self.m_tonika and self.m_tonika + self.m_interval != old_toptone:
                    break
            self.q_status = self.QSTATUS_NEW
            return self.OK

        if self.get_bool('config/picky_on_new_question') \
                 and self.q_status in [self.QSTATUS_NEW, self.QSTATUS_WRONG]:
            return Teacher.ERR_PICKY

        if self.get_list('intervals') == []:
            self.q_status = self.QSTATUS_NO
            return Teacher.ERR_NO_INTERVALLS
        last_question = self.m_interval
        last_tonika = self.m_tonika
        while 1:
            # in this loop we will try to make a question that is not the
            # same that the last one.
            try:
                if self.get_bool("lock-to-key"):
                    self.m_tonika, self.m_interval = \
                        utils.random_tonic_and_interval_in_key(L, H,
                            self.get_list('intervals'),
                            mpd.MusicalPitch.new_from_int(self.get_int("lock-to-key-note")),
                            list(solfege.utils.key_data.keys())[:][self.get_int("lock-to-key-scaletype")])
                else:
                    self.m_tonika, self.m_interval = \
                          utils.random_tonika_and_interval(L, H,
                            self.get_list('intervals'))
            except solfege.utils.NoPossibleIntervals as e:
                solfege.win.display_error_message2(
                    _("Exercise configuration problem"), str(e))
                return self.ERR_NO_INTERVALLS
            if last_question is None:
                break
            if (self.m_interval == last_question
                and self.m_tonika == last_tonika) \
                and (len(self.get_list('intervals')) > 1):
                continue
            break
        assert self.m_tonika
        self.q_status = self.QSTATUS_NEW
        return Teacher.OK
예제 #8
0
 def __init__(self, exname):
     abstract.Teacher.__init__(self, exname)
     self.lessonfileclass = lessonfile.HeaderLessonfile
     self.m_transpose = mpd.MusicalPitch()
     self.m_statistics = ToneInKeyStatistics(self)