]> git.donarmstrong.com Git - lilypond.git/commitdiff
jiba tab
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 28 May 2002 23:04:46 +0000 (23:04 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 28 May 2002 23:04:46 +0000 (23:04 +0000)
12 files changed:
ChangeLog
Documentation/topdocs/AUTHORS.texi
input/test/tablature.ly [new file with mode: 0644]
lily/include/stem.hh
lily/pitch.cc
lily/stem.cc
lily/tab-note-heads-engraver.cc [new file with mode: 0644]
ly/engraver-init.ly
ly/params-init.ly
scm/grob-description.scm
scm/grob-property-description.scm
scm/output-lib.scm

index 085232038deb33dc8bb4354c8a858654721a4ad6..78e5a84452d2be9b8166d2f14d1f6c1990aaee77 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2002-05-29  Han-Wen  <hanwen@cs.uu.nl>
+
+       * ly/engraver-init.ly (TabStaffContext): 
+       enable TabStaff by default.
+
+       *  Tablature support by Jean-Baptiste Lamy <jiba@@tuxfamily.org>
+
 2002-05-28  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * config.hh.in: Remove duplicate DIR_DATADIR entry.
index e57ae509acb2af6782921d638ba7532ea3a23690..ac1a01392097d918f5fd2916fd650b4a5d360a32 100644 (file)
@@ -21,7 +21,10 @@ list is alphabetically ordered.
 
 @itemize @bullet
 @item @email{tca@@gnu.org, Tom Cato Amundsen},
-    cembalo-partita in lilypond, accordion symbols, some lilypond-book.py
+    cembalo-partita in lilypond, accordion symbols, some
+lilypond-book.py
+@item  @email{jiba@@tuxfamily.org,Jean-Baptiste Lamy }
+   Tablature support
 @item @email{matsb@@s3.kth.se, Mats Bengtsson},
     @uref{http://www.s3.kth.se/~matsb/}
     lots of testing, fixes, general comments and contributions.
diff --git a/input/test/tablature.ly b/input/test/tablature.ly
new file mode 100644 (file)
index 0000000..7f12df0
--- /dev/null
@@ -0,0 +1,16 @@
+\version "1.3.146"
+
+%{
+
+A sample tablature.
+
+Tablature is done by overriding the note-head formatting function, and
+putting it on a 6-line staff. A special engraver takes care of going
+from string-number + pitch to number.
+
+%}
+
+\score {
+  \notes  \context TabStaff { ces'16-2 d'-2 e'8-2 g'2.-3  c'4-1 c''8-5 b'-5 }
+  
+ }
index c48bade0cc5bf28097173ee153010848130a851b..0e93750714bfa7b89f38ce4c2e15cede2712ce63 100644 (file)
@@ -23,6 +23,7 @@ public:
   static void set_beaming (Grob*,int,  Direction d);
   static Grob * beam_l (Grob*);
   static Grob * first_head (Grob*) ;
+  static Grob * last_head  (Grob*) ;
   static Drul_array<Grob*> extremal_heads (Grob*);
   static Grob * support_head (Grob*) ;
   static void add_head (Grob*me, Grob*n);
index 79a1b66635f4eae8a472cf9202fa8a650ced3f5e..fa06546afee4eeca96dc7c51a81bf628a66de17c 100644 (file)
@@ -348,9 +348,16 @@ LY_DEFINE(pitch_semitones,  "pitch-semitones", 1, 0, 0,
          "calculate the number of semitones of @var{p} from central C.")
 {
   Pitch *p = unsmob_pitch (pp);
-   SCM_ASSERT_TYPE(p, pp, SCM_ARG1, __FUNCTION__, "Pitch");
+  SCM_ASSERT_TYPE(p, pp, SCM_ARG1, __FUNCTION__, "Pitch");
  
-  int q = p->steps ();
+  int q = p->semitone_pitch ();
+  
+  // Was :
+  //
+  //int q = p->steps ();
+  //
+  // As the function is called "pitch_semitones", I assume it was a mistake !
+  // Jiba
 
   return gh_int2scm (q);
 }
index d0efe954f8e1f8e399c286efe95444048384eef3..9d38d54d7d8567f4dba75bf75380fda5e7281e90 100644 (file)
@@ -165,6 +165,18 @@ Stem::first_head (Grob*me)
   return extremal_heads (me)[-d];
 }
 
+/*
+  The note head opposite to the first head.
+ */
+Grob*
+Stem::last_head (Grob*me)
+{
+  Direction d = get_direction (me);
+  if (!d)
+    return 0;
+  return extremal_heads (me)[d];
+}
+
 /*
   START is part where stem reaches `last' head. 
  */
@@ -610,7 +622,27 @@ Stem::brew_molecule (SCM smob)
   Direction d = get_direction (me);
   
   
-  Real y1 = Staff_symbol_referencer::position_f (first_head (me));
+     
+  Real y1;
+
+  /*
+    This is required to avoid stems passing in tablature chords...
+   */
+
+
+  /*
+    TODO: make  the stem start a direction ?
+    
+  */
+  if (to_boolean (me->get_grob_property ("avoid-note-head")))
+    {
+      y1 = Staff_symbol_referencer::position_f (last_head (me));
+    }
+  else
+    {
+      y1 = Staff_symbol_referencer::position_f (first_head (me));
+    }
+  
   Real y2 = stem_end_position (me);
   
   Interval stem_y (y1 <? y2,y2 >? y1);
diff --git a/lily/tab-note-heads-engraver.cc b/lily/tab-note-heads-engraver.cc
new file mode 100644 (file)
index 0000000..3d426a0
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+  head-grav.cc -- part of GNU LilyPond
+
+  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+#include <ctype.h>
+#include <stdio.h>
+
+#include "rhythmic-head.hh"
+#include "paper-def.hh"
+#include "musical-request.hh"
+#include "dots.hh"
+#include "dot-column.hh"
+#include "staff-symbol-referencer.hh"
+#include "item.hh"
+#include "score-engraver.hh"
+#include "warn.hh"
+
+/**
+  make (guitar-like) tablature note
+ */
+class Tab_note_heads_engraver : public Engraver
+{
+  Link_array<Item> note_p_arr_;
+  
+  Link_array<Item> dot_p_arr_;
+  Link_array<Note_req> note_req_l_arr_;
+  
+  Link_array<Text_script_req> tabstring_req_arr_;
+
+public:
+  TRANSLATOR_DECLARATIONS(Tab_note_heads_engraver);
+
+protected:
+  virtual void start_translation_timestep ();
+  virtual bool try_music (Music *req_l) ;
+  virtual void process_music ();
+
+  virtual void stop_translation_timestep ();
+};
+
+
+Tab_note_heads_engraver::Tab_note_heads_engraver()
+{
+}
+
+bool
+Tab_note_heads_engraver::try_music (Music *m) 
+{
+  if (Note_req * n =dynamic_cast <Note_req *> (m))
+    {
+      note_req_l_arr_.push (n);
+      return true;
+    }
+  else if (Text_script_req * ts = dynamic_cast<Text_script_req*> (m))
+    {
+      if (m->get_mus_property ("text-type") != ly_symbol2scm ("finger")) return false;
+      
+      //if (tabstring_req_arr_.size () < note_req_l_arr_.size ()) {
+        tabstring_req_arr_.push (ts);
+      //}
+      return true;
+    }
+  else if (dynamic_cast<Busy_playing_req*> (m))
+    {
+      return note_req_l_arr_.size ();
+    }
+  
+  return false;
+}
+
+
+void
+Tab_note_heads_engraver::process_music ()
+{
+  /*
+  for (int i=0; i < tabstring_req_arr_.size (); i++) {
+      Music * tabstring_req = tabstring_req_arr_[i];
+      
+      size_t lenp;
+      char* tab_string_as_str = gh_scm2newstr(tabstring_req->get_mus_property ("text"), &lenp);
+  }
+  */
+  
+  for (int i=0; i < note_req_l_arr_.size (); i++)
+    {
+      Item * note_p  = new Item (get_property ("TabNoteHead"));
+      
+      Music * req = note_req_l_arr_[i];
+      
+      Music * tabstring_req = tabstring_req_arr_[i];
+      
+      size_t lenp;
+      char* tab_string_as_str = gh_scm2newstr(tabstring_req->get_mus_property ("text"), &lenp);
+      int tab_string = atoi(tab_string_as_str);
+      
+      Duration dur = *unsmob_duration (req->get_mus_property ("duration"));
+      
+      note_p->set_grob_property ("duration-log", gh_int2scm (dur.duration_log ()));
+
+      if (dur.dot_count ())
+       {
+         Item * d = new Item (get_property ("Dots"));
+         Rhythmic_head::set_dots (note_p, d);
+         
+         if (dur.dot_count ()
+             != gh_scm2int (d->get_grob_property ("dot-count")))
+           d->set_grob_property ("dot-count", gh_int2scm (dur.dot_count ()));
+
+         d->set_parent (note_p, Y_AXIS);
+         announce_grob (d, SCM_EOL);
+         dot_p_arr_.push (d);
+       }
+      
+      int pos = 2 * tab_string - 2; // No tab-note between the string !!!
+      SCM c0 = get_property ("centralCPosition");
+      if (gh_number_p (c0)) pos += gh_scm2int (c0);
+      
+      note_p->set_grob_property ("tab-string", gh_int2scm (tab_string));
+      
+      note_p->set_grob_property ("staff-position", gh_int2scm (pos));
+      announce_grob (note_p, req->self_scm());
+      note_p_arr_.push (note_p);
+    }
+}
+
+void
+Tab_note_heads_engraver::stop_translation_timestep ()
+{
+  for (int i=0; i < note_p_arr_.size (); i++)
+    {
+      typeset_grob (note_p_arr_[i]);
+    }
+
+  note_p_arr_.clear ();
+  for (int i=0; i < dot_p_arr_.size (); i++)
+    {
+      typeset_grob (dot_p_arr_[i]);
+    }
+  dot_p_arr_.clear ();
+  
+  note_req_l_arr_.clear ();
+  
+  tabstring_req_arr_.clear ();
+}
+
+void
+Tab_note_heads_engraver::start_translation_timestep ()
+{
+}
+
+
+ENTER_DESCRIPTION(Tab_note_heads_engraver,
+/* descr */       "Generate one or more tablature noteheads from Music of type Note_req.",
+/* creats*/       "TabNoteHead Dots",
+/* acks  */       "",
+/* reads */       "centralCPosition",
+/* write */       "");
index c22a99c9e8fdafa26aa685091beeba677742c266..aeed2f96e55f6193f06d3d2915ca81e6611a5b55 100644 (file)
@@ -223,7 +223,7 @@ InnerStaffGroupContext= \translator {
        \accepts "RhythmicStaff"
        \accepts "GrandStaff"
        \accepts "PianoStaff"
-       
+       \accepts "TabStaff"     
        \accepts "Lyrics"
        \accepts "ChordNames"
 }
@@ -347,6 +347,7 @@ ScoreContext = \translator {
        \consists "Span_arpeggio_engraver"
 
        \accepts "Staff"
+       \accepts "TabStaff"
        \accepts "StaffContainer"
        \accepts "StaffGroup"
        \accepts "RhythmicStaff"        
@@ -442,3 +443,37 @@ FiguredBassContext = \translator {
        \consists "Figured_bass_engraver"       
        \consistsend "Axis_group_engraver"
 }
+
+TabVoiceContext =   \translator {
+      \VoiceContext
+      \name "TabVoice"
+      \denies "Thread"
+      \consists "Tab_note_heads_engraver"
+}
+
+TabStaffContext = \translator {
+      \StaffContext
+      \alias "Staff"
+      \name "TabStaff"
+      \denies "Voice"
+      \accepts "TabVoice"
+      
+      % 6 strings
+      StaffSymbol \override #'line-count  = #6
+      StaffSymbol \override #'staff-space = #1.5
+      
+      % One may change the strings tuning as following :
+      % The lenght of the list must be equal to the number of string
+      %TabNoteHead \override #'string-tunings = #'(10 10 10 10 10 10)
+      
+      % Special "TAB" clef
+      clefGlyph = #"clefs-tab"
+      clefPosition = #0
+      
+      % Don't draw stems over the tabature figures !
+      Stem \override #'avoid-note-head = ##t
+      
+      % No accidental in tablature !
+      Accidental  = \turnOff 
+}
+   
index 5dd3aa44e24a7d4e12134d524216a19e52d7cd73..104f7d0cf4deb639103843f377284b96f32ec470 100644 (file)
@@ -49,7 +49,8 @@ interscoreline = 4. \mm
 \translator { \LyricsVoiceContext }
 \translator { \StaffContainerContext }
 \translator { \FiguredBassContext }
-
+\translator { \TabStaffContext }
+\translator { \TabVoiceContext }
 
 
 
index 647551589a6c9b9598fee28ae2de600d9f808703..b6c95fd76b9e8b03de5f013c473e710fc974c177 100644 (file)
        (meta . ((interfaces . (rhythmic-head-interface font-interface note-head-interface staff-symbol-referencer-interface))))
        ))
 
+    (TabNoteHead
+     . (
+       (font-family . roman)
+       (style . default)
+       (molecule-callback . ,tablature-molecule-callback)
+       (Y-offset-callbacks  . (,Staff_symbol_referencer::callback))
+       (stem-attachment-function . ,tablature-stem-attachment-function)
+  (string-tunings . (-8 -3 2 7 11 16))
+       (meta . ((interfaces . (rhythmic-head-interface font-interface note-head-interface staff-symbol-referencer-interface))))
+       ))
+
     (Glissando
      . (
        (type . line)
        (Y-offset-callbacks . (,Staff_symbol_referencer::callback))
        (adjust-if-on-staffline . #t)
        (font-family . music)      
+       (avoid-note-head . #f)
        (meta . ((interfaces . (stem-interface  font-interface))))
        ))
 
index ba025764cb605d162a0eea2d86f2f66252eddcc0..67e97366f41cad13a72f8a90581b9a2562a81ea0 100644 (file)
@@ -464,3 +464,7 @@ functions set spanner positions.")
 (grob-property-description 'chord-name-function procedure? "DOCME")
 (grob-property-description 'minimum-beam-collision-distance number?
 "Minimum distance to beam for a rest collision.")
+
+(grob-property-description 'tab-string number?       "The tablature string of a TabNoteHead.")
+(grob-property-description 'avoid-note-head boolean? "if set, the stem of a chord does not pass through all note head, but start at the last note head. Used by tablature.")
+(grob-property-description 'string-tunings list?     "The strings tuning, in semi-tons from the middle C. Used by tablature.")
index 8ae4df7790d8edeb1aeedace236ecddc2b298299..d4374a5974d3a802a2c765cf62588d8313299b26 100644 (file)
@@ -5,6 +5,36 @@
 ;;;; (c) 1998--2001 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
 
+; Tablature functions, by Jiba (jiba@tuxfamily.org)
+
+; The TabNoteHead stem attachment function.
+(define (tablature-stem-attachment-function style)
+  (cons 0.0 1.0)
+)
+
+; The TabNoteHead molecule callback.
+; Create a text molecule
+(define (tablature-molecule-callback grob)
+  (let ((molecule (fontify-text
+                   (ly-get-default-font grob)
+                   (string-append
+                    (number->string
+                     (- (pitch-semitones (ly-get-mus-property (ly-get-grob-property grob 'cause) 'pitch))
+                        (list-ref
+                         (ly-get-grob-property grob 'string-tunings)
+                         (- (ly-get-grob-property grob 'tab-string)
+                            1 ; remove 1 because list index starts at 0 and guitar string at 1.
+                            ))
+                        )
+                     )
+                    )
+                   )))
+    molecule ; return the molecule.
+    )
+  )
+
+; end of tablature functions
+
 
 (define (arg->string arg)
   (cond ((number? arg) (inexact->string arg 10))