]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.5.17
authorfred <fred>
Wed, 27 Mar 2002 02:03:39 +0000 (02:03 +0000)
committerfred <fred>
Wed, 27 Mar 2002 02:03:39 +0000 (02:03 +0000)
35 files changed:
CHANGES
flower/include/rational.hh
flower/rational.cc
input/bugs/cross-staff-tie.ly [new file with mode: 0644]
input/bugs/knee.ly [new file with mode: 0644]
input/template/piano-dynamics.ly [new file with mode: 0644]
lily/duration.cc
lily/font-metric.cc
lily/grob.cc
lily/include/duration.hh
lily/include/font-metric.hh
lily/include/grob.hh
lily/include/input-smob.hh
lily/include/ly-smobs.icc
lily/include/lyric-phrasing-engraver.hh
lily/include/molecule.hh
lily/include/moment.hh
lily/include/music-output-def.hh
lily/include/music.hh
lily/include/pitch.hh
lily/include/score.hh
lily/include/smobs.hh
lily/include/translator-def.hh
lily/include/translator.hh
lily/molecule.cc
lily/moment.cc
lily/music-output-def.cc
lily/music.cc
lily/pitch.cc
lily/scm-hash.cc
lily/score.cc
lily/syllable-group.cc
lily/translator-def.cc
lily/translator.cc
scripts/midi2ly.py

diff --git a/CHANGES b/CHANGES
index 7eac9d8357a07205359188d7b0624a076893fd33..f2983b1216e6ab30f084b07f0fabe2ee7ace651d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,32 @@
+1.5.16.hjj2
+===========
+
+* Emacs-mode: Inserting tags
+
+* Enable python2.1/Python.h
+
+1.5.16.hwn1
+===========
+
+* Add unfold-repeats function (Rune Zedeler!) to standard init SCM file.
+
+* Bugfix: spacing is no longer confused by coupled clefs, where one of the
+clefs is loose, and the other not.
+
+* Robustness fix for Slur. Don't crash if attachment not set.
+
+* Arpeggios can now have arrows on the top or bottom to determine
+their direction. (MF code by Chris Jackson)
+
+* Symbol cache bugfix in system-start-delimiter.cc -- may switch
+symbol cache off for gcc 2.96?
+
+* MikTeX PDF detection bugfix (Mats Bengtsson)
+
+* Some more random hacking at midi2ly.py. (jcn1)
+
+* Inline unsmob_XXX functions.  Speedup of 6% on wtk1-fugue2.
+
 1.5.15.jcn1
 ===========
 
index 995700c55c32e2ce513f82d653e17a9ea904cd3e..9373b484489eea9a1356969e75eeddf66d68c456 100644 (file)
@@ -59,8 +59,10 @@ public:
   Rational (int, int);
   Rational (double);
   Rational (Rational const&r) {   copy (r);}
+  Rational &operator = (Rational const &r) {
+    copy (r); return *this;
+  }
 
-  Rational &operator = (Rational const &);
   Rational &operator *= (Rational);
   Rational &operator /= (Rational);  
   Rational &operator += (Rational);
index b2b7c898ee5f2a4491194c05d558e2d593c3f2e0..42e0c0a97c2025424a4ec17686684f899e01b4f1 100644 (file)
@@ -271,16 +271,6 @@ Rational::operator -= (Rational r)
   return (*this += r);
 }
 
-/*
-  be paranoid about overiding libg++ stuff
- */
-Rational &
-Rational::operator = (Rational const &r)
-{
-  copy (r);
-  return *this;
-}
-
 String
 Rational::str () const
 {
diff --git a/input/bugs/cross-staff-tie.ly b/input/bugs/cross-staff-tie.ly
new file mode 100644 (file)
index 0000000..7dca649
--- /dev/null
@@ -0,0 +1,18 @@
+
+
+
+\version "1.4.8"
+\score { \notes
+  \context PianoStaff <
+         \context Staff = up { \clef G
+      c'2 ~ \translator Staff=down c'
+    }
+    \context Staff = down { \clef F
+      s1
+    }
+  >
+  \paper { }
+}
+
+
+
diff --git a/input/bugs/knee.ly b/input/bugs/knee.ly
new file mode 100644 (file)
index 0000000..4f90edf
--- /dev/null
@@ -0,0 +1,40 @@
+\header {
+
+texidoc="
+gives
+
+@example
+      |    |
+      |    |
+ +--  |  --+
+ +----+----+
+ |
+ |
+
+instead of the desired
+
+      |    |
+      |    |
+      |  --+
+ +----+----+
+ +--
+ |
+ |
+
+@end example
+"
+
+}
+
+\score {
+  \notes\relative c' {
+     c16 c''8 c16
+     
+     % it's very helpful to have this one too,
+     % because a fix is likely to break
+
+     c,, c'' c,, cc
+  }
+  \paper { linewidth = -1 }
+}
+         
\ No newline at end of file
diff --git a/input/template/piano-dynamics.ly b/input/template/piano-dynamics.ly
new file mode 100644 (file)
index 0000000..59a0a08
--- /dev/null
@@ -0,0 +1,96 @@
+\version "1.5.1"
+
+\header {
+  dedication = "dedication"
+  title = "Title"
+  subtitle = "Subtitle"
+  subsubtitle = "Subsubtitle"
+  composer = "Composer (xxxx-yyyy)"
+  opus = "Opus 0"
+  piece = "Piece I"
+  instrument = "Instrument"
+  arranger = "Arranger"
+  poet = "Poet"
+  texttranslator = "Translator"
+  copyright = "public domain"
+  enteredby = "jcn"
+  source =  "urtext"
+}
+
+upper = \notes\relative c'' {
+  a b c d
+}
+
+lower = \notes\relative c {
+  a2 c
+}
+
+dynamics = \notes {
+  \outputproperty #(make-type-checker 'dynamic-interface)
+    #'extra-offset = #'(0 . 2.5)
+  s2\fff\> s4
+  \outputproperty #(make-type-checker 'dynamic-interface)
+    #'extra-offset = #'(0 . 2.5)
+  \!s\pp
+}
+
+pedal = \notes {
+ s2\sustainDown s2\sustainUp
+}
+
+\score {
+  \context PianoStaff <
+    \context Staff=upper \upper
+    \context Dynamics=dynamics \dynamics
+    \context Staff=lower <
+      \clef bass
+      \lower
+    >
+    \context Dynamics=pedal \pedal
+  >
+  \paper {
+    \translator {
+      \type "Engraver_group_engraver"
+      \name Dynamics
+      \consists "Output_property_engraver"
+      Generic_property_list = #generic-voice-properties
+      \consists "Property_engraver"
+      MinimumVerticalExtent = #'(-1 . 1)
+
+      pedalSustainStrings = #'("Ped." "*Ped." "*")
+      pedalUnaCordaStrings = #'("una corda" "" "tre corde")
+      
+      \consists "Piano_pedal_engraver"
+      \consists "Script_engraver"
+      \consists "Dynamic_engraver"
+      \consists "Text_engraver"
+
+      TextScript \override #'font-relative-size = #1
+      TextScript \override #'font-shape = #'italic
+
+      \consists "Skip_req_swallow_translator"
+
+      \consistsend "Axis_group_engraver"
+    }
+    \translator {
+      \PianoStaffContext
+      \accepts Dynamics
+      VerticalAlignment \override #'forced-distance = #7
+    }
+  }
+  \midi {
+    \translator {
+      \type "Performer_group_performer"
+      \name Dynamics
+      Generic_property_list = #generic-voice-properties
+
+      \consists "Piano_pedal_performer"
+      \consists "Span_dynamic_performer"
+      \consists "Dynamic_performer"
+    }
+    \translator {
+      \PianoStaffContext
+      \accepts Dynamics
+    }
+  }
+}
index 6476466774e51a8398660487d654f19361705e4c..f6ffb9145bc92320585cf8dd694309a69159362d 100644 (file)
@@ -80,7 +80,6 @@ Duration::str () const
 
 
 IMPLEMENT_TYPE_P (Duration, "duration?");
-IMPLEMENT_UNSMOB (Duration, duration);
 
 SCM
 Duration::mark_smob (SCM)
index d22da509eeb5a8a6a81e90d1db65a350bb91d864..0fcf96fc11782432fab276f86a2b6d76ff01c24b 100644 (file)
@@ -121,7 +121,7 @@ Font_metric::print_smob (SCM s, SCM port, scm_print_state *)
 }
 
 
-IMPLEMENT_UNSMOB (Font_metric, metrics);
+
 IMPLEMENT_SMOBS (Font_metric);
 IMPLEMENT_DEFAULT_EQUAL_P (Font_metric);
 IMPLEMENT_TYPE_P (Font_metric, "font-metric?");
index 82b177151687b8801711902640c013e311168895..f55ee2f8e257b73fe4ac3b41ae317a9a0a8e4f4e 100644 (file)
@@ -141,7 +141,7 @@ Grob::get_grob_property (SCM sym) const
 
 /*
   Remove the value associated with KEY, and return it. The result is
-  that a next call will yield SCM_UNDEFINED (and not the underlying
+  that a next call will yield SCM_EOL (and not the underlying
   `basic' property.
 */
 SCM
@@ -768,7 +768,7 @@ Grob::fixup_refpoint (SCM smob)
  ****************************************************/
 
 
-IMPLEMENT_UNSMOB (Grob, grob);
+
 IMPLEMENT_SMOBS (Grob);
 IMPLEMENT_DEFAULT_EQUAL_P (Grob);
 
index bdb988a1c3c3bb8c4e13f6058cfc834a95665250..7324349fdc1e75d45b050bb6f679945912bf11e8 100644 (file)
@@ -45,7 +45,7 @@ private:
 
 #include "compare.hh"
 INSTANTIATE_COMPARE (Duration, Duration::compare);
-Duration*unsmob_duration (SCM);
+DECLARE_UNSMOB(Duration,duration);
 // int compare (Array<Duration>*, Array<Duration>*);
 
 #endif // DURATION_HH
index 87137221c3cf547a4f1592b124ac4d29806924ef..d3ae05da69a3cc15b017642e7d4eee459443cdc6 100644 (file)
@@ -34,7 +34,7 @@ protected:
   Font_metric ();
 };
 
-Font_metric * unsmob_metrics (SCM s);
+DECLARE_UNSMOB(Font_metric, metrics);
 
 #endif /* FONT_METRIC_HH */
 
index e1820f9d07985580014ece3c681ed4edc651eefe..0cabf6e0e1957cca192dd9b9898bb6c8a427225a 100644 (file)
@@ -174,7 +174,7 @@ public:
   DECLARE_SCHEME_CALLBACK (fixup_refpoint, (SCM));
 };
 
-Grob * unsmob_grob (SCM);
+DECLARE_UNSMOB(Grob,grob);
 
 #endif // STAFFELEM_HH
 
index 2cd9462d5dc14e4315b6b91e54b31c9219b427a6..c38c240edf11a8cebf3ae65a3fdd1468080ed240 100644 (file)
 
 #include "input.hh"
 #include "lily-guile.hh"
+#include "smobs.hh"
 
 SCM make_input (Input spot);
-Input *unsmob_input (SCM);
+Input *unsmob_input(SCM);
 
 extern Input dummy_input_global;
 
index 69c7d2ecfe633c5da76a089fe6cff73b838d1594..f5b8f62c10849711af81da720f10722bfb34e5e3 100644 (file)
 #include "smobs.hh"
 
 
-#define IMPLEMENT_UNSMOB(CL, name)             \
-CL *                                           \
-unsmob_ ## name ( SCM s)                       \
-{                                              \
-return  CL::unsmob (s);                                \
-}
-
 #define IMPLEMENT_TYPE_P(CL, FUNCNAME)\
 void init_type_p_ ## CL ()\
 {\
@@ -64,14 +57,6 @@ SCM CL::smobbed_self () const                                        \
                                                                \
   return s;                                                    \
 }                                                              \
-CL *                                                           \
-CL::unsmob (SCM s)                                             \
-{                                                              \
-  if (SCM_NIMP (s) && SCM_CELL_TYPE (s) == smob_tag_)          \
-    return (CL*) SCM_CELL_WORD_1 (s);                          \
-  else                                                         \
-    return 0;                                                  \
-}                                                              \
 size_t                                                         \
 CL::free_smob (SCM ses)                                                \
 {                                                              \
index 269d5a96587bea16e329e882d28d2b3a3e575ed0..8a336e55ae59c2d4eeaccc19d2beadcb375f0960 100644 (file)
@@ -118,7 +118,7 @@ private:
   DECLARE_SIMPLE_SMOBS (Syllable_group,);
 } ;
 
-Syllable_group * unsmob_voice_entry (SCM);
+DECLARE_UNSMOB(Syllable_group,voice_entry);
 
 
 #endif // LYRIC_PHRASING_ENGRAVER_HH
index a8a342527917d9c539ccb484f0e45e4b0d568790..214e3181a491fceee73ef811dbeab796fe3329ea 100644 (file)
@@ -86,7 +86,7 @@ public:
 };
 
 
-Molecule *unsmob_molecule (SCM);
+DECLARE_UNSMOB(Molecule,molecule);
 SCM fontify_atom (Font_metric*, SCM atom);
 
 Molecule create_molecule (SCM brew_molecule);
index 4993b7691f84bebb64f30cb45571a5805ee6aeb7..54a8ad9cd720d404a130200dcf538caae93729ec 100644 (file)
@@ -58,7 +58,7 @@ IMPLEMENT_ARITHMETIC_OPERATOR (Moment, * );
 
 ostream & operator << ( ostream &,Moment const &);
 
-Moment * unsmob_moment (SCM);
+DECLARE_UNSMOB(Moment,moment);
 int compare (Moment const&,Moment const&);
 INSTANTIATE_COMPARE (Moment const&, Moment::compare);
 
index 9128c2b2ed5719ebf163ec63083da7685ff91372..bc7e5c73a053c210f2a7832291c532343ef41ab7 100644 (file)
@@ -46,5 +46,5 @@ public:
   DECLARE_SMOBS (Music_output_def,);
 };
 
-Music_output_def* unsmob_music_output_def (SCM);
+DECLARE_UNSMOB(Music_output_def,music_output_def);
 #endif // Music_output_DEF_HH
index 2ce12fed36ecaeb4a674fa461fd85434b3a549cb..500eb003dc1d4e793fbb10e45ff2c34390ec2a16 100644 (file)
@@ -68,7 +68,7 @@ protected:
 };
 
 
-Music * unsmob_music (SCM);
+DECLARE_UNSMOB(Music,music);
 #endif // MUSIC_HH
 
 
index c88ed87ff061880e8505de7f0aa38b1853032559..c76b11182ed5c4fb72d705240c4b3cc2a964f5fa 100644 (file)
@@ -72,7 +72,7 @@ public:
 
 };
 
-Pitch* unsmob_pitch (SCM);
+DECLARE_UNSMOB(Pitch,pitch);
 
 #include "compare.hh"
 INSTANTIATE_COMPARE (Pitch, Pitch::compare);
index 78dc4ccabd1827971a095443435555dffe8cf676..af1e3caccb568fe4933437d91aa708828d55f40b 100644 (file)
@@ -37,5 +37,5 @@ public:
 private:
   void run_translator (Music_output_def*);
 };
-Score * unsmob_score (SCM); 
+DECLARE_UNSMOB(Score,score); 
 #endif
index a29547361678655216db03a42f27097a860682de..437235c9ea8c2b965629d63e3f8389d7da144630 100644 (file)
@@ -110,7 +110,12 @@ private:\
        static int print_smob (SCM s, SCM p, scm_print_state*); \
 public: \
        static SCM equal_p (SCM a, SCM b);\
-       static CL * unsmob (SCM);\
+       static CL * unsmob (SCM s){\
+  if (SCM_NIMP (s) && SCM_CELL_TYPE (s) == smob_tag_)          \
+    return (CL*) SCM_CELL_WORD_1 (s);                          \
+  else                                                         \
+    return 0;                                                  \
+}                                                              \
        static SCM smob_p (SCM);\
        static void init_smobs ();                              \
 private:
@@ -128,6 +133,14 @@ public: \
        SCM self_scm () const { return self_scm_; } \
 private:
 
+#define DECLARE_UNSMOB(CL,name) \
+inline CL *                                            \
+unsmob_ ## name (SCM s)                        \
+{                                              \
+return  CL::unsmob (s);                                \
+}
+
+
 
 #endif /* SMOBS_HH */
 
index 77082e268dbbed8e8453d8c0e7126c2c5fac09dc..fd6d42fd77b8e80ffd574d5a961d76a3651a3b9c 100644 (file)
@@ -64,7 +64,7 @@ private:
 
 };
 
-Translator_def* unsmob_translator_def (SCM);
+DECLARE_UNSMOB(Translator_def,translator_def);
 
 
 #endif /* TRANSLATOR_DEF_HH */
index 9877495be18c3bf5949c77be9571b7cefc6bbed8..6c1ff11327c95040d7feb2584d541f0de6e98f6a 100644 (file)
@@ -142,5 +142,5 @@ extern Dictionary<Translator*> *global_translator_dict_p;
 void add_translator (Translator*trans_p);
 
 Translator*get_translator_l (String s);
-Translator *unsmob_translator (SCM);
+DECLARE_UNSMOB(Translator,translator);
 #endif // TRANSLATOR_HH
index f1aedc2295223a249143ac8c1e821678bf760129..c4c46411db21196f28ce2f264b348cfd325bb6e6 100644 (file)
@@ -268,4 +268,4 @@ Molecule::mark_smob (SCM s)
 
 IMPLEMENT_TYPE_P (Molecule, "molecule?");
 IMPLEMENT_DEFAULT_EQUAL_P (Molecule);
-IMPLEMENT_UNSMOB (Molecule, molecule);
+
index 91eea12f126b99fda10794637e077e0dab5a6884..5b1f1d9027362961e5a8bbf7753aa8385a1eb0ce 100644 (file)
@@ -13,7 +13,7 @@
 #include "warn.hh"
 #include "ly-smobs.icc"
 
-IMPLEMENT_UNSMOB (Moment,moment);
+
 IMPLEMENT_SIMPLE_SMOBS (Moment);
 IMPLEMENT_TYPE_P (Moment, "moment?");
 
index 308b02577336d62ae691d63c9690c9d98b6a702e..df2c404764e8f5b081df9d0f08b3233f4596351d 100644 (file)
@@ -66,7 +66,7 @@ Music_output_def::Music_output_def (Music_output_def const &s)
 
 
 IMPLEMENT_SMOBS (Music_output_def);
-IMPLEMENT_UNSMOB (Music_output_def,music_output_def);
+
 IMPLEMENT_DEFAULT_EQUAL_P (Music_output_def);
 
 SCM
index c9955845dace681e762e5c343f7e2cbc7226d244..d3f5cdb4a804f75d28f2fd521289fcb5c3827ad7 100644 (file)
@@ -135,7 +135,7 @@ Music::transpose (Pitch)
 }
 
 IMPLEMENT_TYPE_P (Music, "music?");
-IMPLEMENT_UNSMOB (Music,music);
+
 IMPLEMENT_SMOBS (Music);
 IMPLEMENT_DEFAULT_EQUAL_P (Music);
 
index 54d876cfa7080bee983b2e89022d452e0bb5fbfc..46013523fd454bc124e9295ca69129c0aff1964a 100644 (file)
@@ -240,7 +240,7 @@ pitch_transpose (SCM p, SCM delta)
 
 
 IMPLEMENT_TYPE_P (Pitch, "pitch?");
-IMPLEMENT_UNSMOB (Pitch, pitch);
+
 SCM
 Pitch::mark_smob (SCM)
 {
index 7eeb67188b0be14174725b23465942b5fe43bc3d..5a4d27018afb6867a992cdab73a92bee1fa76d07 100644 (file)
@@ -153,7 +153,7 @@ Scheme_hash_table::to_alist () const
 
 
 
-IMPLEMENT_UNSMOB (Scheme_hash_table,scheme_hash);
+
 IMPLEMENT_SMOBS (Scheme_hash_table);
 IMPLEMENT_DEFAULT_EQUAL_P (Scheme_hash_table);
 
index 9cc2f6d0c652fee8540e645d15927dbaf5ff3706..9b8d379999fb34737d107bdd5be58049bdcb61e1 100644 (file)
@@ -166,7 +166,7 @@ Score::add_output (Music_output_def *pap_p)
 
 IMPLEMENT_SMOBS (Score);
 IMPLEMENT_DEFAULT_EQUAL_P (Score);
-IMPLEMENT_UNSMOB (Score, score);
+
 
 SCM
 Score::mark_smob (SCM s)
index 119acd03df36e3dfe6de5a799d5a626d8f6105e9..3106026868e10d050d1920353167957d53e321bc 100644 (file)
@@ -259,7 +259,7 @@ Syllable_group::print_smob (SCM, SCM port, scm_print_state *)
   return 1;
 }
 
-IMPLEMENT_UNSMOB (Syllable_group, voice_entry);
+
 IMPLEMENT_SIMPLE_SMOBS (Syllable_group);
 IMPLEMENT_DEFAULT_EQUAL_P (Syllable_group);
 
index 1d1f65aeb5037eaeb9c6c02710834b3696b0ddac..200e0513cce577a1391dcddf7aab14222502514f 100644 (file)
@@ -208,7 +208,7 @@ Translator_def::path_to_acceptable_translator (SCM type_str, Music_output_def* o
 
   return best_result;
 }
-IMPLEMENT_UNSMOB (Translator_def,translator_def);
+
 IMPLEMENT_SMOBS (Translator_def);
 IMPLEMENT_DEFAULT_EQUAL_P (Translator_def);
 
index fd9f367df62f796acf4c64007e79288d46e00e10..ef5f4b100a8d3e126e53e14a05124375c4a95dc9 100644 (file)
@@ -207,6 +207,6 @@ Translator::static_translator_description ()const
   return SCM_EOL;
 }
 
-IMPLEMENT_UNSMOB (Translator, translator);
+
 IMPLEMENT_SMOBS (Translator);
 IMPLEMENT_DEFAULT_EQUAL_P (Translator);
index 0c3b42ae05c923a92e6f0b34a1184f1d9df544c7..23ca1264f8f7de94c6234ff27be2db1cd52c4910 100644 (file)
@@ -7,6 +7,9 @@ import string
 LINE_BELL = 60
 scale_steps = [0,2,4,5,7,9,11]
 
+whole_clocks = 1536
+quart_clocks = 0
+
 def split_track (track):
        chs = {}
        for i in range(16):
@@ -35,15 +38,15 @@ def split_track (track):
 
 
 class Note:
-       def __init__ (self, duration, pitch, velocity):
+       def __init__ (self, clocks, pitch, velocity):
                self.velocity = velocity
                self.pitch = pitch
-               self.duration = duration
+               self.clocks = clocks
 
-       def duration_compare (a, b):
-               if a.duration < b.duration:
+       def clocks_compare (a, b):
+               if a.clocks < b.clocks:
                        return -1
-               elif a.duration > b.duration:
+               elif a.clocks > b.clocks:
                        return 1
                else:
                        return 0
@@ -53,40 +56,54 @@ class Note:
 
 class Time:
        def __init__ (self, t, num, den):
-               self.duration = t
+               self.skip = t
                self.num = num
                self.den = den
+               self.clocks = 0
                
        def dump (self):
-               return dump_skip (self.duration) + '\\time %d/%d ' % (self.num, self.den)
+               s = ''
+               if self.skip:
+                       s = dump_skip (self.skip)
+               s = s + '\n  '
+               return s  + '\\time %d/%d ' % (self.num, self.den) + '\n  '
 
 class Key:
        key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis')
        key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges')
 
        def __init__ (self, t, sharps, flats, minor):
-               self.duration = t
+               self.skip = t
                self.flats = flats
                self.sharps = sharps
                self.minor = minor
+               self.clocks = 0
                
        def dump (self):
+               s = ''
+               if self.skip:
+                       s = dump_skip (self.skip)
+               s = s + '\n  '
                if self.sharps and self.flats:
                        s = '\\keysignature %s ' % 'TODO'
                elif self.sharps:
-                       s = '\\notes\\key %s \major' % key_sharps[self.sharps]
+                       s = '\\notes\\key %s \major' % self.key_sharps[self.sharps]
                elif self.flats:
-                       s = '\\notes\\key %s \major' % key_flats[self.flats]
-               return dump_skip (self.duration) + s
+                       s = '\\notes\\key %s \major' % self.key_flats[self.flats]
+               return s + '\n  '
 
 
 class Text:
-       def __init__ (self, text):
+       def __init__ (self, t, text):
+               self.skip = t
                self.text = text
-               self.duration = 0
-               
+               self.clocks = 0
+
        def dump (self):
-               return dump_text (self)
+               s = ''
+               if self.skip:
+                       s = dump_skip (self.skip)
+               return s + dump_text (self)
 
 def notes_on_channel (channel):
        pitches = {}
@@ -103,7 +120,7 @@ def notes_on_channel (channel):
                                (lt, vel) = pitches[e[1][1]]
                                del pitches[e[1][1]]
                                
-                               nch.append ((t, Note (t-lt, e[1][1], vel)))
+                               nch.append ((lt, Note (t-lt, e[1][1], vel)))
                                
                        except KeyError:
                                pass
@@ -121,7 +138,7 @@ def notes_on_channel (channel):
                                        flats = 256 - accidentals
                                nch.append ((t, Key (t, sharps, flats, minor)))
                        elif e[1][1] == midi.TEXT_EVENT:
-                               nch.append ((t, Text (e[1][2])))
+                               nch.append ((t, Text (t, e[1][2])))
                        else:
                                sys.stderr.write ("SKIP: %s\n" % `e`)
                                pass
@@ -140,11 +157,11 @@ def unthread_notes (channel):
                todo = []
                for e in channel:
                        t = e[0]
-                       if e[1].__class__ == Note and ((t == start_busy_t and e[1].duration + t == end_busy_t) \
+                       if e[1].__class__ == Note and ((t == start_busy_t and e[1].clocks + t == end_busy_t) \
                            or t >= end_busy_t):
                                thread.append (e)
                                start_busy_t = t
-                               end_busy_t = t + e[1].duration
+                               end_busy_t = t + e[1].clocks
                        elif e[1].__class__ == Time or e[1].__class__ == Key or e[1].__class__ == Text:
                                thread.append (e)
                        else:
@@ -164,20 +181,18 @@ def gcd (a,b):
                b = c
        return a
        
-def dump_skip (dt):
-       return 's' + dump_duration (dt)
-
-def dump_duration (dur):
-       g = gcd (dur, 384)
-       s = '4'
-       (p,q) = (dur / g, 384 / g)
-       if (p == 1 and q == 1) :
-               pass
+def dump_skip (clocks):
+       return 's' + dump_duration (clocks) + ' '
+
+def dump_duration (clocks):
+       g = gcd (clocks, whole_clocks)
+       (d, n) = (whole_clocks/ g, clocks / g)
+       if n == 1:
+               s = '%d' % d
+       elif n == 3 and d != 1:
+               s = '%d.' % (d / 2)
        else:
-               if p <> 1:      
-                       s = s + '*%d'% p
-               if q <> 1:
-                       s = s + '*%d'% q
+               s = '%d*%d' % (d, n)
        return s
        
 def dump_note (note):
@@ -196,7 +211,7 @@ def dump_note (note):
        if scale_steps[i] <> step:
                str = str + 'is'
 
-       return ' %s' % str + dump_duration (note.duration)
+       return str + dump_duration (note.clocks) + ' '
 
 def dump (self):
        return self.dump ()
@@ -245,7 +260,7 @@ def dump_channel (thread):
                        
                lines[-1] = lines[-1] + dump_chord (ch[1])
 
-               last_t = t + ch[1][0].duration
+               last_t = t + ch[1][0].clocks
 
        return string.join (lines, '\n  ') + '\n'
 
@@ -286,9 +301,13 @@ def dump_track (channels, n):
                        
        
 def convert_midi (f):
+       global whole_clocks, quart_clocks
+
        str = open (f).read ()
        midi_dump = midi.parse (str)
 
+       whole_clocks = midi_dump[0][1]
+       quart_clocks = whole_clocks / 4
 
        tracks = []
        for t in midi_dump[1]: