示例#1
0
 def __init__(self):
     gtk.Window.__init__(self)
     vbox = gtk.VBox()
     self.add(vbox)
     self.set_default_size(600, 400)
     self.w = RhythmWidget()
     s = elems.Score()
     s.add_staff(staff_class=elems.RhythmStaff)
     s.add_bar(elems.TimeSignature(3, 4))
     s.add_bar(elems.TimeSignature(3, 4))
     s.voice11.fill_with_skips()
     self.w.set_score(s)
     vbox.pack_start(self.w)
     #
     c = RhythmWidgetController(self.w)
     vbox.pack_start(c, False)
     c.show()
     c.set_editable(True)
     self.connect('delete_event', self.quit)
示例#2
0
 def __init__(self, staff, last_timepos):
     """
     Create engraver objects for the staff, one timepos at the time.
     Append them to self, and add refs to them in the m_engravers dict
     to access them by timepos and type.
     """
     list.__init__(self)
     self.m_label = getattr(staff, 'm_label', None)
     self.m_engravers = {}
     # When joining two empty Scores with Score.concat2, we need to return
     # to avoid IndexErrors further down this method.
     if not staff.w_parent().m_bars:
         return
     # make a set of all timeposes in the staffs voices
     t = set()
     # We need to add the timepos of the beginning of all bars, since
     # all staffs has to display the time signature if it changes. Normally
     # it is not necessary to do this here, since staff.m_tdict will have
     # the timepos. But it is necessary for Scores created by Score.concat2
     [t.add(b.m_timepos) for b in staff.w_parent().m_bars]
     # Then we add the timepos of all notes and rests
     [t.add(tp) for tp in staff.m_tdict]
     for voice in staff.m_voices:
         [t.add(tp) for tp in voice.m_tdict]
     if last_timepos is None:
         # display all notes
         timeposes = sorted(t)
     else:
         timeposes = [x for x in sorted(t) if x < last_timepos]
     #
     clef = None
     keysig = ("c", "major")
     self.refill_accidentals_info(keysig)
     for voice in staff.m_voices:
         # tmp variable needed to keep track of the beams. Deleted at method exit.
         voice.m_beam = None
         voice.m_ties = {}
         # tuplet
         voice.m_tuplet = None
     bar_idx = 0
     props = {
         'hide-timesignature': False,
     }
     beams = []
     for timepos in timeposes:
         if (bar_idx < len(staff.w_parent().m_bars) - 1 and timepos
                 == staff.w_parent().m_bars[bar_idx + 1].m_timepos):
             bar_idx += 1
         if timepos not in self.m_engravers:
             self.m_engravers[timepos] = {}
         eng = self.m_engravers[timepos]
         ##############
         # Properties #
         ##############
         if (timepos in staff.m_tdict
                 and 'properties' in staff.m_tdict[timepos]):
             props.update(staff.m_tdict[timepos]['properties'])
         # Forget accidentals at bar lines
         if timepos == staff.w_parent().m_bars[bar_idx].m_timepos:
             self.refill_accidentals_info(keysig)
         ########
         # Clef #
         ########
         if timepos in staff.m_tdict and 'clef' in staff.m_tdict[timepos]:
             clef = staff.m_tdict[timepos]['clef']
             eng['clef'] = ClefEngraver(staff.m_tdict[timepos]['clef'])
             self.append(eng['clef'])
         #################
         # Key signature #
         #################
         if timepos in staff.m_tdict and 'keysig' in staff.m_tdict[timepos]:
             eng['keysig'] = KeySignatureEngraver(
                 keysig, staff.m_tdict[timepos]['keysig'], clef)
             self.append(eng['keysig'])
             keysig = staff.m_tdict[timepos]['keysig']
             self.refill_accidentals_info(keysig)
         ##################
         # Time signature #
         ##################
         if not staff.w_parent().m_bars:
             return
         if (props['hide-timesignature'] == False and
             ((timepos == staff.w_parent().m_bars[bar_idx].m_timepos and
               bar_idx > 0 and staff.w_parent().m_bars[bar_idx].m_timesig !=
               staff.w_parent().m_bars[bar_idx - 1].m_timesig)
              or timepos == elems.TimeSignature(0, 1))):
             eng['timesig'] = TimeSignatureEngraver(
                 staff.w_parent().m_bars[bar_idx].m_timesig)
             self.append(eng['timesig'])
         ###############
         # Accidentals #
         ###############
         if isinstance(self, StaffContext):
             v = {}
             for voice in staff.m_voices:
                 if timepos not in voice.m_tdict:
                     continue
                 # If the 'elem' is a rest or skip,
                 # then there are no accidentals.
                 if isinstance(voice.m_tdict[timepos]['elem'][0],
                               (elems.Rest, elems.Skip)):
                     continue
                 for elem in voice.m_tdict[timepos]['elem']:
                     e = self.needed_accidental(elem.m_musicalpitch)
                     if e is not None:
                         v[clef.steps_to_ylinepos(
                             elem.m_musicalpitch.steps())] = e
             if v:
                 self.append(AccidentalsEngraver(v))
                 eng['accidentals'] = self[-1]
         ############################################
         # Create stems, noteheads and ledger lines #
         ############################################
         # These two count show many ledger lines we need.
         yline_up = 0
         yline_down = 0
         for voice in staff.m_voices:
             if timepos not in voice.m_tdict:
                 continue
             if 'elem' in voice.m_tdict[timepos]:
                 elem = voice.m_tdict[timepos]['elem']
                 if isinstance(elem, elems.Stem):
                     if elem.m_beaminfo == 'start':
                         voice.m_beam = BeamEngraver()
                         beams.append(voice.m_beam)
                         self.append(voice.m_beam)
                     # If the tuplet contain only one tone, then elem.m_tupletinfo == 'end' and
                     # voice.m_tuplet will be None
                     if elem.m_tupletinfo == 'start' or (
                             elem.m_tupletinfo == 'end'
                             and voice.m_tuplet == None):
                         voice.m_tuplet = TupletEngraver(
                             elem.m_tuplet_ratio, elem.m_tuplet_dir)
                 if 'elem' not in eng:
                     eng['elem'] = []
                 if isinstance(voice.m_tdict[timepos]['elem'][0],
                               elems.Rest):
                     e = RestEngraver(
                         0, voice.m_tdict[timepos]['elem'][0].m_duration)
                     self.append(e)
                     eng['elem'].append(e)
                 elif isinstance(elem[0], elems.Skip):
                     e = SkipEngraver(elem[0].m_duration)
                     self.append(e)
                     eng['elem'].append(e)
                 elif not isinstance(voice.m_tdict[timepos]['elem'][0],
                                     elems.Skip):
                     elist, stemengraver = self.create_notehead_engraver(
                         clef, voice.m_tdict[timepos]['elem'])
                     for note, engraver in zip(
                             voice.m_tdict[timepos]['elem'], elist):
                         if note.m_tieinfo == 'start':
                             voice.m_ties[note.m_musicalpitch.
                                          get_octave_notename()] = engraver
                         elif note.m_tieinfo == 'go':
                             self.append(
                                 TieEngraver(
                                     voice.m_ties[note.m_musicalpitch.
                                                  get_octave_notename()],
                                     engraver))
                             del voice.m_ties[
                                 note.m_musicalpitch.get_octave_notename()]
                             voice.m_ties[note.m_musicalpitch.
                                          get_octave_notename()] = engraver
                         elif note.m_tieinfo == 'end':
                             self.append(
                                 TieEngraver(
                                     voice.m_ties[note.m_musicalpitch.
                                                  get_octave_notename()],
                                     engraver))
                             del voice.m_ties[
                                 note.m_musicalpitch.get_octave_notename()]
                     if voice.m_beam:
                         stemengraver.m_is_beamed = True
                         voice.m_beam.add_stem(stemengraver)
                     if voice.m_tuplet:
                         voice.m_tuplet.add_stem(stemengraver)
                     eng['elem'].extend(elist)
                     eng['elem'].append(stemengraver)
                     self.extend(elist)
                     self.append(stemengraver)
                 if isinstance(elem, elems.Stem):
                     if elem.m_beaminfo == 'end':
                         voice.m_beam = None
                     if elem.m_tupletinfo == 'end':
                         self.append(voice.m_tuplet)
                         voice.m_tuplet = None
             # Ledger lines
             for elem in voice.m_tdict[timepos]['elem']:
                 if isinstance(elem, elems.Note):
                     if not clef:
                         # clef is None on a rhythm staff. Then we need no
                         # ledger lines
                         continue
                     ypos = clef.steps_to_ylinepos(
                         elem.m_musicalpitch.steps())
                     if yline_up > ypos < -5:
                         yline_up = ypos
                     if yline_down < ypos > 5:
                         yline_down = ypos
         if yline_up:
             yline_up = -yline_up / 2 - 2
         if yline_down:
             yline_down = yline_down / 2 - 2
         if yline_up or yline_down:
             e = LedgerLineEngraver(yline_up, yline_down)
             eng['elem'].append(e)
             self.append(e)
     # We do this here instead of further up where we check for'
     # if m_beaminfo == 'end' because we need to do do_layout for beams
     # even when we only want to engrave the first note in a beam.
     for b in beams:
         b.do_layout()
示例#3
0
 def _next(self):
     # Doing this while loop inside the exception clause is a little
     # faster than using a regular expression.
     try:
         while self.m_string[self.m_idx] in (' ', '\n', '\t'):
             self.m_idx += 1
     except IndexError:
         raise StopIteration
     self.m_last_idx = self.m_idx
     m = self.re_rest.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         resttype, notelen, dots = m.groups()
         numdots = len(dots)
         if notelen:
             notelen = int(notelen)
         else:
             notelen = 0
             if numdots:
                 raise LexerError(
                     'Need a digit before dots. Write "%(goodcode)s", not "%(badcode)s".'
                     % {
                         'badcode':
                         m.group().strip(),
                         'goodcode':
                         '%s%i%s' % (resttype, self.m_notelen.m_nh, dots)
                     }, self)
         if notelen is 0:
             return self.REST, RestRequest(None, None)
         else:
             self.m_notelen = Duration(notelen, numdots)
             return self.REST, RestRequest(notelen, numdots)
     m = self.re_skip.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         IGN1, skiplen, dots = m.groups()
         numdots = len(dots)
         if skiplen:
             skiplen = int(skiplen)
             self.m_notelen = Duration(skiplen, numdots)
         else:
             skiplen = 0
             if numdots:
                 raise LexerError(
                     'Need a digit before dots. Write "%(goodcode)s", not "%(badcode)s".'
                     % {
                         'badcode': m.group().strip(),
                         'goodcode': 's%i%s' % (self.m_notelen.m_nh, dots)
                     }, self)
         if skiplen is 0:
             return self.SKIP, SkipRequest(skiplen, numdots)
         else:
             self.m_notelen = Duration(skiplen, numdots)
             return self.SKIP, SkipRequest(skiplen, numdots)
     m = self.re_partial.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         num, dot = m.groups()
         num = int(num)
         dot = len(dot)
         return self.PARTIAL, Duration(num, dot)
     m = self.re_melodic.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         notename, IGN1, IGN2, notelen, dots = m.groups()
         numdots = len(dots)
         if notelen:
             notelen = int(notelen)
             self.m_notelen = Duration(notelen, numdots)
         else:
             notelen = 0
             if dots:
                 raise LexerError(
                     'Need a digit before dots. Write "%(goodcode)s", not "%(badcode)s".'
                     % {
                         'badcode':
                         m.group().strip(),
                         'goodcode':
                         '%s%i%s' % (notename, self.m_notelen.m_nh, dots)
                     }, self)
         n = MusicRequest(notename, notelen, numdots)
         return self.NOTE, n
     m = self.re_staff.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.STAFF, None
     m = self.re_rhythmstaff.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.RHYTHMSTAFF, None
     m = self.re_voice.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.VOICE, None
     m = self.re_relative.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.RELATIVE, MusicalPitch.new_from_notename(m.group(1))
     m = self.re_clef_quoted.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.CLEF, m.group(1)
     m = self.re_clef.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.CLEF, m.group(1)
     m = self.re_stem_updown.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         d = [const.UP, const.DOWN, const.BOTH][['Up', 'Down',
                                                 'Both'].index(m.group(2))]
         return self.STEMDIR, d
     m = self.re_tuplet_updown.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         d = [const.UP, const.DOWN, const.BOTH][['Up', 'Down',
                                                 'Both'].index(m.group(2))]
         return self.TUPLETDIR, d
     m = self.re_transpose.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.TRANSPOSE, MusicalPitch.new_from_notename(m.group(1))
     m = self.re_time.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.TIME, elems.TimeSignature(int(m.group(1)),
                                               int(m.group(2)))
     m = self.re_key.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.KEY, (m.group(1), m.group(2))
     m = self.re_times.match(self.m_string, self.m_idx)
     if m:
         self.m_idx = m.end()
         return self.TIMES, Rat(int(m.groups()[0]), int(m.groups()[1]))
     if self.m_idx == len(self.m_string):
         raise StopIteration
     self.m_idx += 1
     return self.m_string[self.m_idx - 1], None