Ejemplo n.º 1
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
Ejemplo n.º 2
0
 def test_bug1(self):
     """
     For each moment in time, all note-off events have to be
     done before the note-on events. This to avoid problems
     with the same note being played two times after each other
     in different tracks.
     """
     t1 = Track()
     t1.set_patch(3)
     t1.note(4, 93, 127)
     t1.note(4, 95, 127)
     t2 = Track()
     t2.set_patch(4)
     t2.note(4, 95, 127)
     t2.note(4, 97, 127)
     self.assertEquals(list(MidiEventStream(t1, t2)),
                       [('program-change', 0, 3), ('program-change', 1, 4),
                        ('volume', 0, 100), ('note-on', 0, 93, 127),
                        ('volume', 1, 100), ('note-on', 1, 95, 127),
                        ('notelen-time', Rat(1, 4)),
                        ('note-off', 0, 93, 127), ('note-off', 1, 95, 127),
                        ('note-on', 0, 95, 127), ('note-on', 1, 97, 127),
                        ('notelen-time', Rat(1, 4)),
                        ('note-off', 0, 95, 127), ('note-off', 1, 97, 127)])
     self.assertEquals(
         MidiEventStream(t1, t2).str_repr(details=1),
         "p0:3 p1:4 v0:100 n0:93 v1:100 n1:95 d1/4 o93 o95 n0:95 n1:97 d1/4 o95 o97"
     )
Ejemplo n.º 3
0
 def test_1(self):
     bp = BarProxy(self.score.voice11, Rat(0, 1))
     bp.remove_trailing(Rat(1, 4))
     bp.pop_last_elem()
     bp.remove_skips()
     bp.repack()
     bp.fill_skips()
     bp.end()
Ejemplo n.º 4
0
 def test_add_bar(self):
     self.assertIsInstance(self.score.add_bar(TimeSignature(4, 4)), Bar)
     self.score.add_bar(TimeSignature(4, 4))
     self.score.add_bar(TimeSignature(1, 4))
     self.score.add_bar(TimeSignature(1, 4))
     self.assertEqual(self.score.m_bars[0].m_timepos, Rat(0, 1))
     self.assertEqual(self.score.m_bars[1].m_timepos, Rat(1, 1))
     self.assertEqual(self.score.m_bars[2].m_timepos, Rat(2, 1))
     self.assertEqual(self.score.m_bars[3].m_timepos, Rat(9, 4))
Ejemplo n.º 5
0
 def test_stem_down(self):
     self.score.voice11.append(Note.new_from_string("c'8"))
     self.score.voice11.append(Note.new_from_string("c'8"), const.DOWN)
     self.assertEqual(
         self.score.voice11.m_tdict[Rat(0, 1)]['elem'].m_stemdir,
         const.BOTH)
     self.assertEqual(
         self.score.voice11.m_tdict[Rat(1, 8)]['elem'].m_stemdir,
         const.DOWN)
Ejemplo n.º 6
0
 def test_is_last(self):
     voice = self.score.voice11
     voice.append(Note.new_from_string("c2"))
     voice.append(Note.new_from_string("d2"))
     voice.append(Note.new_from_string("f1"))
     voice.append(Note.new_from_string("g4"))
     self.assertTrue(voice.is_last(Rat(1, 2)))
     self.assertFalse(voice.is_last(Rat(0, 1)))
     self.assertTrue(voice.is_last(Rat(1, 2)))
     self.assertTrue(voice.is_last(Rat(1, 1)))
     self.assertFalse(voice.is_last(Rat(2, 1)))
Ejemplo n.º 7
0
 def test_tuplets(self):
     n1 = Note(MusicalPitch.new_from_notename("g'"),
               Duration(8, 0, Rat(2, 3)))
     n2 = Note(MusicalPitch.new_from_notename("g'"),
               Duration(8, 0, Rat(2, 3)))
     n3 = Note(MusicalPitch.new_from_notename("g'"),
               Duration(8, 0, Rat(2, 3)))
     self.score.voice11.append(n1)
     self.score.voice11.append(n2)
     self.score.voice11.append(n3)
     self.score.voice11.tuplet(Rat(2, 3), const.UP, [n1, n2, n3])
Ejemplo n.º 8
0
 def test_constructor(self):
     self.assertEquals(float(Rat(1, 4)), 0.25)
     self.assertEquals(float(Rat(9, 8)), 1.125)
     self.assertEquals(float(Rat(4, 4)), 1.0)
     # I was a little surprised by the following, that 4/4 is not
     # simplified to 1, but I also see that we need it this way
     # for time signatures.
     r = Rat(4, 4)
     self.assertEquals(float(r), 1.0)
     self.assertEquals(r.m_num, 4)
     self.assertEquals(r.m_den, 4)
Ejemplo n.º 9
0
 def test_bar_fill_skips(self):
     n1 = Note(MusicalPitch.new_from_notename("g'"), Duration(4, 0))
     self.score.voice11.append(n1)
     self.score.voice11.append(Rest(Duration.new_from_string("4")))
     self.bp.fill_skips()
     self.assertTrue(
         isinstance(self.score.voice11.m_tdict[Rat(0, 1)]['elem'][0], Note))
     self.assertTrue(
         isinstance(self.score.voice11.m_tdict[Rat(1, 4)]['elem'][0], Rest))
     self.assertTrue(
         isinstance(self.score.voice11.m_tdict[Rat(1, 2)]['elem'][0], Skip))
     self.assertTrue(
         isinstance(self.score.voice11.m_tdict[Rat(3, 4)]['elem'][0], Skip))
Ejemplo n.º 10
0
 def get_rat_value(self):
     """
     >>> A=Duration(4, 1, Rat(1, 1))
     >>> B=Duration(4, 2, Rat(3, 5))
     >>> A.get_rat_value(), B.get_rat_value()
     ((Rat 3/8), (Rat 21/80))
     """
     d = Rat(1, self.m_nh)
     if self.m_dots > 0:
         d = d + Rat(1, self.m_nh * 2)
     if self.m_dots > 1:
         d = d + Rat(1, self.m_nh * 4)
     return d * self.m_tuplet
Ejemplo n.º 11
0
 def on_expose_event(self, darea, event):
     MusicDisplayer.on_expose_event(self, darea, event)
     dim = engravers.dimentions[self.m_fontsize]
     if self.m_cursor is not None:
         staff_centrum = dim.first_staff_ypos
         if self.m_cursor == 'erase':
             return
         if self.m_cursor == 'notehead':
             eng = engravers.NoteheadEngraver(Rat(0, 1), "20-tight", 0, self._yp, 2, 0, 0, 0)
         else:
             eng = engravers.AccidentalsEngraver(Rat(0, 1), "20-tight", {self._yp: [int(self.m_cursor)]})
         eng.m_xpos = 50
         eng.engrave(darea, self.black_gc, staff_centrum)
Ejemplo n.º 12
0
 def test_add_partial_bar(self):
     self.score.add_partial_bar(Duration.new_from_string("4"),
                                TimeSignature(4, 4))
     self.score.add_bar(None)
     self.assertEqual(self.score.m_bars[0].m_timepos, Rat(0, 1))
     self.assertEqual(self.score.m_bars[0].end(), Rat(1, 4))
     self.assertEqual(self.score.m_bars[1].m_timepos, Rat(1, 4))
     self.assertEqual(self.score.get_bar_at(Rat(0, 1)),
                      self.score.m_bars[0])
     self.assertEqual(self.score.get_bar_at(Rat(1, 4)),
                      self.score.m_bars[1])
     self.score.voice11.append(Note.new_from_string("c4"))
     self.score.voice11.append(Note.new_from_string("c1"))
     self.score.voice11.append(Note.new_from_string("c1"))
Ejemplo n.º 13
0
 def test_set_clef(self):
     self.score.voice11.set_clef("violin")
     self.assertEqual(self.score.staff1.m_tdict[Rat(0, 1)]['clef'].m_name,
                      "violin")
     self.score.voice11.set_clef("bass")
     # The last clef set is remembered
     self.assertEqual(self.score.staff1.m_tdict[Rat(0, 1)]['clef'].m_name,
                      "bass")
     self.score.voice11.append(Note.new_from_string("c'8"))
     self.score.voice11.set_clef("treble")
     self.assertEqual(self.score.staff1.m_tdict[Rat(0, 1)]['clef'].m_name,
                      "bass")
     self.assertEqual(self.score.staff1.m_tdict[Rat(1, 8)]['clef'].m_name,
                      "treble")
Ejemplo n.º 14
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
Ejemplo n.º 15
0
 def test_simple1(self):
     t = Track()
     t.note(4, 90, 127)
     self.assertEqual(list(MidiEventStream(t)),
                      [('program-change', 0, 0), ('volume', 0, 100),
                       ('note-on', 0, 90, 127), ('notelen-time', Rat(1, 4)),
                       ('note-off', 0, 90, 127)])
Ejemplo n.º 16
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 in range(len(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
Ejemplo n.º 17
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)
Ejemplo n.º 18
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 st1, st2 in 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 in range(len(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
Ejemplo n.º 19
0
 def __init__(self, duration, dots):
     """duration: integer 1 for 1/1 note 4 for 1/4 etc
     """
     if duration:
         self.m_duration = Duration(duration, dots, Rat(1, 1))
     else:
         self.m_duration = None
Ejemplo n.º 20
0
 def test_1voice_setpatch(self):
     t = Track()
     t.note(4, 90, 127)
     t.set_patch(3)
     t.note(4, 91, 127)
     self.assertEquals(list(MidiEventStream(t)), [
         ('program-change', 0, 0),
         ('program-change', 1, 3),
         ('volume', 0, 100),
         ('note-on', 0, 90, 127),
         ('notelen-time', Rat(1, 4)),
         ('note-off', 0, 90, 127),
         ('volume', 1, 100),
         ('note-on', 1, 91, 127),
         ('notelen-time', Rat(1, 4)),
         ('note-off', 1, 91, 127),
     ])
Ejemplo n.º 21
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)
Ejemplo n.º 22
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
Ejemplo n.º 23
0
 def __init__(self, nh, dots, tuplet=Rat(1, 1)):
     """
     nh   - the type of note: 1 2 4 8 16 32 etc
     dots - the number of dots after the notehead
     tuplet - for example 2/3 for triplets
     """
     self.m_nh = nh
     self.m_dots = dots
     self.m_tuplet = tuplet
Ejemplo n.º 24
0
 def test_rh_1(self):
     self.assertEqual(f3(r"\staff{c}"), [[True, Rat(1, 4)]])
     self.assertEqual(f3(r"\staff{c2}"), [[True, Rat(1, 2)]])
     self.assertEqual(f3(r"\staff{c4 c8}"), [
         [True, Rat(1, 4)],
         [True, Rat(1, 8)],
     ])
     self.assertEqual(f3(r"\staff{c4 c4}"), [
         [True, Rat(1, 4)],
         [True, Rat(1, 4)],
     ])
     self.assertEqual(f3(r"\staff{c4. c4}"), [
         [True, Rat(3, 8)],
         [True, Rat(1, 4)],
     ])
     self.assertEqual(f3(r"\staff{c4~ c8 c4}"), [
         [True, Rat(3, 8)],
         [True, Rat(1, 4)],
     ])
Ejemplo n.º 25
0
 def test_rh_rest(self):
     self.assertEqual(f3(r"\staff{c4 r8 c4}"), [
         [True, Rat(1, 4)],
         [False, Rat(1, 8)],
         [True, Rat(1, 4)],
     ])
     self.assertEqual(f3(r"\staff{c4 r8 r16 c4}"), [
         [True, Rat(1, 4)],
         [False, Rat(3, 16)],
         [True, Rat(1, 4)],
     ])
     self.assertEqual(f3(r"\staff{c4 c8 c8}"), [
         [True, Rat(1, 4)],
         [True, Rat(1, 8)],
         [True, Rat(1, 8)],
     ])
Ejemplo n.º 26
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
Ejemplo n.º 27
0
 def test_add_note(self):
     self.score.voice11.append(Note.new_from_string("c'4"))
     self.score.voice11.append(Note.new_from_string("c'2"))
     self.score.voice11.append(Note.new_from_string("c'8"))
     self.assertIsInstance(self.score.voice11.m_tdict[Rat(0, 1)]['elem'][0],
                           Note)
     self.assertIsInstance(
         self.score.voice11.m_tdict[Rat(0, 1)]['elem'][0].w_parent(), Stem)
     self.assertIsInstance(
         self.score.voice11.m_tdict[Rat(
             0, 1)]['elem'][0].w_parent().w_parent(), Voice)
     # bar full:
     self.assertRaises(Voice.BarFullException, self.score.voice11.append,
                       Note.new_from_string("c'4"))
     self.score.voice11.append(Note.new_from_string("c'8"))
     self.score.voice11.append([
         Note.new_from_string("c'1"),
         Note.new_from_string("e'1"),
         Note.new_from_string("g'1"),
     ])
Ejemplo n.º 28
0
 def calculate_event_times(self):
     """
     Set the variable m_time on each Event. Well actually we don't set
     it on the Delay events because events of that type does not generate
     any events when generating music.
     """
     pos = Rat(0, 1)
     for e in self.m_v:
         if isinstance(e, Delay):
             pos += e.m_duration
         else:
             e.m_time = pos
Ejemplo n.º 29
0
 def generate_track_for_voice(self, voice, kv, tracktype):
     D = self.get_event_dict(voice, kv)
     keys = D.keys()
     keys.sort()
     prev_time = Rat(0)
     ms = tracktype()
     for k in keys:
         delta = None
         if k != Rat(0, 1):
             delta = k - prev_time
         prev_time = k
         for e in D[k]:
             if e[1] == START_NOTE:
                 if delta:
                     ms.notelen_time(delta)
                 ms.start_note(e[2], const.DEFAULT_VELOCITY)
             elif e[1] == STOP_NOTE:
                 if delta:
                     ms.notelen_time(delta)
                 ms.stop_note(e[2], const.DEFAULT_VELOCITY)
             delta = None
     return ms
Ejemplo n.º 30
0
 def notelen_time(self, notelen):
     """
     To avoid having to alter all code calling this, we interpret
     notelen in two different ways depending on its type:
     int: replace to Rat(1, notelen)
     Rat: the value tell the note length. For example Rat(1, 4) for a
          quarter note.
     """
     if isinstance(notelen, int):
         self.m_v.append(Delay(Rat(1, notelen)))
     else:
         assert isinstance(notelen, Rat)
         self.m_v.append(Delay(notelen))