Esempio n. 1
0
 def test_relative(self):
     s = r"\staff\relative d'{ d f }"
     score = parse_to_score_object(s)
     self.assertEquals(score.voice11.m_tdict[Rat(0, 1)]['elem'][0],
                       Note.new_from_string("d'4"))
     self.assertEquals(score.voice11.m_tdict[Rat(1, 4)]['elem'][0],
                       Note.new_from_string("f'4"))
Esempio n. 2
0
 def fill_skips(self, voice):
     """
     Add Skips at the end of the bar, so that it is filled.
     We assume that any elements already added are placed at
     the correct timepos.
     """
     # nt = short for "next timepos", the timepos to start fill skips to
     if voice.get_timeposes_of(self):
         nt = voice.get_timeposes_of(self)[-1]
         nt = nt + voice.m_tdict[nt]['elem'][0].m_duration.get_rat_value()
     else:
         # we get here if the bar is empty
         nt = self.m_timepos
     default_skip = Rat(1, 4)
     # pos within default skip
     pp = nt - int(nt / default_skip) * default_skip
     if pp != Rat(0, 1):
         # Here we add a skip so that the next column will be X times
         # default_skip
         voice.set_elem([Skip(Duration.new_from_rat(default_skip - pp))],
                        nt)
         nt += (default_skip - pp)
     # And the we fill the bar with Skips as long as default_skip.
     while nt < self.end():
         voice.set_elem([Skip(Duration.new_from_rat(default_skip))], nt)
         nt += default_skip
Esempio n. 3
0
 def test_transpose(self):
     s = r"\staff\transpose d'{ c d }"
     score = parse_to_score_object(s)
     self.assertEquals(score.voice11.m_tdict[Rat(0, 1)]['elem'][0],
                       Note.new_from_string("d4"))
     self.assertEquals(score.voice11.m_tdict[Rat(1, 4)]['elem'][0],
                       Note.new_from_string("e4"))
     s = r"\staff\transpose d''{ c d }"
     score = parse_to_score_object(s)
     self.assertEquals(score.voice11.m_tdict[Rat(0, 1)]['elem'][0],
                       Note.new_from_string("d'4"))
     self.assertEquals(score.voice11.m_tdict[Rat(1, 4)]['elem'][0],
                       Note.new_from_string("e'4"))
Esempio n. 4
0
 def test_transpose_relative(self):
     s = r"\staff\transpose d'\relative c'{ c d }"
     score = parse_to_score_object(s)
     self.assertEqual(score.voice11.m_tdict[Rat(0, 1)]['elem'][0],
                      Note.new_from_string("d'4"))
     self.assertEqual(score.voice11.m_tdict[Rat(1, 4)]['elem'][0],
                      Note.new_from_string("e'4"))
     s = r"\staff\transpose d''\relative c'{ c d e}"
     score = parse_to_score_object(s)
     self.assertEqual(score.voice11.m_tdict[Rat(0, 1)]['elem'][0],
                      Note.new_from_string("d''4"))
     self.assertEqual(score.voice11.m_tdict[Rat(1, 4)]['elem'][0],
                      Note.new_from_string("e''4"))
     self.assertEqual(score.voice11.m_tdict[Rat(1, 2)]['elem'][0],
                      Note.new_from_string("fis''4"))
Esempio n. 5
0
    def _update(self):
        """
        Updates the buttons above the action_area where you have
        one or more buttons with a small note pixmap on. Each of the
        buttons will play one part of the music in the question.
        """

        # tmp func used as callback function
        def f(w, start, end, self=self):
            try:
                utils.play_music(
                    self.m_t.m_P.get_music(), self.m_t.m_P.get_tempo(),
                    cfg.get_int('config/preferred_instrument'),
                    cfg.get_int('config/preferred_instrument_volume'), start,
                    end)
            except Exception as e:
                if not self.standard_exception_handler(e,
                                                       soundcard.synth.stop):
                    raise

        for i in self.g_partbox.get_children():
            i.destroy()
        # if the lessonfile was invalid, m_P could be None
        if self.m_t.m_P and self.m_t.m_P.m_questions:
            if 'name' in self.m_t.m_P.get_question():
                self.g_question_title.set_text(self.m_t.m_P.get_name())
            else:
                self.g_question_title.set_text("")
            v = self.m_t.m_P.get_breakpoints()
            if v == []:
                # we display one button that will play the whole music if
                # there are not breakpoints in the music
                btn = self.create_pixmap_button()
                btn.connect('clicked', f, None, None)
                btn.show()
                self.g_partbox.pack_start(btn, True, True, 0)
                return
            tmp = [Rat(0, 1)] + v + [Rat(2**30, 1)]
            for i in range(len(tmp) - 1):
                btn = self.create_pixmap_button()
                btn.show()
                btn.connect('clicked', f, tmp[i], tmp[i + 1])
                self.g_partbox.pack_start(btn, True, True, 0)
        # q_status is QSTATUS_NO if the question is invalid (from the lessonfile)
        if self.m_t.q_status == self.QSTATUS_NO:
            self.g_partbox.set_sensitive(False)
        else:
            self.g_partbox.set_sensitive(True)
Esempio n. 6
0
 def try_set_elem(self, elem, timepos, insert_mode):
     """
     Replace whatever is at timepos with elem.
     Return True if succuessful.
     """
     bp = BarProxy(self, timepos)
     if isinstance(self.m_tdict[timepos]['elem'][0], Skip):
         if timepos + elem.m_duration.get_rat_value() <= bp.end():
             if isinstance(elem, Note):
                 stem = Stem(self, [elem], const.UP)
                 self.set_elem(stem, timepos)
             else:
                 self.set_elem([elem], timepos)
                 elem.w_parent = weakref.ref(self)
             bp.remove_skips()
             bp.repack()
             bp.fill_skips()
             return True
     else:
         max_free = bp.get_free_time()
         #flytt til bar-class
         delta = elem.m_duration.get_rat_value(
         ) - self.m_tdict[timepos]['elem'][0].m_duration.get_rat_value()
         if insert_mode:
             if max_free >= elem.m_duration.get_rat_value():
                 self.m_tdict[timepos +
                              Rat(1, 1000000)] = self.m_tdict[timepos]
                 del self.m_tdict[timepos]
                 bp.remove_trailing(elem.m_duration.get_rat_value())
                 stem = Stem(self, [elem], const.UP)
                 self.set_elem(stem, timepos)
                 bp.remove_skips()
                 bp.repack()
                 bp.fill_skips()
                 return True
         if not insert_mode:
             if (max_free >= delta):
                 # We have space to add.
                 # Delete skips (and rests) from the end of the bar
                 # until we have enough space to add the elem.
                 if delta > Rat(0, 1):
                     bp.remove_trailing(delta)
                 stem = Stem(self, [elem], const.UP)
                 self.set_elem(stem, timepos)
                 bp.remove_skips()
                 bp.repack()
                 bp.fill_skips()
                 return True
Esempio n. 7
0
 def concat(s1, s2):
     """
     Concatenate the two scores, and return a new score. Both scores
     need to have the exact same staff and voice layout.
     """
     assert isinstance(s1, Score)
     assert isinstance(s2, Score)
     if len(s1.m_staffs) != len(s2.m_staffs):
         raise Score.StaffCountException()
     if [type(x) for x in s1.m_staffs] != [type(x) for x in s2.m_staffs]:
         raise Score.StaffTypeException()
     for idx, (st1, st2) in enumerate(zip(s1.m_staffs, s2.m_staffs)):
         if len(st1.m_voices) != len(st2.m_voices):
             raise Score.VoiceCountException()
     ret = s1.copy()
     if not s1.m_staffs:
         return s1
     # do the adding
     for bar in s2.m_bars:
         bar.m_timepos = ret.m_bars[-1].end()
         ret.m_bars.append(bar)
     ret.create_shortcuts()
     if s1.m_bars:
         start = s1.m_bars[-1].end()
     else:
         start = Rat(0, 1)
     s2.create_shortcuts()  # FIXME why?
     for staff_idx, staff in enumerate(s1.m_staffs):
         for voice_idx, voice in enumerate(staff.m_voices):
             for k in s2.m_staffs[staff_idx].m_voices[voice_idx].m_tdict:
                 ret.m_staffs[staff_idx].m_voices[voice_idx].m_tdict[
                     k + start] = s2.m_staffs[staff_idx].m_voices[
                         voice_idx].m_tdict[k]
     return ret
Esempio n. 8
0
 def display_start_of_music(self):
     """
     Callers must catch exceptions.
     """
     fontsize = self.get_int('config/feta_font_size=20')
     try:
         if self.m_t.m_P.get_clue_music():
             self.g_music_displayer.display(
                 self.m_t.m_P.get_clue_music().get_mpd_music_string(
                     self.m_t.m_P), fontsize)
         elif self.m_t.m_P.get_clue_end():
             self.g_music_displayer.display(self.m_t.m_P.get_music(),
                                            fontsize,
                                            self.m_t.m_P.get_clue_end())
         else:
             self.g_music_displayer.display(self.m_t.m_P.get_music(),
                                            fontsize, Rat(0, 1))
     except mpd.MpdException, e:
         if self.m_t.m_P.get_clue_music():
             e.m_mpd_varname = 'clue_music'
         else:
             e.m_mpd_varname = 'music'
         self.m_t.m_P.get_question()['music'].complete_to_musicdata_coords(
             self.m_t.m_P, e)
         if 'm_mpd_badcode' not in dir(e):
             e.m_mpd_badcode = self.m_t.m_P.get_question()[
                 e.m_mpd_varname].get_err_context(e, self.m_t.m_P)
         raise
Esempio n. 9
0
 def concat2(s1, s2):
     """
     Return a new Score object concatenating the two scores. This is
     intended return value is intended for playback only, since the
     staffs placed below each other. So the first score will have empty
     bars at the end, and the last score will have empty bars at the
     beginning.
     """
     assert isinstance(s1, Score)
     assert isinstance(s2, Score)
     ret = s1.copy()
     if s1.m_bars:
         start = s1.m_bars[-1].end()
     else:
         start = Rat(0, 1)
     for bar in s2.m_bars:
         ret.m_bars.append(Bar(bar.m_timesig, ret.m_bars[-1].end()))
     for staff_idx, staff in enumerate(s2.m_staffs):
         ret.add_staff(staff_class=staff.__class__)
         for k in staff.m_tdict:
             ret.m_staffs[-1].m_tdict[start + k] = staff.m_tdict[k]
         for voice_idx, voice in enumerate(staff.m_voices):
             if voice_idx != 0:
                 ret.m_staffs[-1].add_voice()
             # This line make the music from sc2 continue after the
             # point where the music from sc1 ends.
             ret.m_staffs[-1].m_voices[-1].m_length = s1.m_bars[-1].end()
             for elem in s2.m_staffs[staff_idx].m_voices[voice_idx]:
                 ret.m_staffs[-1].m_voices[-1].append(elem['elem'])
     ret.create_shortcuts()
     return ret
Esempio n. 10
0
 def _get_new_bar_timepos(self):
     """
     Return the timepos where the next bar will be added.
     """
     if self.m_bars:
         return self.m_bars[-1].end()
     return Rat(0, 1)
Esempio n. 11
0
 def get_timelist(self):
     curpos = Rat(0, 1)
     retval = []
     for timepos in sorted(self.m_tdict.keys()):
         if isinstance(self.m_tdict[timepos]['elem'][0], Rest):
             if retval[-1][0] == False:
                 retval[-1][1] += self.m_tdict[timepos]['elem'][
                     0].m_duration.get_rat_value()
             else:
                 retval.append([
                     False, self.m_tdict[timepos]['elem']
                     [0].m_duration.get_rat_value()
                 ])
         elif self.m_tdict[timepos]['elem'][0].m_tieinfo == 'start':
             nlen = self.m_tdict[timepos]['elem'][
                 0].m_duration.get_rat_value()
         elif self.m_tdict[timepos]['elem'][0].m_tieinfo == 'continue':
             nlen += self.m_tdict[timepos]['elem'][
                 0].m_duration.get_rat_value()
         else:
             if self.m_tdict[timepos]['elem'][0].m_tieinfo == 'end':
                 nlen += self.m_tdict[timepos]['elem'][
                     0].m_duration.get_rat_value()
             else:
                 nlen = self.m_tdict[timepos]['elem'][
                     0].m_duration.get_rat_value()
             retval.append(
                 [isinstance(self.m_tdict[timepos]['elem'][0], Note), nlen])
             nlen = None
     return retval
Esempio n. 12
0
 def remove_trailing(self, voice, duration):
     """
     Remove elements from the end of the bar, until their duration
     is a least 'duration' long.
     """
     assert isinstance(duration, Rat)
     total = Rat(0, 1)
     while total < duration:
         total += self.pop_last_elem(voice)
Esempio n. 13
0
 def copy(self, parent):
     """
     Return a copy of this Voice object. We make a copy of the dict and
     the m_length variable, but the dict revers to the same object.
     """
     ret = Voice(parent)
     ret.m_length = Rat(self.m_length.m_num, self.m_length.m_den)
     ret.m_tdict = self.m_tdict.copy()
     return ret
Esempio n. 14
0
 def get_free_time(self, voice):
     """
     Return the duration, as a Rat value, on the end of the bar
     consisting of Rests and Skips.
     """
     d = Rat(0, 1)
     for timepos in reversed(voice.get_timeposes_of(self)):
         if not isinstance(voice.m_tdict[timepos]['elem'][0], (Skip, Rest)):
             break
         d += voice.m_tdict[timepos]['elem'][0].m_duration.get_rat_value()
     return d
Esempio n. 15
0
 def get_timelist(self):
     data = {}
     for staff_idx, staff in enumerate(self.m_staffs):
         for voice_idx, voice in enumerate(staff.m_voices):
             for timepos in voice.m_tdict:
                 n = voice.m_tdict[timepos]['elem'][0]
                 if isinstance(n, Note):
                     if timepos not in data:
                         data[timepos] = {'start': set(), 'end': set()}
                     if n.m_tieinfo not in ('go', 'end'):
                         data[timepos]['start'].add((staff_idx, voice_idx))
                     if n.m_tieinfo in (None, 'end'):
                         endpos = timepos + n.m_duration.get_rat_value()
                         if endpos not in data:
                             data[endpos] = {'start': set(), 'end': set()}
                         data[endpos]['end'].add((staff_idx, voice_idx))
     retval = []
     start_time = None
     v = sorted(data)[:]
     ppos = Rat(0, 1)
     voices = set()
     for idx, timepos in enumerate(v):
         if data[timepos]['start'] and data[timepos]['end']:
             for voice in data[timepos]['end']:
                 voices.remove(voice)
             for voice in data[timepos]['start']:
                 voices.add(voice)
             assert voices
             retval.append([True, timepos - ppos])
             ppos = timepos
         elif data[timepos]['start']:
             if not voices:
                 if (timepos != ppos):
                     retval.append([False, timepos - ppos])
                     ppos = timepos
             else:
                 retval.append([True, timepos - ppos])
                 ppos = timepos
             for voice in data[timepos]['start']:
                 voices.add(voice)
         elif data[timepos]['end']:
             for voice in data[timepos]['end']:
                 voices.remove(voice)
             if not voices:
                 retval.append([True, timepos - ppos])
                 ppos = timepos
     return retval
Esempio n. 16
0
 def test_timelist(self):
     score = parse_to_score_object(r"\staff{c2    r4 r8 a8}"
                                   r"\staff{c4 c2    r8 g8}")
     self.assertEquals(score.get_timelist(), [
         [True, Rat(1, 4)],
         [True, Rat(1, 2)],
         [False, Rat(1, 8)],
         [True, Rat(1, 8)],
     ])
     score = parse_to_score_object(r"\staff{c4   d8 }" r"\staff{r8 e    }")
     self.assertEquals(score.get_timelist(), [
         [True, Rat(1, 8)],
         [True, Rat(1, 8)],
         [True, Rat(1, 8)],
     ])
     score = parse_to_score_object(r"\staff{c4    r8 r8 d8 }"
                                   r"\staff{r8 e8 r8 r4   }")
     self.assertEquals(score.get_timelist(), [
         [True, Rat(1, 8)],
         [True, Rat(1, 8)],
         [False, Rat(1, 4)],
         [True, Rat(1, 8)],
     ])
Esempio n. 17
0
        # if the lessonfile was invalid, m_P could be None
        if self.m_t.m_P and self.m_t.m_P.m_questions:
            if 'name' in self.m_t.m_P.get_question():
                self.g_question_title.set_text(self.m_t.m_P.get_name())
            else:
                self.g_question_title.set_text("")
            v = self.m_t.m_P.get_breakpoints()
            if v == []:
                # we display one button that will play the whole music if
                # there are not breakpoints in the music
                btn = self.create_pixmap_button()
                btn.connect('clicked', f, None, None)
                btn.show()
                self.g_partbox.pack_start(btn, True, True, 0)
                return
            tmp = [Rat(0, 1)] + v + [Rat(2**30, 1)]
            for i in range(len(tmp) - 1):
                btn = self.create_pixmap_button()
                btn.show()
                btn.connect('clicked', f, tmp[i], tmp[i + 1])
                self.g_partbox.pack_start(btn, True, True, 0)
        # q_status is QSTATUS_NO if the question is invalid (from the lessonfile)
        if self.m_t.q_status == self.QSTATUS_NO:
            self.g_partbox.set_sensitive(False)
        else:
            self.g_partbox.set_sensitive(True)

    def display_start_of_music(self):
        """
        Callers must catch exceptions.
        """
Esempio n. 18
0
 def __init__(self, parent):
     _StaffCommon.__init__(self, parent)
     self.set_clef("violin", Rat(0, 1))
Esempio n. 19
0
 def __init__(self, parent):
     HasParent.__init__(self, parent)
     # The timelen of the Voice
     self.m_length = Rat(0, 1)
     self.m_tdict = {}
Esempio n. 20
0
 def as_rat(self):
     return Rat(self.m_num, self.m_den)