From: Han-Wen Nienhuys Date: Wed, 25 Oct 2006 00:33:08 +0000 (+0000) Subject: * scm/translation-functions.scm (determine-frets-mf): new X-Git-Tag: release/2.10.0-2~88 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=1aff89b4d5507bc850698a041bb0f51dd22cff2b;p=lilypond.git * 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 --- diff --git a/ChangeLog b/ChangeLog index c5de55225d..348657c118 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2006-10-25 Han-Wen Nienhuys + + * 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 * lily/grob.cc (pure_relative_y_coordinate) @@ -32,6 +52,9 @@ 2006-10-24 Han-Wen Nienhuys + * 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 index 0000000000..d0ad15050f --- /dev/null +++ b/lily/fretboard-engraver.cc @@ -0,0 +1,100 @@ +/* + fretboard-engraver.cc -- part of GNU LilyPond + + (c) 2006 Han-Wen Nienhuys +*/ + +#include +#include +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 note_events_; + vector 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 */ ""); + diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 19a8dbd43f..3422089e9c 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -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 +SCM +ly_cxx_vector_to_list (vector 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 */ diff --git a/lily/semi-tie.cc b/lily/semi-tie.cc index fbc98f20aa..854dd0302e 100644 --- a/lily/semi-tie.cc +++ b/lily/semi-tie.cc @@ -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"); diff --git a/lily/tab-note-heads-engraver.cc b/lily/tab-note-heads-engraver.cc index 9758ffcb95..7870c0218a 100644 --- a/lily/tab-note-heads-engraver.cc +++ b/lily/tab-note-heads-engraver.cc @@ -8,17 +8,16 @@ #include #include + +#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]; diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index ffa0c245a5..4c759f3029 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -10,6 +10,18 @@ \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" diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 352256d817..1b640cbde0 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -647,6 +647,13 @@ 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) diff --git a/scm/fret-diagrams.scm b/scm/fret-diagrams.scm index fe5b6128d7..1558e3433d 100644 --- a/scm/fret-diagrams.scm +++ b/scm/fret-diagrams.scm @@ -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 diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 1748401fd4..07784a687a 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -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)))) diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm index 0bf05bca57..ff01c07582 100644 --- a/scm/translation-functions.scm +++ b/scm/translation-functions.scm @@ -137,3 +137,97 @@ )) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 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= (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