]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.83
authorfred <fred>
Tue, 26 Mar 2002 23:55:13 +0000 (23:55 +0000)
committerfred <fred>
Tue, 26 Mar 2002 23:55:13 +0000 (23:55 +0000)
34 files changed:
buildscripts/pmx2ly.py
flower/include/cons.hh
lily/align-note-column-engraver.cc
lily/beam.cc
lily/breathing-sign.cc
lily/chord-tremolo-engraver.cc
lily/command-request.cc
lily/directional-element-interface.cc
lily/dot-column.cc
lily/dots.cc
lily/dynamic-engraver.cc
lily/engraver.cc
lily/include/bar-engraver.hh
lily/include/command-request.hh
lily/include/directional-element-interface.hh
lily/include/music.hh
lily/include/score-element.hh
lily/include/timing-translator.hh
lily/include/translator-group.hh
lily/repeat-engraver.cc
lily/score-element.cc
lily/score-engraver.cc
lily/separating-group-spanner.cc
lily/slur.cc
lily/spanner.cc
lily/stem-tremolo.cc
lily/stem.cc
lily/tie-column.cc
lily/tie.cc
lily/timing-translator.cc
lily/translator-group.cc
lily/tuplet-spanner.cc
lily/volta-spanner.cc
scripts/etf2ly.py

index 58d32cb4bb6cda7c7664901f6aaa0c8904ceb58a..2f9155005e2ff413f40aab469852d5f34b2987c6 100644 (file)
 #!@PYTHON@
+
+# (urg! wat een pokkeformaat (pokkenformaat?))  
+
 import string
+import sys
+import re
+
+fn = sys.argv[1]
 
-ls = open ('barsant.pmx').readlines ()
+ls = open (fn).readlines ()
 def stripcomment (l):
-       return re.sub ('^%.*$', '', l)
+       return re.sub ('[ \t]*%.*$\n', '', l)
+       
+def stripwhite (l):
+       return re.sub ('[ \n\t]+', ' ', l)
+       
+def stripeols (l):
+       return re.sub ('^ ',  '', re.sub (' $', '', l))
        
 ls = map (stripcomment, ls)
+ls = map (stripwhite, ls)
+ls = map (stripeols, ls)
+
+
 ls = filter (lambda x: x <> '', ls)
 
 opening = ls[0]
 ls = ls[1:]
 
+
 opening = map (string.atoi, re.split ('[\t ]+', opening))
-(nv,noinst,mtrnuml,mtrdenl,mtrnump,mtrdenp,xmtrnum0,isig) = tuple (opening)
+
+(no_staffs, no_instruments, timesig_num,timesig_den, ptimesig_num,
+ ptimesig_den, pickup_beats,keysig_number) = tuple (opening)
 
 
 opening = ls[0]
 ls = ls[1:]
-opening = map (string.atoi, re.split ('[\t ]+', opening))
-(npages,nsyst,musicsize,fracindent) = tuple (opening)
 
-for l  in ls:
-       pass
+# ignore this.
+# opening = map (string.atoi, re.split ('[\t ]+', opening))
+# (no_pages,no_systems, musicsize, fracindent) = tuple (opening)
+
+instruments = []
+while len (instruments) < no_instruments:
+       instruments.append (ls[0])
+       ls = ls[1:]
+
+class Staff:
+       def __init__ (self): 
+               self.voices = ([],[])
+               self.clef = None
+               self.instrument = 0 
+l = ls[0]
+ls = ls[1:]
+
+staffs = map (lambda x: Staff (), range(0, no_staffs))
+staff_idx = 0
+
+for s in staffs:
+       s.clef = l[0]
+       l = l[1:]
+
+# dump path 
+ls = ls[1:] 
+
+# dump more ?
+ls = ls[2:]
+
+actab = {-2: 'eses', -1: 'es', 0 : '', 1: 'is', 2:'isis'}
+
+def pitch_to_lily_string (tup):
+       (o,n,a) = tup
+
+       nm = chr((n + 2) % 7 + ord ('a'))
+       nm = nm + actab[a]
+       if o > 0:
+               nm = nm + "'" * o
+       elif o < 0:
+               nm = nm + "," * -o
+       return nm
+
+class Chord:
+       def __init__ (self):
+               self.pitches = []
+               self.dots = 0
+               self.basic_duration = 0
+               
+       def dump (self):
+               str = ''
+
+               for p in self.pitches:
+                       if str:
+                               str = str + ' ' 
+                       str = str + pitch_to_lily_string (p)
+
+               if len (self.pitches) > 1:
+                       str = '<%s>' % str
+               elif len (self.pitches) == 0:
+                       str = 'r'
+               
+               
+               sd = ''
+               if self.basic_duration == 0.5:
+                       sd = '\\breve'
+               else:
+                       sd = '%d' % self.basic_duration
+
+               str = str + sd + '.' * self.dots 
+               return str
+               
+
+input_left = string.join (ls, ' ')
+
+
+input_left = re.sub ('[ \t\n]+',   ' ', input_left)
+
+SPACE=' \t\n'
+DIGITS ='0123456789'
+basicdur_table = {
+       9: 0.5,
+       0: 0 ,
+       2: 2 ,
+       4: 4 ,
+       8: 8 ,
+       1: 16,
+       3: 32,
+       6: 64
+       }
+
+class Parser:
+       def __init__ (self):
+               self.chords = []
+               self.forced_duration = None
+               self.last_octave = 4
+               
+       def parse_note (self, str):
+               ch = Chord ()
+
+               name = None
+               if str[0] <> 'r':
+                       name = (ord (str[0]) - ord('a') + 5) % 7
+               str = str[1:]
+               
+               forced_duration  = 0
+               alteration = 0
+               dots = 0
+               oct = None
+               durdigit = None
+               multibar = 0
+               while str[0] in 'dsfmnul0123456789.,':
+                       c = str[0]
+                       str = str[1:]
+                       if c == 'f':
+                               alteration = alteration -1
+                       elif c == 'n':
+                               alteration = 0
+                       elif c == 'm':
+                               multibar = 1
+                       elif c == 's':
+                               alteration = alteration +1
+                       elif c == 'd':
+                               dots = dots + 1
+                       elif c in DIGITS and durdigit == None:
+                               durdigit = string.atoi (c)
+                       elif c in DIGITS:
+                               oct = string.atoi (c) - 4
+                       elif c == '.':
+                               dots = dots+ 1
+                               forced_duration = 2
+                       elif c == ',':
+                               forced_duration = 2
+                       
+
+               if durdigit:
+                       ch.basic_duration = basicdur_table[durdigit]
+                       self.last_basic_duration = ch.basic_duration
+               else:
+                       ch.basic_duration = self.last_basic_duration
+
+               if name:
+                       if oct:
+                               self.last_octave =oct
+                       else:
+                               oct = self.last_octave
+
+               if name:
+                       ch.pitches.append ((oct, name,  alteration))
+                       
+               ch.dots = dots
+
+               
+               if forced_duration:
+                       self.forced_duration = ch.basic_duration / forced_duration
+
+
+               self.chords.append (ch)
+               while str[0] in SPACE:
+                       str = str [1:]
+               return str
+
+
+parser =  Parser()
+while input_left:
+       while input_left[0] in 'abcdefgr':
+               input_left = parser.parse_note (input_left)
+       print input_left[0]
+       
+       sys.stderr.write ("\nHuh? Unknown directive %s" %input_left[0:1])
+       input_left = input_left[1:]
+
+
+
+for c in parser.chords:
+       print c.dump ()
        
index 266b9ce51c7a5017181f42a8954abffb6e3409fd..a2ebc352d7b423db6ae89fb476b614639036d0f0 100644 (file)
@@ -75,7 +75,7 @@ template<class T> int cons_list_size_i (Cons<T> *l)
 template<class T>
 Cons<T> * last_cons (Cons<T> * head)
 {
-  while (head->next_)
+  while (head && head->next_)
     {
       head = head->next_;
     }
index 75fb5b94e310a4569ff68d822ed413a5cc3b7330..d29bc1d78cccba3919aef6299211a76d04730e34 100644 (file)
@@ -61,7 +61,7 @@ Align_note_column_engraver::do_removal_processing ()
   if (isdir_b (al))
     {
       Direction d = to_dir (al);
-      Directional_element_interface (align_item_p_).set (d);
+      Directional_element_interface::set (align_item_p_,d);
     }
   
   typeset_element (align_item_p_);
index a9ba9b076ed8477317ba7149b8b5775a2fd192f6..ad90e51814c5b3a6e38d566eb55915d3b83bf938 100644 (file)
@@ -84,8 +84,8 @@ Beam::before_line_breaking (SCM smob)
       warning (_ ("beam has less than two stems"));
     }
 
-  if (!Directional_element_interface (me).get ())
-    Directional_element_interface (me).set (get_default_dir (me));
+  if (!Directional_element_interface::get (me))
+    Directional_element_interface::set (me, get_default_dir (me));
 
   auto_knees (me);
   set_stem_directions (me);
@@ -112,7 +112,7 @@ Beam::get_default_dir (Score_element*me)
   for (int i=0; i <stems.size (); i++)
     do { // HUH -- waar slaat dit op?
       Score_element *s = stems[i];
-      Direction sd = Directional_element_interface (s).get ();
+      Direction sd = Directional_element_interface::get (s);
       int current = sd ? (1 + d * sd)/2
        : Stem::get_center_distance (s, (Direction)-d);
 
@@ -152,14 +152,14 @@ Beam::set_stem_directions (Score_element*me)
 {
   Link_array<Item> stems
     =Pointer_group_interface__extract_elements (me,  (Item*) 0, "stems");
-  Direction d = Directional_element_interface (me).get ();
+  Direction d = Directional_element_interface::get (me);
   
   for (int i=0; i <stems.size (); i++)
     {
       Score_element *s = stems[i];
       SCM force = s->remove_elt_property ("dir-forced");
       if (!gh_boolean_p (force) || !gh_scm2bool (force))
-       Directional_element_interface (s).set (d);
+       Directional_element_interface ::set (s,d);
     }
 } 
 
@@ -183,8 +183,8 @@ Beam::auto_knee (Score_element*me, String gap_str, bool interstaff_b)
   bool knee_b = false;
   int knee_y = 0;
   SCM gap = me->get_elt_property (gap_str.ch_C());
-  
-  Direction d = Directional_element_interface (me).get ();
+
+  Direction d = Directional_element_interface::get (me);
       Link_array<Item> stems=
        Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
   
@@ -218,7 +218,7 @@ Beam::auto_knee (Score_element*me, String gap_str, bool interstaff_b)
          int y = (int)(Stem::head_positions(s)[d])
            + (int)calc_interstaff_dist (s, dynamic_cast<Spanner*> (me));
 
-         Directional_element_interface (s).set (y < knee_y ? UP : DOWN);
+         Directional_element_interface::set (s,y < knee_y ? UP : DOWN);
          s->set_elt_property ("dir-forced", SCM_BOOL_T);
        }
     }
@@ -300,8 +300,8 @@ Beam::after_line_breaking (SCM smob)
   /*
     until here, we used only stem_info, which acts as if dir=up
    */
-  y *= Directional_element_interface (me).get ();
-  dy *= Directional_element_interface (me).get ();
+  y *= Directional_element_interface::get (me);
+  dy *= Directional_element_interface::get (me);
 
 
   Real half_space = Staff_symbol_referencer::staff_space (me) / 2;
@@ -343,7 +343,7 @@ Beam::after_line_breaking (SCM smob)
          */
          int quant_dir = 0;
          if (abs (y_shift) > half_space / 2)
-           quant_dir = sign (y_shift) * Directional_element_interface (me).get ();
+           quant_dir = sign (y_shift) * Directional_element_interface::get (me);
          y = quantise_y_f (me, y, dy, quant_dir);
        }
     }
@@ -459,8 +459,8 @@ Beam::calc_stem_y_f (Score_element*me,Item* s, Real y, Real dy)
   Real stem_y = (dy && dx ? (s->relative_coordinate (0, X_AXIS) - x0) / dx * dy : 0) + y;
 
   /* knee */
-   Direction dir  = Directional_element_interface(me).get ();
-   Direction sdir = Directional_element_interface (s).get ();
+   Direction dir  = Directional_element_interface::get (me);
+   Direction sdir = Directional_element_interface::get (s);
    
     /* knee */
    if (dir!= sdir)
@@ -473,7 +473,7 @@ Beam::calc_stem_y_f (Score_element*me,Item* s, Real y, Real dy)
       // huh, why not for first visible?
        if (Staff_symbol_referencer::staff_symbol_l (s)
           != Staff_symbol_referencer::staff_symbol_l (last_visible_stem (me)))
-        stem_y += Directional_element_interface (me).get ()
+        stem_y += Directional_element_interface::get (me)
           * (beam_multiplicity - stem_multiplicity) * interbeam_f;
       }
 
@@ -485,7 +485,7 @@ Beam::check_stem_length_f (Score_element*me,Real y, Real dy)
 {
   Real shorten = 0;
   Real lengthen = 0;
-  Direction dir = Directional_element_interface (me).get ();
+  Direction dir = Directional_element_interface::get (me);
 
   Link_array<Item> stems=
     Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
@@ -596,7 +596,7 @@ Beam::quantise_y_f (Score_element*me,Real y, Real dy, int quant_dir)
   if (a.size () <= 1)
     return y;
 
-  Real up_y = Directional_element_interface (me).get () * y;
+  Real up_y = Directional_element_interface::get (me) * y;
   Interval iv = quantise_iv (a, up_y/staff_space) * staff_space;
 
   Real q = up_y - iv[SMALLER] <= iv[BIGGER] - up_y 
@@ -604,7 +604,7 @@ Beam::quantise_y_f (Score_element*me,Real y, Real dy, int quant_dir)
   if (quant_dir)
     q = iv[(Direction)quant_dir];
 
-  return q * Directional_element_interface (me).get ();
+  return q * Directional_element_interface::get (me);
 }
 
 void
@@ -674,7 +674,7 @@ Beam::stem_beams (Score_element*me,Item *here, Item *next, Item *prev)
     nw_f = me->paper_l ()->get_var ("quartwidth");
 
 
-  Direction dir = Directional_element_interface (me).get ();
+  Direction dir = Directional_element_interface::get (me);
   
   /* half beams extending to the left. */
   if (prev)
index 8dd2d4298d6903ff2e737bbf5a7576b71010fab5..f6225e51e17cc4e302a8764ed87e4734d957f283 100644 (file)
@@ -43,11 +43,11 @@ Breathing_sign::offset_callback (Score_element * b, Axis a)
   Score_element * me = (Score_element*)b;
   
   Real space = Staff_symbol_referencer::staff_space (b);
-  Direction d = Directional_element_interface (b). get ();
+  Direction d = Directional_element_interface::get (b);
   if (!d)
     {
       d = UP;
-      Directional_element_interface (me).set (d);
+      Directional_element_interface::set (me, d);
     }
 
   return 2.0 * space * d;
index 289ad00b2829a3d4277cb0744cc165bf283bec28..1891eea84474e040fbb49121e85aba150f398f76 100644 (file)
@@ -151,7 +151,7 @@ Chord_tremolo_engraver::acknowledge_element (Score_element_info info)
            It's amazing Mike:
            
              Stem:: type_i () ->first_head ()->get_direction () ->
-                     Directional_element_interface (me).set (d);
+                     Directional_element_interface::set (me, d);
 
 
              don't understand this comment.
index bc919f63e75c489b421bcb9616990f801976ee63..1aaaea84eac453af8abe05465444adbe3ba44aac 100644 (file)
 #include "musical-request.hh"
 
 
-bool
-Bar_req::do_equal_b (Request const *r) const
-{
-  Bar_req  const* b = dynamic_cast <Bar_req const *> (r);
-  return b && type_str_ == b->type_str_;
-}
-
-void
-Bar_req::do_print () const
-{
-#ifndef NPRINT
-  DEBUG_OUT << type_str_;
-#endif
-}
-
 Bar_req::Bar_req (String s)
 {
-  type_str_ = s;
+  set_mus_property ("type", ly_str02scm (s.ch_C()));
 }
 
 bool
index 4a6a9e4d11c1b6de5c470b5706fea495f5503e07..9689529f434a3b4c44ed337067535ba9cbf768cc 100644 (file)
 #include "directional-element-interface.hh"
 
 
-Directional_element_interface::Directional_element_interface (Score_element const *s)
+static SCM Directional_element_interface::direction_sym;
+
+static void
+init_functions ()
 {
-  elt_l_ =  (Score_element*)s;
+  Directional_element_interface::direction_sym = scm_permanent_object (ly_symbol2scm ("direction"));
 }
+ADD_SCM_INIT_FUNC(Directional, init_functions);
+
 
 bool
-Directional_element_interface::has_interface () const
+Directional_element_interface::has_interface (Score_element*me) 
 {
-  return isdir_b (elt_l_->get_elt_property ("direction"));
+  return isdir_b (me->get_elt_property (direction_sym));
 }
 
-
-  
-
 Direction
-Directional_element_interface::get () const
+Directional_element_interface::get (Score_element*me) 
 {
   // return dir_;
-  SCM d= elt_l_->get_elt_property ("direction");
+  SCM d= me->get_elt_property (direction_sym);
   if (!isdir_b(d))
     return CENTER;
       
@@ -36,7 +38,10 @@ Directional_element_interface::get () const
 }
 
 void
-Directional_element_interface::set (Direction d) 
+Directional_element_interface::set (Score_element*me, Direction d) 
 {
-  elt_l_->set_elt_property ("direction", gh_int2scm (d));
+  SCM sd = gh_int2scm (d);
+
+  if (me->get_elt_property (direction_sym) != sd)
+    me->set_elt_property (direction_sym, sd);
 }
index 5557790b33915819b77c26dc6b0bfbf23129514c..38777cb5696fd811924f2f2690ff0efce6e90193 100644 (file)
@@ -40,7 +40,7 @@ void
 Dot_column::set_interface (Score_element* me)
 {
   me->set_elt_property  ("dots", SCM_EOL);
-  Directional_element_interface (me).set (RIGHT);
+  Directional_element_interface::set (me, RIGHT);
   
   Axis_group_interface::set_interface (me);
   Axis_group_interface::set_axes (me, X_AXIS,X_AXIS);
index 1b702e293207749c85219d95b329ccb046041931..c249d6a1cf969967cc4cfd360892e915df9e4278 100644 (file)
@@ -23,13 +23,13 @@ Dots::quantised_position_callback (Score_element * me, Axis a)
   SCM d= me->get_elt_property ("dot-count");
   if (gh_number_p (d) && gh_scm2int (d))
     {
-      if (!Directional_element_interface (me).get ())
-       Directional_element_interface (me).set (UP);
+      if (!Directional_element_interface::get (me))
+       Directional_element_interface::set (me, UP);
 
 
       int pos = int (Staff_symbol_referencer::position_f (me));
       if (!(pos % 2))
-       return Staff_symbol_referencer::staff_space (me) / 2.0 * Directional_element_interface (me).get ();
+       return Staff_symbol_referencer::staff_space (me) / 2.0 * Directional_element_interface::get (me);
     }
 
   return  0.0;
index c399d36f639befba1e1a1dd24576052a23b98970..9093c2aa66d9ca5f3274e5bb37323e3d8bb95409 100644 (file)
@@ -167,7 +167,7 @@ Dynamic_engraver::do_process_music ()
       text_p_ = new Item (get_property ("basicDynamicTextProperties"));
       text_p_->set_elt_property ("text", ly_str02scm (loud.ch_C ()));
       if (Direction d=text_req_l_->get_direction ())
-       Directional_element_interface (line_spanner_).set (d);
+       Directional_element_interface::set (line_spanner_, d);
 
       Axis_group_interface::add_element (line_spanner_, text_p_);
 
@@ -199,8 +199,7 @@ Dynamic_engraver::do_process_music ()
        {
          accepted_spanreqs_drul_[START]->origin ()->warning
            (current_cresc_req_->span_dir_ == 1
-            ?
-            _ ("already have a crescendo")
+            ? _ ("already have a crescendo")
             : _ ("already have a decrescendo"));
        }
       else
index 896c206f1214c40494f22ce54ccdb830d3f58405..60a72fa594ff6a6dd7e6f484c290d9eac25d354f 100644 (file)
@@ -25,9 +25,6 @@ Engraver::announce_element (Score_element_info inf)
 void
 Engraver::announce_element (Score_element* e, Music *m)
 {
-  if (e->get_elt_property ("interfaces") == SCM_EOL)
-    Group_interface (e, "interfaces").add_thing (ly_symbol2scm (e->name()));
-
   if (m && m->origin ()->location_str ().length_i ())
     {
       e->set_elt_property ("origin", m->get_mus_property ("origin"));
index 89ad0898f7b5e84f44d2ce4f2ff082525aae344a..5d91c15b890030765dd7285dd95d3712607b38e6 100644 (file)
@@ -31,6 +31,7 @@ protected:
 
 
 private:
+  void typeset_bar ();
   void create_bar ();
 
   Item * bar_p_;
index 759332508114cde9805964bb9da768dee0caa67d..7ef86dda91242868b4776ea19ebd89fc7d372c27 100644 (file)
@@ -26,10 +26,8 @@ protected:
 
 class Mark_req : public Request {
 public:
-  SCM mark_label ();
-
-
   virtual bool do_equal_b (Request const*) const;
+  SCM mark_label ();
   VIRTUAL_COPY_CONS(Music);
 };
 
@@ -84,12 +82,9 @@ public:
   the latter should only happen at the start of a measure.  */
 class Bar_req  : public Request  {
 public:
-  String type_str_;
+
   Bar_req (String);
 protected:
-  virtual bool do_equal_b (Request const*) const;
-  virtual void do_print () const;
-
   VIRTUAL_COPY_CONS(Music);
 };
 
index 57e1e228dfb0c01442fd315afee8d154f28be252..92546cee4e9b00498e9aaee9d0fdac4ebc282bdf 100644 (file)
 
 struct Directional_element_interface 
 {
-  
 public:
-  Score_element *elt_l_;
-  
-  Directional_element_interface (Score_element const *);
-  void set  (Direction d);
-  Direction get () const;
-  bool has_interface () const;
-  // bool set_interface ();
+  static SCM direction_sym ;
+  static void set  (Score_element*,Direction d);
+  static Direction get (Score_element*) ;
+  static bool has_interface (Score_element*) ;
 };
 
 
index fc3d8ae05cf708487b983d8af9d94e8dfdd17608..9e50aa0998d47ef547b9d722efb9de174e59208b 100644 (file)
@@ -27,6 +27,8 @@
 
   @see Music_sequence
 
+
+  TODO: make a equalp function for general music. 
   */
 class Music {
 public:
index f1a86dee28288426efaac213634820b00f5a60e6..b867d2119e2b5d5d53af55b19e0098bfb167ef63 100644 (file)
@@ -72,7 +72,7 @@ public:
     0 means ORPHAN,
    */
   char status_i_;
-  char const * name () const;
+  String name () const;
 
   /*
     IDEA: make this a global variable. This is the same for all
index 7735562b3dae3e9aeb15761fbe33b2eab9dabf17..579b15848499188cc571036b73a7c6ba232f36f1 100644 (file)
@@ -19,7 +19,6 @@ class Timing_translator : public virtual Translator
 {
 public:
   VIRTUAL_COPY_CONS(Translator);
-  Time_signature_change_req * time_signature_req_l () const;
   Timing_translator ();
   Link_array<Timing_req> timing_req_l_arr_;
 
@@ -31,10 +30,8 @@ protected:
   virtual void do_post_move_processing();
 
 public:
-
   Moment measure_position () const;
   Moment measure_length () const;  
   void set_time_signature (int, int);
-
 };
 #endif // TIMING_TRANSLATOR_HH
index 126c232c8d6ed9991f59fb386046d7b37dd395e7..4701c48bbb29678b0d58a4b21b0d9cfc4b41726f 100644 (file)
@@ -63,7 +63,6 @@ public:
   VIRTUAL_COPY_CONS(Translator);
   Translator_group(Translator_group const &);
   Translator_group();
-  void add_simple_translator (Translator *trans_p);
   void add_group_translator (Translator *trans_p);
 
   
@@ -75,7 +74,7 @@ public:
   void terminate_translator (Translator*r_l);
   Translator *remove_translator_p (Translator*trans_l);
   void check_removal ();
-  Translator *get_simple_translator (String) const;
+  // Translator *get_simple_translator (String) const;
   Translator_group *find_existing_translator_l (String n, String id);
   Translator_group *find_create_translator_l (String n, String id);
   Link_array<Translator_group> path_to_acceptable_translator (String alias, Music_output_def*) const;
index 2cae99cb0928efa7c90261d7decb198cc91bc921..96b11d5e1186f2a58eecaba95fb5d2ba32c07aa9 100644 (file)
@@ -136,10 +136,10 @@ Repeat_engraver::queue_events ()
        happens at the begin of the alt. The :| bar event at the ending.
       */
 
-  for (SCM s = repeated_music_l_->alternatives ()->music_list ();
-       gh_pair_p (s);  s = gh_cdr (s))
-    {
-      Music *mus =unsmob_music (gh_car (s));
+      for (SCM s = repeated_music_l_->alternatives ()->music_list ();
+          gh_pair_p (s);  s = gh_cdr (s))
+       {
+         Music *mus =unsmob_music (gh_car (s));
 
          /*
            some idiot might typeset a repeat not starting on a
@@ -164,8 +164,8 @@ Repeat_engraver::queue_events ()
              becel.append (c);
              last_number = volta_number;
              volta_number ++;
-              SCM l (get_property ("voltaSpannerDuration"));
-              if (unsmob_moment(l))
+             SCM l (get_property ("voltaSpannerDuration"));
+             if (unsmob_moment(l))
                {
                  Moment vSD_mom = *unsmob_moment (l);
                  if ( vSD_mom < mus->length_mom() ) // terminate volta early ?
@@ -185,11 +185,15 @@ Repeat_engraver::queue_events ()
        }
     }
 
-  Cons<Bar_create_event> *&tail = create_barmoments_queue_
-    ? last_cons (create_barmoments_queue_)->next_
-    : create_barmoments_queue_;
+  /*
+    ugh, should merge :| and |: here.
+   */
+  Cons<Bar_create_event> * last = last_cons (create_barmoments_queue_);
+  Cons<Bar_create_event> **tail = last?  & last->next_
+    : & create_barmoments_queue_;
 
-  tail = becel.head_ ;
+  *tail = becel.head_ ;
+  
   becel.head_ = 0;
 }
 
@@ -203,13 +207,10 @@ Repeat_engraver::do_process_music ()
     }
   
   
-  Cons<Bar_create_event> * head =   create_barmoments_queue_;
+  Cons<Bar_create_event> * head = create_barmoments_queue_;
   if (!head)
     return;
 
-  Bar_engraver* bar_engraver_l = dynamic_cast <Bar_engraver*>
-    (daddy_grav_l ()->get_simple_translator ("Bar_engraver")); // UGH
-
   /*
     Do all the events that need to be done now.
   */
@@ -217,41 +218,52 @@ Repeat_engraver::do_process_music ()
     {
       create_barmoments_queue_ = create_barmoments_queue_->next_;
       head->next_ =0;
-      if (bar_engraver_l)
+      String t = head->car_->type_;
+      if (head->car_->bar_b_)
        {
-         String t = head->car_->type_;
-         if (head->car_->bar_b_)
+         if (t == "stop" || t == ":|")
            {
-             if (t == "stop" || t == ":|")
-               {
-                 end_volta_span_p_ = volta_span_p_;
-                 volta_span_p_ =0;
-               }
-
-             if (t != "stop")
-               bar_engraver_l->request_bar (t);
-             else
-               bar_engraver_l->request_bar (""); 
+             end_volta_span_p_ = volta_span_p_;
+             volta_span_p_ =0;
            }
-         else
+
+         SCM whsym = ly_symbol2scm ("whichBar");
+         Translator_group* where = daddy_trans_l_->where_defined (whsym);
+         SCM which = where->get_property (whsym);
+
+         /*
+           Should use symbols for bar glyphs.
+         */
+         if (t == "stop" && which == SCM_UNDEFINED)
+           which = ly_str02scm ("");
+         else if (t != "stop")
            {
-             assert (!volta_span_p_);
-             volta_span_p_ = new Spanner (get_property ("basicVoltaSpannerProperties"));
-             Volta_spanner::set_interface (volta_span_p_);
-             announce_element (volta_span_p_,0);
-             volta_span_p_->set_elt_property ("text",
-                                              ly_str02scm (t.ch_C()));
-             volta_span_p_->set_elt_property ("last-volta",
-                                              gh_bool2scm (head->car_->last_b_));
-             // voltaSpannerDuration stuff here.
-             // other property stuff here.
+             SCM l = ly_str02scm (":|");
+             SCM r = ly_str02scm ("|:");                 
+                 
+             if ( (t == "|:" && scm_equal_p (which, l) == SCM_BOOL_T)
+                  || (t == ":|" && scm_equal_p (which, r)== SCM_BOOL_T))
+               t = ":|:";
+
+             if (t != "" || !gh_string_p (which))
+               which = ly_str02scm (t.ch_C());
            }
-         
+         where->set_property (whsym, which);
        }
       else
        {
-         warning (_ ("No bar engraver found.  Ignoring repeats."));
+         assert (!volta_span_p_);
+         volta_span_p_ = new Spanner (get_property ("basicVoltaSpannerProperties"));
+         Volta_spanner::set_interface (volta_span_p_);
+         announce_element (volta_span_p_,0);
+         volta_span_p_->set_elt_property ("text",
+                                          ly_str02scm (t.ch_C()));
+         volta_span_p_->set_elt_property ("last-volta",
+                                          gh_bool2scm (head->car_->last_b_));
+         // voltaSpannerDuration stuff here.
+         // other property stuff here.
        }
+         
 
       delete head->car_;
       delete head;
index 26a62293fcec8cf03c43014bc331b8a6876d3323..06a9cf70fc012540aadb6d01d01570626e8b7c37 100644 (file)
@@ -629,10 +629,12 @@ Score_element::common_refpoint (SCM elist, Axis a) const
   return common;
 }
 
-char const *
+String
 Score_element::name () const
 {
-  return classname (this);
+  SCM nm = get_elt_property ("name");
+  
+  return  nm == SCM_EOL ? classname (this) :ly_scm2string (nm) ;  
 }
 
 void
@@ -749,7 +751,7 @@ Score_element::print_smob (SCM s, SCM port, scm_print_state *)
   Score_element *sc = (Score_element *) gh_cdr (s);
      
   scm_puts ("#<Score_element ", port);
-  scm_puts ((char *)sc->name (), port);
+  scm_puts ((char *)sc->name ().ch_C(), port);
 
   /*
     don't try to print properties, that is too much hassle.
index 80ad78157a8fea3c180ebaf92b7911a18b58faad..2cbeafd1eb7b9c89a265d00f008bb2ccf65b9137 100644 (file)
@@ -148,7 +148,7 @@ Score_engraver::typeset_all()
            if (!s->get_bound (d))
              {
                s->set_bound(d, command_column_l_);
-               ::warning (_f ("unbound spanner `%s'", classname(s)));
+               ::warning (_f ("unbound spanner `%s'", s->name().ch_C()));
              }
          } while (flip(&d) != LEFT);
        }
index e0082e84b0c971c702d3404388bc8863f7c6a293..628af83903ec87c95e267dad2692798f5cd35a4a 100644 (file)
@@ -106,5 +106,5 @@ Separating_group_spanner::add_spacing_unit (Score_element* me ,Item*i)
 void
 Separating_group_spanner::set_interface (Score_element*me)
 {
-  me->set_elt_property ("elements", SCM_EOL);
+
 }
index e59f5fdf0362bedc9272accfa81fcb674dd5bfb1..5be17a25d6bc12d845283bd18be40b4bb52cd8ab 100644 (file)
@@ -122,8 +122,8 @@ Slur::after_line_breaking (SCM smob)
 void
 Slur::set_extremities (Score_element*me)
 {
-  if (!Directional_element_interface (me).get ())
-    Directional_element_interface (me).set (get_default_dir (me));
+  if (!Directional_element_interface::get (me))
+    Directional_element_interface ::set (me,get_default_dir (me));
 
   Direction dir = LEFT;
   do 
@@ -234,12 +234,12 @@ Slur::get_attachment (Score_element*me,Direction dir,
          if (str == "head")
            {
              o = Offset (0, Stem::head_positions (stem)
-                         [Directional_element_interface (me).get ()] * hs);
+                         [Directional_element_interface::get (me)] * hs);
              /*
                Default position is centered in X, on outer side of head Y
               */
              o += Offset (0.5 * n->extent (X_AXIS).length (),
-                          0.5 * ss * Directional_element_interface (me).get ());
+                          0.5 * ss * Directional_element_interface::get (me));
            }
          else if (str == "alongside-stem")
            {
@@ -249,7 +249,7 @@ Slur::get_attachment (Score_element*me,Direction dir,
               */
              o += Offset (n->extent (X_AXIS).length ()
                           * (1 + Stem::get_direction (stem)),
-                          0.5 * ss * Directional_element_interface (me).get ());
+                          0.5 * ss * Directional_element_interface::get (me));
            }
          else if (str == "stem")
            {
@@ -287,7 +287,7 @@ Slur::get_attachment (Score_element*me,Direction dir,
   SCM l = scm_assoc
     (scm_listify (a,
                  gh_int2scm (stem ? Stem::get_direction (stem) : 1 * dir),
-                 gh_int2scm (Directional_element_interface (me).get () * dir),
+                 gh_int2scm (Directional_element_interface::get (me) * dir),
                  SCM_UNDEFINED),
      scm_eval2 (ly_symbol2scm ("slur-extremity-offset-alist"), SCM_EOL));
   
@@ -317,7 +317,7 @@ Slur::encompass_offset (Score_element*me,
   Offset o;
   Score_element* stem_l = unsmob_element (col->get_elt_property ("stem"));
   
-  Direction dir = Directional_element_interface (me).get ();
+  Direction dir = Directional_element_interface::get (me);
   
   if (!stem_l)
     {
@@ -326,7 +326,7 @@ Slur::encompass_offset (Score_element*me,
       o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS);
       return o;  
     }
-  Direction stem_dir = Directional_element_interface (stem_l).get ();
+  Direction stem_dir = Directional_element_interface::get (stem_l);
   o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS);
 
   /*
@@ -467,7 +467,7 @@ Slur::brew_molecule (SCM smob)
   if (gh_number_p (d))
     a = me->lookup_l ()->dashed_slur (one, thick, thick * gh_scm2double (d));
   else
-    a = me->lookup_l ()->slur (one, Directional_element_interface (me).get () * thick, thick);
+    a = me->lookup_l ()->slur (one, Directional_element_interface::get (me) * thick, thick);
 
   return a.create_scheme();
 }
@@ -481,7 +481,7 @@ Slur::set_control_points (Score_element*me)
   Real r_0 = me->paper_l ()->get_var ("slur_ratio");
   
   Slur_bezier_bow bb (get_encompass_offset_arr (me),
-                     Directional_element_interface (me).get (),
+                     Directional_element_interface::get (me),
                      h_inf, r_0);
 
   if (bb.fit_factor () > 1.0)
@@ -530,7 +530,7 @@ Slur::get_curve (Score_element*me)
   Bezier b;
   int i = 0;
 
-  if (!Directional_element_interface (me).get ()
+  if (!Directional_element_interface::get (me)
       || ! gh_symbol_p (index_cell (me->get_elt_property ("attachment"), LEFT)))
     set_extremities (me);
   
@@ -544,7 +544,7 @@ Slur::get_curve (Score_element*me)
     }
 
   Array<Offset> enc (get_encompass_offset_arr (me));
-  Direction dir = Directional_element_interface (me).get ();
+  Direction dir = Directional_element_interface::get (me);
   
   Real x1 = enc[0][X_AXIS];
   Real x2 = enc.top ()[X_AXIS];
index 3328d266369c0eae3a688849a98d37d249d9ca5d..131f19e5afc1c4e7288fcd69c54b70f432c3d1c3 100644 (file)
@@ -41,8 +41,8 @@ Spanner::do_break_processing ()
          if (!parent->spanned_rank_iv ().contains_b (this->spanned_rank_iv ()))
            {
              programming_error (to_str ("Spanner `%s' is not fully contained in parent spanner `%s'.",
-                                        classname (this),
-                                        classname (parent)));
+                                        name().ch_C(),
+                                        parent->name ().ch_C ()));
            }
        }
     }
index fc0ed1023f31f51ff49c0c2eacfb60344a46e430..e52df9fd05dda4888bd0f73f0cbc1bfdb665f9f5 100644 (file)
@@ -95,7 +95,7 @@ Stem_tremolo::brew_molecule (SCM smob)
       int beams_i = Stem::beam_count(stem, RIGHT) >? Stem::beam_count (stem, LEFT);
       mol.translate (Offset(stem->relative_coordinate (0, X_AXIS) - me->relative_coordinate (0, X_AXIS),
                            Stem::stem_end_position (stem ) * ss / 2 - 
-                           Directional_element_interface (beam).get () * beams_i * interbeam_f));
+                           Directional_element_interface::get (beam) * beams_i * interbeam_f));
     }
   else
     {  
index 36f9c467933e0339f19de4f153b66890da4d50de..b64f89bafacbf81b40311789b1855ab428700ef2 100644 (file)
@@ -94,13 +94,13 @@ Stem::stem_end_position (Score_element*me)
 Direction
 Stem::get_direction (Score_element*me)
 {
-  Direction d = Directional_element_interface (me).get ();
+  Direction d = Directional_element_interface::get (me);
 
   if (!d)
     {
        d = get_default_dir (me);
        // urg, AAARGH!
-       Directional_element_interface (me).set (d);
+       Directional_element_interface::set (me, d);
     }
   return d ;
 }
@@ -289,7 +289,7 @@ Stem::get_default_stem_end_position (Score_element*me)
   if (!dir)
     {
       dir = get_default_dir (me);
-      Directional_element_interface (me).set (dir);
+      Directional_element_interface::set (me, dir);
     }
   
   /* 
@@ -522,7 +522,7 @@ Stem::calc_stem_info (Score_element*me)
 {
   Score_element * beam = beam_l (me);
 
-  Direction beam_dir = Directional_element_interface (beam).get ();
+  Direction beam_dir = Directional_element_interface::get (beam);
   if (!beam_dir)
     {
       programming_error ("Beam dir not set.");
@@ -565,7 +565,7 @@ Stem::calc_stem_info (Score_element*me)
 
   Real stem_length =  a[multiplicity <? (a.size () - 1)] * staff_space;
 
-  if (!beam_dir || (beam_dir == Directional_element_interface (me).get ()))
+  if (!beam_dir || (beam_dir == Directional_element_interface::get (me)))
     /* normal beamed stem */
     {
       if (multiplicity)
index 346fa9992e0af2d23d664a84686408729c8d0380..257885be9e9d59c8af1d599a7a38d9c4bdd64a1e 100644 (file)
@@ -68,14 +68,14 @@ Tie_column::set_directions (Score_element*me)
     Pointer_group_interface__extract_elements (me, (Score_element*)0, "ties");
 
 
-  Direction d = Directional_element_interface (me).get ();
+  Direction d = Directional_element_interface::get (me);
 
   if (d)
     {
       for (int i = ties.size (); i--;)
        {
          Score_element *  t = ties[i];
-         Directional_element_interface (t).set (d);
+         Directional_element_interface::set (t, d);
        }
       return;
     }
@@ -83,18 +83,15 @@ Tie_column::set_directions (Score_element*me)
   if (ties.size () == 1)
     {
       Score_element *  t = ties[0];      
-      Directional_element_interface (t).set (Tie::get_default_dir (t));
+      Directional_element_interface::set (t,Tie::get_default_dir (t));
       return;
     }
   
   ties.sort (tie_compare);
-  Directional_element_interface tie0(ties[0]);
-  tie0.set (DOWN);
+  Directional_element_interface::set( ties[0], DOWN);
   ties.del (0);
   
-  Directional_element_interface tietop(ties.pop ());
-  tietop.set (UP);
-
+  Directional_element_interface ::set(ties.pop (), UP);
   for (int i=ties.size(); i--; )
     {
       Score_element *  t = ties[i];
@@ -102,7 +99,7 @@ Tie_column::set_directions (Score_element*me)
       Direction d = (Direction) sign (p);
       if (!d)
        d = UP;
-      Directional_element_interface (t).set (d);
+      Directional_element_interface::set (t, d);
     }
   
 }
index 9c7b70ff33dc8aba2b19d3909e092f4b04a024d2..0ce6fbd98374ecf14e916c1e3080d8632ee37e64 100644 (file)
@@ -88,14 +88,14 @@ Tie::get_default_dir (Score_element*me)
 
   if (sl && sr)
     {
-      if (Directional_element_interface (sl).get () == UP
-         && Directional_element_interface (sr).get () == UP)
+      if (Directional_element_interface::get (sl) == UP
+         && Directional_element_interface::get (sr) == UP)
        return DOWN;
     }
   else if (sl || sr)
     {
       Item *s = sl ? sl : sr;
-      return - Directional_element_interface (s). get ();
+      return - Directional_element_interface::get (s);
     }
 
   
@@ -119,8 +119,8 @@ Tie::get_control_points (SCM smob)
       return SCM_UNSPECIFIED;
     }
   
-  if (!Directional_element_interface (me).get ())
-    Directional_element_interface (me).set (Tie::get_default_dir (me));
+  if (!Directional_element_interface::get (me))
+    Directional_element_interface::set (me, Tie::get_default_dir (me));
   
   Real staff_space = Staff_symbol_referencer::staff_space (me);
 
@@ -163,7 +163,7 @@ Tie::get_control_points (SCM smob)
          - 2 * x_gap_f;
     }
   
-  Direction dir = Directional_element_interface (me).get();
+  Direction dir = Directional_element_interface::get(me);
   
   Real h_inf = me->paper_l ()->get_var ("tie_height_limit_factor") * staff_space;
   Real r_0 = me->paper_l ()->get_var ("tie_ratio");
@@ -290,7 +290,7 @@ Tie::brew_molecule (SCM smob)
       i++;
     }
   
-   Molecule a = me->lookup_l ()->slur (b, Directional_element_interface (me).get () * thick, thick);
+   Molecule a = me->lookup_l ()->slur (b, Directional_element_interface::get (me) * thick, thick);
    
    return a.create_scheme ();
 }
index ab453e5a45d3fa0bf34009d9e84fafd237955e6c..430a9939bc06ce60475a7c59cb10be0f27619d48 100644 (file)
@@ -44,20 +44,6 @@ Timing_translator::do_try_music (Music*r)
     }
   return false;
 }
-
-/*ugh.
- */
-Time_signature_change_req*
-Timing_translator::time_signature_req_l() const
-{
-  Time_signature_change_req *m_l=0;
-  for (int i=0; !m_l && i < timing_req_l_arr_.size (); i++)
-    {
-      m_l=dynamic_cast<Time_signature_change_req*> (timing_req_l_arr_[i]);
-    }
-  return m_l;
-}
-
 void
 Timing_translator::do_process_music()
 {
@@ -127,6 +113,8 @@ Timing_translator::do_creation_processing()
   daddy_trans_l_->set_property ("measurePosition", m.make_scm ());
   daddy_trans_l_->set_property ("beatLength", Moment (1,4).make_scm ());
   daddy_trans_l_->set_property ("measureLength",  Moment (1).make_scm());
+  daddy_trans_l_->set_property ("timeSignatureFraction",
+                               gh_cons (gh_int2scm (4), gh_int2scm (4)));
 }
 
 Moment
@@ -147,6 +135,8 @@ Timing_translator::set_time_signature (int l, int o)
   Moment len = Moment (l) * one_beat;
   daddy_trans_l_->set_property ("measureLength", len.make_scm ());
   daddy_trans_l_->set_property ("beatLength", one_beat.make_scm ());
+  daddy_trans_l_->set_property ("timeSignatureFraction",
+                               gh_cons (gh_int2scm (l), gh_int2scm (o)));
 }
 
 Timing_translator::Timing_translator()
index d2b7c83a04dbcd637bdf31ac8ab7759d81a9ed23..74cee77b61d95d1368b12c81c0b095da68ac915e 100644 (file)
@@ -73,11 +73,6 @@ Translator_group::add_translator (SCM list, Translator *t)
   return list;
 }
 void
-Translator_group::add_simple_translator (Translator*t)
-{
-  simple_trans_list_ = add_translator (simple_trans_list_, t);
-}
-void
 Translator_group::add_group_translator (Translator *t)
 {
   trans_group_list_ = add_translator (trans_group_list_,t);
@@ -247,7 +242,10 @@ Translator_group::remove_translator_p (Translator*trans_l)
   return trans_l;
 }
 
-
+#if 0
+/*
+  should not use, instead: use properties to communicate between engravers.
+ */
 Translator*
 Translator_group::get_simple_translator (String type) const
 {
@@ -260,7 +258,7 @@ Translator_group::get_simple_translator (String type) const
     return daddy_trans_l_->get_simple_translator (type);
   return 0;
 }
-
+#endif 
 
 bool
 Translator_group::is_bottom_translator_b () const
index a86a222c8488f2ab4b79e73287f3b716b23482e8..a74e155f0f05d7921e97188453c0598502ce32e3 100644 (file)
@@ -73,7 +73,7 @@ Tuplet_spanner::brew_molecule (SCM smob)
       Real w = dynamic_cast<Spanner*>(me)->spanner_length () + ncw;
 
       Real staff_space = me->paper_l ()->get_var ("interline");
-      Direction dir = Directional_element_interface (me).get ();
+      Direction dir = Directional_element_interface::get (me);
       Real dy = gh_scm2double (me->get_elt_property ("delta-y"));
       SCM number = me->get_elt_property ("text");
       if (gh_string_p (number) && number_visibility)
@@ -131,7 +131,7 @@ Tuplet_spanner::calc_position_and_height (Score_element*me,Real *offset, Real *
   Score_element * commony = me->common_refpoint (me->get_elt_property ("columns"), Y_AXIS);
   Score_element * commonx = me->common_refpoint (me->get_elt_property ("columns"), X_AXIS);  
   
-  Direction d = Directional_element_interface (me).get ();
+  Direction d = Directional_element_interface::get (me);
 
   /*
     Use outer non-rest columns to determine slope
@@ -186,7 +186,7 @@ Tuplet_spanner::calc_dy (Score_element*me,Real * dy)
   Link_array<Score_element> column_arr=
     Pointer_group_interface__extract_elements (me, (Score_element*)0, "columns");
  
-  Direction d = Directional_element_interface (me).get ();
+  Direction d = Directional_element_interface::get (me);
   *dy = column_arr.top ()->extent (Y_AXIS) [d]
     - column_arr[0]->extent (Y_AXIS) [d];
 }
@@ -207,11 +207,11 @@ Tuplet_spanner::after_line_breaking (SCM smob)
       return SCM_UNSPECIFIED;
     }
 
-  Direction d = Directional_element_interface (me).get ();
+  Direction d = Directional_element_interface::get (me);
   if (!d)
     {
       d = Tuplet_spanner::get_default_dir (me);
-      Directional_element_interface (me).set (d);
+      Directional_element_interface::set (me, d);
 
     }
   Real dy, offset;
index 295e1665aed78cf0749f8295a43936c5af02e4a6..7e738429893b004adaa029ba74fc6f6d2933bcfe 100644 (file)
@@ -24,7 +24,7 @@ Volta_spanner::set_interface (Score_element*me)
 {
   me->set_elt_property ("bars", SCM_EOL);
   Side_position::set_axis (me, Y_AXIS);
-  Directional_element_interface (me).set (UP);
+  Directional_element_interface::set (me, UP);
 }
 
 
index b194f285614f32fc5446ae567a6e5e5473550f00..1835fd340be29a25cf771c6152ff2c5ec6cf7c0c 100644 (file)
 #  * slurs
 #  * lyrics
 #  * articulation
-# 
+#  * grace notes
+#  * tuplets
+
 
 # todo:
-#  * automatic PC/mac/unix conversion
 #  * slur/stem directions
 #  * voices (2nd half of frame?)
 #  * more intelligent lyrics
 #  * beams (better use autobeam?)
-#  * more robust: try entertainer.etf (freenote), schubert ave maria (gmd)
+#  * more robust: try entertainer.etf (freenote)
+#  * dynamics
+#
 
 program_name = 'etf2ly'
 version = '@TOPLEVEL_VERSION@'
@@ -142,6 +145,44 @@ def lily_notename (tuple2):
        return nn
 
 
+class Tuplet:
+       def __init__ (self, number):
+               self.start_note = number
+               self.finale = []
+
+       def append_finale (self, fin):
+               self.finale.append (fin)
+
+       def factor (self):
+               n = self.finale[0][2]*self.finale[0][3]
+               d = self.finale[0][0]*self.finale[0][1]
+               return rat_simplify( (n, d))
+       
+       def dump_start (self):
+               return '\\times %d/%d { ' % self.factor ()
+       
+       def dump_end (self):
+               return ' }'
+
+       def calculate (self, chords):
+               edu_left = self.finale[0][0] * self.finale[0][1]
+
+               startch = chords[self.start_note]
+               c = startch
+               while c and edu_left:
+                       c.tuplet = self
+                       if c == startch:
+                               c.chord_prefix = self.dump_start () + c.chord_prefix 
+
+                       if not c.grace:
+                               edu_left = edu_left - c.EDU_duration ()
+                       if edu_left == 0:
+                               c.chord_suffix = c.chord_suffix+ self.dump_end ()
+                       c = c.next
+
+               if edu_left:
+                       sys.stderr.write ("\nHuh? Tuplet starting at entry %d was too short." % self.start_note)
+               
 class Slur:
        def __init__ (self, number):
                self.number = number
@@ -163,8 +204,7 @@ class Slur:
                        cs.note_suffix = '(' + cs.note_suffix 
                        ce.note_prefix = ce.note_prefix + ')'
                except IndexError:
-                       sys.stderr.write ("""\nHuh? Incorrect slur start/endpoint
-len(list) is %d, start/end is (%d,%d)\n""" % (len (chords), startnote, endnote))
+                       sys.stderr.write ("""\nHuh? Slur no %d between (%d,%d), with %d notes""" % (self.number,  startnote, endnote, len (chords)))
                                         
                
 class Global_measure:
@@ -198,6 +238,9 @@ articulation_dict ={
        11: '\\prall',
        12: '\\mordent',
        8: '\\fermata',
+       4: '^',
+       1: '.',
+       3: '>',
        18: '"arp"' , # arpeggio
 };
 
@@ -211,6 +254,7 @@ class Articulation:
                try:
                        a = articulation_dict[self.type]
                except KeyError:
+                       sys.stderr.write ("\nUnknown articulation no. %d on note no. %d" % (self.type, self.notenumber))
                        a = '"art"'
                        
                c.note_suffix = '-' + a + c.note_suffix
@@ -299,22 +343,43 @@ class Frame:
        def set_measure (self, m):
                self.measure = m
 
+       def calculate (self):
+
+               # do grace notes.
+               lastch = None
+               for c in self.chords:
+                       if c.grace and (lastch == None or (not lastch.grace)):
+                               c.chord_prefix = r'\grace {' + c.chord_prefix
+                       elif not c.grace and lastch and lastch.grace:
+                               lastch.chord_suffix = lastch.chord_suffix + ' } '
+
+                       lastch = c
+                       
+
+               
        def dump (self):
-               str = ''
+               str = '%% FR(%d)\n' % self.number
                left = self.measure.global_measure.length ()
+
+               
+               ln = ''
                for c in self.chords:
-                       str = str + c.ly_string () + ' '
+                       add = c.ly_string () + ' '
+                       if len (ln) + len(add) > 72:
+                               str = str + ln + '\n'
+                               ln = ''
+                       ln = ln + add
                        left = rat_subtract (left, c.length ())
-                       
+
+               str = str + ln 
+               
                if left[0] < 0:
-                       sys.stderr.write ("""Huh? Going backwards.
-Frame no %d, start/end (%d,%d)
-""" % (self.number, self.start, self.end))
+                       sys.stderr.write ("""\nHuh? Going backwards in frame no %d, start/end (%d,%d)""" % (self.number, self.start, self.end))
                        left = (0,1)
                if left[0]:
-                       str = str + 's*%d/%d' % left
-                       
-               str = str + '\n'
+                       str = str + rat_to_lily_duration (left)
+
+               str = str + '  | \n'
                return str
                
 def encodeint (i):
@@ -364,7 +429,7 @@ class Staff:
                                last_clef = m.clef
                        if e:
                                if gap <> (0,1):
-                                       k = k +' s1*%d/%d \n ' % gap
+                                       k = k +' ' + rat_to_lily_duration (gap) + '\n'
                                gap = (0,1)
                                k = k + e
                        
@@ -393,7 +458,7 @@ class Staff:
                                if fr:
                                        first_frame = fr
                                        if gap <> (0,1):
-                                               laystr = laystr +'} s1*%d/%d {\n ' % gap
+                                               laystr = laystr +'} %s {\n ' % rat_to_lily_duration (gap)
                                                gap = (0,1)
                                        laystr = laystr + fr.dump ()
                                else:
@@ -431,6 +496,23 @@ def EDU_to_duration (edu):
                dots = 2
        return (log, dots)      
 
+def rat_to_lily_duration (rat):
+       (n,d) = rat
+
+       basedur = 1
+       while d and  d % 2 == 0:
+               basedur = basedur << 1
+               d = d >> 1
+
+       str = 's%d' % basedur
+       if n <> 1:
+               str = str + '*%d' % n
+       if d <> 1:
+               str = str + '/%d' % d
+
+       return str
+               
+
 class Chord:
        def __init__ (self, finale_entry):
                self.pitches = []
@@ -443,6 +525,8 @@ class Chord:
                self.note_suffix = ''
                self.chord_suffix = ''
                self.chord_prefix = ''
+               self.tuplet = None
+               self.grace = 0
                
        def measure (self):
                if not self.frame:
@@ -450,19 +534,36 @@ class Chord:
                return self.frame.measure
 
        def length (self):
+               if self.grace:
+                       return (0,1)
+               
                l = (1, self.duration[0])
 
                d = 1 << self.duration[1]
 
                dotfact = rat_subtract ((2,1), (1,d))
-               return rat_multiply (dotfact, l)
+               mylen =  rat_multiply (dotfact, l)
+
+               if self.tuplet:
+                       mylen = rat_multiply (mylen, self.tuplet.factor())
+               return mylen
                
        def number (self):
                return self.finale[0][0]
+
+       def EDU_duration (self):
+               return self.finale[0][3]
        def set_duration (self):
-               ((no, prev, next, dur, pos, entryflag, extended, follow),
-                notelist) = self.finale
-               self.duration = EDU_to_duration(dur)
+               self.duration = EDU_to_duration(self.EDU_duration ())
+       def calculate (self):
+               self.find_realpitch ()
+               self.set_duration ()
+
+               flag = self.finale[0][5]
+               if Chord.GRACE_MASK & flag:
+                       self.grace = 1
+               
+               
        def find_realpitch (self):
                
                ((no, prev, next, dur, pos, entryflag, extended, follow), notelist) = self.finale
@@ -493,6 +594,8 @@ class Chord:
                
        REST_MASK = 0x40000000L
        TIE_START_MASK = 0x40000000L
+       GRACE_MASK = 0x00800000L
+       
        def ly_string (self):
                s = ''
 
@@ -541,12 +644,16 @@ IMre = re.compile (r"""^\^IM\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+
 vere = re.compile(r"""^\^(ve|ch|se)\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
 versere = re.compile(r"""^\^verse\(([0-9]+)\)(.*)\^end""")
 
+TPre = re.compile(r"""^\^TP\(([0-9]+),([0-9]+)\) *([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
+
+
 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.slurs = [None]
                self.articulations = [None]
@@ -585,7 +692,17 @@ class Etf_file:
                        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:
@@ -627,7 +744,7 @@ class Etf_file:
 
                        entryflag = string.atol (entryflag,16)
                        if no > len (self.entries):
-                               sys.stderr.write ("Huh? Entry number to large,\nexpected %d got %d. Filling with void entries.\n" % (len(self.entries), no  ))
+                               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)
@@ -722,6 +839,8 @@ class Etf_file:
                                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)
 
@@ -759,8 +878,13 @@ class Etf_file:
                                mno = mno + 1
 
                for c in self.chords[1:]:
-                       c.find_realpitch ()
-                       c.set_duration ()
+                       c.calculate()
+
+               for f in self.frames[1:]:
+                       f.calculate ()
+                       
+               for t in self.tuplets[1:]:
+                       t.calculate (self.chords)
                        
                for s in self.slurs [1:]:
                        s.calculate (self.chords)
@@ -788,8 +912,6 @@ class Etf_file:
                                str = str + '\n\n' + s.dump () 
                                staffs.append ('\\' + s.staffid ())
 
-               if staffs:
-                       str = str + '\\score { < %s > } ' % string.join (staffs)
 
                # should use \addlyrics ?
 
@@ -799,6 +921,9 @@ class Etf_file:
                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