-class Etf_file:
- def __init__ (self, name):
- self.measures = [None]
- self.entries = [None]
- self.chords = [None]
- self.frames = [None]
- self.tuplets = [None]
- self.staffs = [None]
- self.slur_dict = {}
- self.articulations = [None]
- self.syllables = [None]
- self.verses = [None]
-
- ## do it
- self.parse (name)
-
- def get_global_measure (self, no):
- if len (self.measures) <= no:
- self.measures = self.measures + [None]* (1 + no - len (self.measures))
-
- if self.measures[no] == None:
- self.measures [no] = Global_measure (no)
-
- return self.measures[no]
-
-
- def get_staff(self,staffno):
- if len (self.staffs) <= staffno:
- self.staffs = self.staffs + [None] * (1 + staffno - len (self.staffs))
-
- if self.staffs[staffno] == None:
- self.staffs[staffno] = Staff (staffno)
-
- return self.staffs[staffno]
-
- # staff-spec
- def try_IS (self, l):
- pass
-
- def try_BC (self, l):
- m = BCre.match (l)
- if m:
- bn = string.atoi (m.group (1))
- where = string.atoi (m.group (2)) / 1024.0
- return m
- def try_TP(self, l):
- m = TPre.match (l)
- if m:
- (nil, num) = map (string.atoi, (m.groups ()[0:2]))
- entries = map (string.atoi, (m.groups ()[2:]))
-
- if self.tuplets[-1] == None or num <> self.tuplets[-1].start_note:
- self.tuplets.append (Tuplet (num))
-
- self.tuplets[-1].append_finale (entries)
-
- def try_IM (self, l):
- m = IMre.match (l)
- if m:
- a = string.atoi (m.group (1))
- b = string.atoi (m.group (2))
-
- fin = map (string.atoi, m.groups ()[2:])
-
- self.articulations.append (Articulation (a,b,fin))
- return m
- def try_verse (self,l):
- m = versere .match (l)
- if m:
- a = string.atoi (m.group (1))
- body =m.group (2)
-
- body = re.sub (r"""\^[a-z]+\([^)]+\)""", "", body)
- body = re.sub ("\^[a-z]+", "", body)
- self.verses.append (Verse (a, body))
-
- return m
- def try_ve (self,l):
- m = vere .match (l)
- if m:
- a = string.atoi (m.group (1))
- b = string.atoi (m.group (2))
-
- fin = map (string.atoi, m.groups ()[2:])
-
- self.syllables.append (Syllable (a,b,fin))
- return m
- def try_eE (self, l):
- m = eEre.match (l)
- if m:
- tup = m.groups()
- (no, prev, next, dur, pos, entryflag, extended, follow) = tup
- (no, prev, next, dur, pos,extended, follow) \
- = tuple (map (string.atoi, [no,prev,next,dur,pos,extended,follow]))
-
- entryflag = string.atol (entryflag,16)
- if no > len (self.entries):
- sys.stderr.write ("\nHuh? Entry number to large,\nexpected %d got %d. Filling with void entries.\n" % (len(self.entries), no ))
- while len (self.entries) <> no:
- c = ((len (self.entries), 0, 0, 0, 0, 0L, 0, 0), [])
- self.entries.append (c)
-
- current_entry = ((no, prev, next, dur, pos, entryflag, extended, follow), [])
- self.entries.append (current_entry)
- return m
-
- def try_Sx(self,l):
- m = Sxre.match (l)
- if m:
- slurno = string.atoi (m.group (1))
-
- sl = None
- try:
- sl = self.slur_dict[slurno]
- except KeyError:
- sl = Slur (slurno)
- self.slur_dict[slurno] = sl
-
- params = list (m.groups ()[1:])
- params = map (string.atoi, params)
- sl.append_entry (params)
-
- return m
- def try_GF(self, l):
- m = GFre.match (l)
- if m:
- (staffno,measno) = m.groups ()[0:2]
- s = string.atoi (staffno)
- me = string.atoi (measno)
-
- entry = m.groups () [2:]
- st = self.get_staff (s)
- meas = st.get_measure (me)
- meas.add_finale_entry (entry)
-
- # frame ?
- def try_FR(self, l):
- m = FRre.match (l)
- if m:
- (frameno, startnote, endnote, foo, bar) = m.groups ()
- (frameno, startnote, endnote) = tuple (map (string.atoi, [frameno, startnote, endnote]))
- if frameno > len (self.frames):
- sys.stderr.write ("Frame no %d missing, filling up to %d\n" % (len(self.frames), frameno))
- while frameno <> len (self.frames):
- self.frames.append (Frame ((len (self.frames), 0,0) ))
-
- self.frames.append (Frame ((frameno, startnote, endnote)))
-
- return m
- def try_MS (self, l):
- m = MSre.match (l)
- if m:
- measno = string.atoi (m.group (1))
- keynum = string.atoi (m.group (3))
- meas =self. get_global_measure (measno)
- meas.set_keysig (keynum)
-
- beats = string.atoi (m.group (4))
- beatlen = string.atoi (m.group (5))
- meas.set_timesig ((beats, beatlen))
-
- return m
-
- def try_note (self, l):
- m = note_re.match (l)
- if m:
- (pitch, flag) = m.groups ()
- pitch = string.atoi (pitch)
- flag = string.atol (flag,16)
- self.entries[-1][1].append ((pitch,flag))
-
- def parse (self, name):
- sys.stderr.write ('parsing ...')
- sys.stderr.flush ()
-
- gulp = open (name).read ()
-
- gulp = re.sub ('[\n\r]+', '\n', gulp)
- ls = string.split (gulp, '\n')
-
- for l in ls:
- m = None
- if not m:
- m = self.try_MS (l)
- if not m:
- m = self.try_FR (l)
- if not m:
- m = self.try_GF (l)
- if not m:
- m = self.try_note (l)
- if not m:
- m = self.try_eE (l)
- if not m:
- m = self.try_IM (l)
- if not m:
- m = self.try_Sx (l)
- if not m:
- m = self.try_TP (l)
- if not m:
- m = self.try_verse (l)
-
- sys.stderr.write ('processing ...')
- sys.stderr.flush ()
-
- self.unthread_entries ()
-
- for st in self.staffs[1:]:
- if not st:
- continue
- mno = 1
- for m in st.measures[1:]:
- if not m:
- continue
-
- m.calculate()
- try:
- m.global_measure = self.measures[mno]
- except IndexError:
- sys.stderr.write ("non-existent global measure %d" % mno)
- continue
-
- frame_obj_list = [None]
- for frno in m.frames:
- fr = self.frames[frno]
- frame_obj_list.append (fr)
-
- m.frames = frame_obj_list
- for fr in frame_obj_list[1:]:
- if not fr:
- continue
-
- fr.set_measure (m)
-
- fr.chords = self.get_thread (fr.start, fr.end)
- for c in fr.chords:
- c.frame = fr
- mno = mno + 1
-
- for c in self.chords[1:]:
- c.calculate()
-
- for f in self.frames[1:]:
- f.calculate ()
-
- for t in self.tuplets[1:]:
- t.calculate (self.chords)
-
- for s in self.slur_dict.values():
- s.calculate (self.chords)
- for s in self.articulations[1:]:
- s.calculate (self.chords)
-
- def get_thread (self, startno, endno):
-
- thread = []
-
- c = None
- try:
- c = self.chords[startno]
- except IndexError:
- sys.stderr.write ("Huh? Frame has invalid bounds (%d,%d)\n" % (startno, endno))
- return []
-
-
- while c and c.number () <> endno:
- thread.append (c)
- c = c.next
-
- if c:
- thread.append (c)
-
- return thread
-
- def dump (self):
- str = ''
- staffs = []
- for s in self.staffs[1:]:
- if s:
- str = str + '\n\n' + s.dump ()
- staffs.append ('\\' + s.staffid ())
-
-
- # should use \addlyrics ?
-
- for v in self.verses[1:]:
- str = str + v.dump()
-
- if len (self.verses) > 1:
- sys.stderr.write ("\nLyrics found; edit to use \\addlyrics to couple to a staff\n")
-
- if staffs:
- str = str + '\\score { < %s > } ' % string.join (staffs)
-
- return str
-
-
- def __str__ (self):
- return 'ETF FILE %s %s' % (self.measures, self.entries)
-
- def unthread_entries (self):
- self.chords = [None]
- for e in self.entries[1:]:
- self.chords.append (Chord (e))
-
- for e in self.chords[1:]:
- e.prev = self.chords[e.finale[0][1]]
- e.next = self.chords[e.finale[0][2]]