]> git.donarmstrong.com Git - lilypond.git/commitdiff
* scm/translation-functions.scm (determine-frets-mf): new
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 25 Oct 2006 00:33:08 +0000 (00:33 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 25 Oct 2006 00:33:08 +0000 (00:33 +0000)
function: compute fret numbers.

* scm/output-lib.scm (string-frets->description) new function.
(fret-board::calc-stencil): new function

* scm/fret-diagrams.scm (fret-diagram-verbose): update doc string.

* scm/define-grobs.scm (all-grob-descriptions): add FretBoard grob.

* lily/include/lily-guile.hh (ly_cxx_vector_to_list): new function.

* lily/tab-note-heads-engraver.cc: cleanups.

* lily/fretboard-engraver.cc: new file

* ly/engraver-init.ly: add FretBoards context

ChangeLog
lily/fretboard-engraver.cc [new file with mode: 0644]
lily/include/lily-guile.hh
lily/semi-tie.cc
lily/tab-note-heads-engraver.cc
ly/engraver-init.ly
scm/define-grobs.scm
scm/fret-diagrams.scm
scm/output-lib.scm
scm/translation-functions.scm

index c5de55225d802f1560e2d03903b0cd0a2200e477..348657c11862cf485a896cf16df149e7e78f3d98 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2006-10-25  Han-Wen Nienhuys  <hanwen@lilypond.org>
+
+       * scm/translation-functions.scm (determine-frets-mf): new
+       function: compute fret numbers. 
+
+       * scm/output-lib.scm (string-frets->description) new function.
+       (fret-board::calc-stencil): new function
+
+       * scm/fret-diagrams.scm (fret-diagram-verbose): update doc string.
+
+       * scm/define-grobs.scm (all-grob-descriptions): add FretBoard grob. 
+
+       * lily/include/lily-guile.hh (ly_cxx_vector_to_list): new function.
+
+       * lily/tab-note-heads-engraver.cc: cleanups.
+
+       * lily/fretboard-engraver.cc: new file
+
+       * ly/engraver-init.ly: add FretBoards context
+
 2006-10-24  Joe Neeman  <joeneeman@gmail.com>
 
        * lily/grob.cc (pure_relative_y_coordinate)
@@ -32,6 +52,9 @@
 
 2006-10-24  Han-Wen Nienhuys  <hanwen@lilypond.org>
 
+       * Documentation/user/lilypond-book.itely (Integrating DocBook and
+       music): patch by Bertalan Fodor for docbook.
+
        * Documentation/topdocs/GNUmakefile (LILYPOND_BINARY): use instead
        of $(LILYPOND). Prevents lilypond run for .txt files.
 
diff --git a/lily/fretboard-engraver.cc b/lily/fretboard-engraver.cc
new file mode 100644 (file)
index 0000000..d0ad150
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+  fretboard-engraver.cc -- part of GNU LilyPond
+
+  (c)  2006  Han-Wen Nienhuys
+*/
+
+#include <cctype>
+#include <cstdio>
+using namespace std;
+
+#include "context.hh"
+#include "item.hh"
+#include "engraver.hh"
+#include "pitch.hh"
+#include "stream-event.hh"
+#include "warn.hh"
+
+#include "translator.icc"
+
+/**
+   make (guitar-like) tablature note
+*/
+class Fretboard_engraver : public Engraver
+{
+  Item *fret_board_;
+  
+  vector<Stream_event*> note_events_;
+  vector<Stream_event*> tabstring_events_;
+public:
+  TRANSLATOR_DECLARATIONS (Fretboard_engraver);
+
+protected:
+  DECLARE_TRANSLATOR_LISTENER (note);
+  DECLARE_TRANSLATOR_LISTENER (string_number);
+  void process_music ();
+
+  void stop_translation_timestep ();
+};
+
+Fretboard_engraver::Fretboard_engraver ()
+{
+  fret_board_ = 0;
+}
+
+IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, note);
+void
+Fretboard_engraver::listen_note (Stream_event *ev)
+{
+  note_events_.push_back (ev);
+}
+
+IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, string_number);
+void
+Fretboard_engraver::listen_string_number (Stream_event *ev)
+{
+  tabstring_events_.push_back (ev);
+}
+
+void
+Fretboard_engraver::process_music ()
+{
+  if (!note_events_.size ())
+    return ;
+
+  fret_board_ = make_item ("FretBoard", note_events_[0]->self_scm ());
+
+  SCM proc = get_property ("noteToFretFunction");
+  if (ly_is_procedure (proc))
+    {
+      scm_call_4 (proc,
+                 context ()->self_scm (),
+                 fret_board_->self_scm (),
+                              
+                 ly_cxx_vector_to_list (note_events_),
+                 ly_cxx_vector_to_list (tabstring_events_));
+    }
+}
+
+void
+Fretboard_engraver::stop_translation_timestep ()
+{
+  fret_board_ = 0;
+  note_events_.clear ();
+  tabstring_events_.clear ();
+}
+
+ADD_TRANSLATOR (Fretboard_engraver,
+               /* doc */ "Generate one or more tablature noteheads from event of type NoteEvent.",
+               /* create */
+               "FretBoard "
+               ,
+
+               /* read */
+               "stringTunings "
+               "minimumFret "
+               "tablatureFormat "
+               "highStringOne "
+               ,
+               /* write */ "");
+
index 19a8dbd43ff62b1d969e2ea9bd93e08dfff6213e..3422089e9c50e043b884093d37600de8d42e14e3 100644 (file)
@@ -96,10 +96,6 @@ inline bool ly_is_equal (SCM x, SCM y)
 
 inline bool ly_scm2bool (SCM x) { return SCM_NFALSEP (x); }
 inline char ly_scm2char (SCM x) { return SCM_CHAR (x); }
-inline unsigned long ly_length (SCM x)
-{
-  return scm_num2ulong (scm_length (x), 0, "ly_length");
-}
 inline SCM ly_bool2scm (bool x) { return SCM_BOOL (x); }
 
 inline SCM ly_append2 (SCM x1, SCM x2)
@@ -183,4 +179,20 @@ inline SCM ly_car (SCM x) { return SCM_CAR (x); }
 inline SCM ly_cdr (SCM x) { return SCM_CDR (x); }
 inline bool ly_is_pair (SCM x) { return SCM_I_CONSP (x); }
 
+
+
+#include  "std-vector.hh"
+
+template<class T>
+SCM
+ly_cxx_vector_to_list  (vector<T> const &src)
+{
+  SCM l = SCM_EOL;
+  for (vsize i = src.size (); i --; )
+    l = scm_cons (src[i]->self_scm (), l);
+
+  return l;
+}
+
+
 #endif /* LILY_GUILE_HH */
index fbc98f20aa1db6eb6ce1c1a094c8cb4a44bc06bc..854dd0302e2843ecbc5570b3bb3531f427b64d44 100644 (file)
@@ -53,7 +53,9 @@ Semi_tie::calc_direction (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
   if (Semi_tie_column::has_interface (me->get_parent (Y_AXIS)))
-    me->get_parent (Y_AXIS)->get_property("positioning-done");
+    {
+      me->get_parent (Y_AXIS)->get_property("positioning-done");
+    }
   else
     {
       programming_error ("lv tie without Semi_tie_column"); 
index 9758ffcb95ad1a02c142871babff82d32a23fa65..7870c0218a74b44fb3e64178c90124b66d0307b6 100644 (file)
@@ -8,17 +8,16 @@
 
 #include <cctype>
 #include <cstdio>
+
+#include "engraver.hh"
+
 using namespace std;
 
-#include "dot-column.hh"
-#include "dots.hh"
 #include "duration.hh"
 #include "item.hh"
 #include "output-def.hh"
 #include "pitch.hh"
 #include "rhythmic-head.hh"
-#include "score-engraver.hh"
-#include "staff-symbol-referencer.hh"
 #include "stream-event.hh"
 #include "warn.hh"
 
@@ -69,7 +68,7 @@ Tab_note_heads_engraver::process_music ()
   for (vsize i = 0; i < note_events_.size (); i++)
     {
       SCM stringTunings = get_property ("stringTunings");
-      int number_of_strings = ((int) ly_length (stringTunings));
+      int number_of_strings = scm_ilength (stringTunings);
       bool high_string_one = to_boolean (get_property ("highStringOne"));
 
       Stream_event *event = note_events_[i];
index ffa0c245a54eb83a3743a2dca764ab9414407797..4c759f3029fcd6f1132b7f13ec64fc915aad15fd 100644 (file)
   \grobdescriptions #all-grob-descriptions
 }
 
+
+\context {
+  \type "Engraver_group"
+  \name "FretBoards"
+
+  \consists "Output_property_engraver" 
+
+  \consists "Axis_group_engraver" 
+  \consists "Fretboard_engraver"
+  \consists "Separating_line_group_engraver"
+  \consists "Font_size_engraver"
+}
 \context {
   \type "Engraver_group"
   \name "Staff"
@@ -24,7 +36,7 @@
   \consists "Separating_line_group_engraver"   
   \consists "Dot_column_engraver"
 
 %% perhaps move to Voice context?
+ %% perhaps move to Voice context?
   \consists "Ottava_spanner_engraver"
   \consists "Clef_engraver"
   \consists "Key_engraver"
@@ -475,6 +487,7 @@ AncientRemoveEmptyStaffContext = \context {
   
   \defaultchild "Staff"
 
+  \accepts "FretBoards"
   \accepts "Staff"
   \accepts "RhythmicStaff"
   \accepts "TabStaff"
@@ -491,7 +504,9 @@ AncientRemoveEmptyStaffContext = \context {
   \accepts "Devnull"
   \accepts "NoteNames"
   \accepts "FiguredBass"
-  
+
+
+  noteToFretFunction = #determine-frets
   soloText = #"Solo"
   soloIIText = #"Solo II"
   aDueText = #"a2"
index 352256d81752e616d86629511d17404cd8fe0e66..1b640cbde024a1972c45c21f445cb7ec8b9a29e5 100644 (file)
                                side-position-interface
                                self-alignment-interface
                                item-interface))))))
+    (FretBoard
+     . ((stencil . ,fret-board::calc-stencil)
+       (meta . ((class . Item)
+                (interfaces . (fret-board-interface
+                               font-interface
+                               ))))
+             ))
     (Glissando
      . (
        (style . line)
index fe5b6128d76b479ad399ae8bf6d55dcf793bff61..1558e3433d42641047cdbc450bd7285ba62271bc 100644 (file)
@@ -298,7 +298,7 @@ Line thickness is given by @var{th}, fret & string spacing by
   For example,
   
 @example
-   \\markup \\fret-diagram #'((mute 6) (mute 5) (open 4)
+   \\markup \\fret-diagram-verbose #'((mute 6) (mute 5) (open 4)
         (place-fret 3 2) (place-fret 2 3) (place-fret 1 2))
 @end example 
   
index 1748401fd4807b21c07f743175d9c54e5c5491fd..07784a687a776fc46ba4382b4e5d50b26a9f5977 100644 (file)
@@ -460,3 +460,36 @@ centered, X==1 is at the right, X == -1 is at the left."
 
 (define-public (lyric-text::calc-text grob)
    (ly:event-property (event-cause grob) 'text))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; fret boards
+
+(define (string-frets->description string-frets string-count)
+  (let*
+      ((desc (list->vector
+             (map (lambda (x) (list 'mute  (1+ x)))
+                  (iota string-count)))))
+       
+       (for-each (lambda (sf)
+                  (let*
+                      ((string (car sf))
+                       (fret (cdr sf)))
+
+
+                    (vector-set! desc (1- string)
+                                 (if (= 0 fret)
+                                     (list 'open string)
+                                     (list 'place-fret string fret)))
+                    ))
+                string-frets)
+       (vector->list desc)))
+
+(define-public (fret-board::calc-stencil grob)
+  (let* ((string-frets (ly:grob-property grob 'string-frets))
+        (string-count (ly:grob-property grob 'string-count))
+        (layout (ly:grob-layout grob))
+        (defs (ly:output-def-lookup layout 'text-font-defaults))
+        (props (ly:grob-alist-chain grob defs)))
+
+    (make-fret-diagram layout props
+                      (string-frets->description string-frets 6))))
index 0bf05bca5714b96739ae18d7b034c5ec1ec9897c..ff01c075824c009a66a5d157620f5ce01317a96f 100644 (file)
 
     ))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; fret diagrams
+
+(define-public (determine-frets context grob notes string-numbers)
+  (define (ensure-number a b)
+    (if (number? a)
+       a
+       b))
+(let*
+      ((tunings (ly:context-property context 'stringTunings))
+       (minimum-fret (ensure-number
+                     (ly:context-property context 'minimumFret) 0))
+       (string-frets (determine-frets-mf notes string-numbers
+                                        minimum-fret
+                                        tunings)))
+
+                     
+  (set! (ly:grob-property grob 'string-count) (length tunings))
+  (set! (ly:grob-property grob 'string-frets) string-frets)
+
+  ))
+
+(define-public (determine-frets-mf notes string-numbers
+                                  minimum-fret
+                                  tunings)
+
+  (define (calc-fret pitch string tuning)
+    (- (ly:pitch-semitones pitch) (list-ref tuning (1- string))))
+
+  (define (note-pitch a)
+    (ly:event-property a 'pitch))
+
+  (define (note-pitch<? a b)
+    (ly:pitch<? (note-pitch a)
+               (note-pitch b)))
+  
+  (define (note-ev-string ev)
+    (let* ((articulations (ly:event-property ev 'articulations))
+          (string-found #f))
+
+      (map (lambda (art)
+            (let*
+                ((num (ly:event-property art 'string-number)))
+
+              (if (number? num)
+                  (set! string-found num))))
+          articulations)
+      string-found))
+
+  (let*
+      ((free-strings (map 1+ (iota (length tunings))))
+       (del-string (lambda (string)
+                    (if (number? string)
+                        (set! free-strings
+                              (delete string free-strings)))))
+       (string-qualifies (lambda (string pitch)
+                          (and (>= (calc-fret pitch string tunings)
+                                   minimum-fret))))
+       (string-frets '())
+       (set-fret (lambda (note string)
+                  (set! string-frets
+                       (acons string
+                              (calc-fret (ly:event-property note 'pitch)
+                                         string tunings)
+                              string-frets))
+                  (del-string string)
+                  ))
+       
+
+       )
+    
+    (for-each (lambda (note)
+               (del-string (note-ev-string note)))
+             notes)
+
+
+    (for-each
+     (lambda (note)
+       (if (note-ev-string note)
+          (set-fret note (note-ev-string note))
+          (let*
+              ((string (find (lambda (string) (string-qualifies string
+                                                                (note-pitch note)))
+                             (reverse free-strings))))
+
+               (set-fret note string))))
+     (sort notes note-pitch<?))
+
+    
+    (display string-frets)
+
+
+    string-frets))
+