Re: [tablatures] hammer on and pull off

[ Thread Index | Date Index | More lilynet.net/tablatures Archives ]


David Stocker schrieb:
Hi Marc,

When I try to compile the test file, I get the following error:

   david@ubuntu-david:~/Desktop/tab/0.2$ lilypond bendtest.ly
   GNU LilyPond 2.13.3
   Processing `bendtest.ly'
   Parsing...

   bend.ly ─ 2009-08-23


   Interpreting music... [8][16]
   Preprocessing graphical objects...
   Solving 1 page-breaking chunks...[1: 1 pages]
   Drawing systems...bend.ly:239:57: In expression
   (parenthesize-tab-note-head grob):
   bend.ly:239:57: Unbound variable: parenthesize-tab-note-head
Hi David,

sorry, I think the error is due to the fact that I simply forgot to include tablature.ly in the test file. If you did that already, then another problem may occur because of an internal
renaming of the function which draws the parentheses around fret numbers.

I send you a corrected version of tablature.ly and bandtest.ly; if it doesn't work, please call me again.

I apologize for these avoidable errors - I have the tablature features included in my 2.13.3 and I compiled 2.13.4 an my computer, so I don't need tablature.ly any more and simply forget
that you still have only an "untouched" 2.13.3 available.

Marc

I've commented out the command about 7-string tuning to eliminate the error I get from that. Any clues?

Thanks again,

David


Marc Hohl wrote:
Hello all,

concerning hammer on and pull off, I have some proposals from
Federico and David. It seems that there is no need for indicating
hammer ons with an "H" (and pull off with "P, respectively).

On the other hands, the slurs don't look quite right in tablature.
So I tried to move them closer to the corresponding fret numbers.

I created a small test file; I hope it compiles without errors, but
I attach the corresponding pdf output, just in case...

Any comments/improvements/etc. are appreciated

Marc






%%%% tablature.ly
%%%%
%%%% source file of the GNU LilyPond music typesetter
%%%%
%%%% (c) 2009 Marc Hohl <marc@xxxxxxxxxx>


% some publications use the triangle-shaped note head
% for palm mute, so here we go:
palmMuteOn = {
  \override NoteHead #'style = #'do
}

palmMuteOff = {
  \revert NoteHead #'style
}

% for single notes (even in chord constructs <...>),
% or grouped notes in {...}
palmMute =
#(define-music-function (parser location note) (ly:music?)
  ;; are we inside a <...>?
  (if (eq? (ly:music-property note 'name) 'NoteEvent)
      ;; yes -> add a tweak
      (begin (set! (ly:music-property note 'tweaks)
                    (acons 'style 'do (ly:music-property note 'tweaks)))
      note)
      ;; no -> use predefined commands to switch to triangle-shaped note heads
      #{
        \palmMuteOn
        $note
        \palmMuteOff
      #}))


% dead notes are marked with a cross-shape note head,
% both in normal notation and in tablature:
deadNotesOn = {
  \override TabNoteHead #'style = #'cross
  \override NoteHead #'style = #'cross
}

deadNotesOff = {
  \revert TabNoteHead #'style
  \revert NoteHead #'style
}

% for single notes (even in chord constructs <...>),
% or grouped notes in {...}
deadNote =
#(define-music-function (parser location note) (ly:music?)
  ;; are we inside a <...>?
  (if (eq? (ly:music-property note 'name) 'NoteEvent)
      ;; yes -> add a tweak
      (begin (set! (ly:music-property note 'tweaks)
                    (acons 'style 'cross (ly:music-property note 'tweaks)))
       note)
       ;; no -> use predefined commmands for changing
       ;; note head and tablature fret signs
       #{
         \deadNotesOn
         $note
         \deadNotesOff
       #}))

% for more control over glyph-name calculations,
% use custom callback with tab noteheads which will ignore
% 'style = 'do
#(define-public (tab-note-head::calc-glyph-name grob)
  (let ((style (ly:grob-property grob 'style)))
   (case style
      ((cross) "2cross"))))

% ensure we only call notehead callback when
% 'style = 'cross
#(define-public (tab-note-head::whiteout-if-style-set grob)
  (let ((style (ly:grob-property grob 'style)))
       (if (and (symbol? style)
                (eq? style 'cross))
           (stencil-whiteout (ly:note-head::print grob))
           (ly:text-interface::print grob))))

% definitions for the "moderntab" clef:
% the "moderntab" clef will be added to the list of known clefs,
% so it can be used as any other clef:
%
% \clef "moderntab"
%
#(add-new-clef "moderntab" "markup.moderntab" 0 0 0)

% this function decides which clef to take
#(define-public (clef::print-modern-tab-if-set grob)
  (let ((glyph (ly:grob-property grob 'glyph)))
       ;; which clef is wanted?
       (if (string=? glyph "markup.moderntab")
           ;; if it is "moderntab", we'll draw it
           (let* ((staff-symbol (ly:grob-object grob 'staff-symbol))
                  (line-count   (ly:grob-property staff-symbol 'line-count))
                  (staff-space  (ly:grob-property staff-symbol 'staff-space 1)))
                 (grob-interpret-markup grob (make-customTabClef-markup line-count staff-space)))
           ;; otherwise, we simply use the default printing routine
           (ly:clef::print grob))))

% define sans serif-style tab-Clefs as a markup:
#(define-markup-command (customTabClef layout props num-strings staff-space) (integer? number?)
  (define (square x) (* x x))
  (let* ((scale-factor (/ staff-space 1.5))
         (font-size (- (* num-strings 1.5 scale-factor) 7))
         (base-skip (* (square (+ (* num-strings 0.195) 0.4)) scale-factor)))

        (interpret-markup layout props
           (markup #:vcenter #:bold
                   #:override (cons 'font-family 'sans)
                   #:fontsize font-size
                   #:override (cons 'baseline-skip base-skip)
                   #:left-align #:center-column ("T" "A" "B")))))

% if the stems are drawn, it is nice to have a double stem for
% (dotted) half notes to distinguish them from quarter notes:
#(define-public (tabvoice::draw-double-stem-for-half-notes grob)
  (let ((stem (ly:stem::print grob)))

       ;; is the note a (dotted) half note?
       (if (= 1 (ly:grob-property grob 'duration-log))
           ;; yes -> draw double stem
           (ly:stencil-combine-at-edge stem X RIGHT stem 0.5)
           ;; no -> draw simple stem
           stem)))

% as default, the glissando line between fret numbers goes
% upwards, here we have a function to correct this behavior:
#(define-public (glissando::calc-tab-extra-dy grob)
  (let* ((original (ly:grob-original grob))
         (left-bound (ly:spanner-bound original LEFT))
         (right-bound (ly:spanner-bound original RIGHT))
         (left-pitch (ly:event-property (event-cause left-bound) 'pitch))
         (right-pitch (ly:event-property (event-cause right-bound) 'pitch)))

    (if (< (ly:pitch-semitones right-pitch) (ly:pitch-semitones left-pitch))
        -0.75
         0.75)))

% for ties in tablature, fret numbers that are tied to should be invisible,
% except for 'tied to' numbers after a line break; these will be parenthesized
% (thanks to Neil for his solution):
#(define-public (parenthesize-tab-note-head grob)
  ;; Helper function to parenthesize tab noteheads,
  ;; since we can't use ParenthesesItem at this stage
  ;; This is basically the same as the C++ function
  ;; in accidental.cc, converted to Scheme
  (let* ((font (ly:grob-default-font grob))
         (open (stencil-whiteout (ly:font-get-glyph font "accidentals.leftparen")))
         (close (stencil-whiteout (ly:font-get-glyph font "accidentals.rightparen")))
         (me (ly:text-interface::print grob)))
        (ly:stencil-combine-at-edge
         (ly:stencil-combine-at-edge
          me
          X
          LEFT
          open)
         X
         RIGHT
         close)))

% ParenthesesItem doesn't work very well for TabNoteHead, since
% the parentheses are too small and clash with the staff-lines
% Define a callback for the 'stencils property which will tweak
% the parentheses' appearance for TabNoteHead
#(define-public (parentheses-item::calc-tabstaff-parenthesis-stencils grob)
   ;; the grob we want to parenthesize
   (let ((victim (ly:grob-array-ref (ly:grob-object grob 'elements) 0)))
     ;; check whether it's a notehead
     (if (grob::has-interface victim 'note-head-interface)
         (begin
           ;; tweak appearance before retrieving list of stencils '(left-paren right-paren)
           (ly:grob-set-property! grob 'font-size -2)
           (ly:grob-set-property! grob 'padding 0)
           ;; apply whiteout to each element of the list
           (map stencil-whiteout (parentheses-item::calc-parenthesis-stencils grob)))
         (parentheses-item::calc-parenthesis-stencils grob))))

% the handler for ties in tablature; split ties yield in a parenthesized
% fret number, otherwise the fret number will be invisible.
#(define-public (tie::handle-tab-tie grob)
   (let* ((original (ly:grob-original grob))
          (tied-tab-note-head (ly:spanner-bound grob RIGHT))
          (siblings (if (ly:grob? original)
                        (ly:spanner-broken-into original) '())))

     (if (and (>= (length siblings) 2)
              (eq? (car (last-pair siblings)) grob))
         ;; tie is split -> parenthesize
         (ly:grob-set-property! tied-tab-note-head 'stencil
                                (lambda (grob) (parenthesize-tab-note-head grob)))

         ;; tie is not split -> make fret number invisible
         (ly:grob-set-property! tied-tab-note-head 'transparent #t))))

% repeat ties occur within alternatives in a repeat construct;
% the correspondig fret numbers are shown in parentheses:
#(define-public (repeat-tie::parenthesize-tab grob)
  (let ((tied-tab-note-head (ly:grob-object grob 'note-head)))

        (ly:grob-set-property! tied-tab-note-head 'stencil
                               (lambda (grob) (parenthesize-tab-note-head grob)))))

% a command for switching to the (improved) full notation
tabFullNotation = {
  % time signature
  \revert TabStaff.TimeSignature #'stencil
  % stems (the half note gets a double stem)
  \override TabVoice.Stem #'stencil = #tabvoice::draw-double-stem-for-half-notes
  % beams, dots
  \revert TabVoice.Beam #'stencil
  \revert TabVoice.Dots #'stencil
  \revert TabVoice.Tie #'stencil
  \revert TabVoice.Tie #'after-line-breaking
  \revert TabVoice.RepeatTie #'stencil
  \revert TabVoice.RepeatTie #'after-line-braking
  \revert TabVoice.LaissezVibrerTie #'stencil
  \revert TabVoice.Slur #'stencil
  \revert PhrasingSlur #'stencil
  % tuplet stuff
  \revert TabVoice.TupletBracket #'stencil
  \revert TabVoice.TupletNumber #'stencil
  % dynamic signs
  \revert DynamicText #'transparent
  \revert DynamicTextSpanner #'stencil
  \revert TabVoice.DynamicTextSpanner #'stencil
  \revert TabVoice.Hairpin #'transparent
  % rests
  \revert TabVoice.Rest #'stencil
  \revert TabVoice.MultiMeasureRest #'stencil
  % markups etc.
  \revert TabVoice.Script #'stencil
  \revert TabVoice.TextScript #'stencil
  \revert TabStaff.Arpeggio #'stencil
}

% the defaults for tablature:
\layout {
  \context {
    \TabStaff
    % the clef handler
    \override Clef #'stencil = #clef::print-modern-tab-if-set
    % no time signature
    \override TimeSignature #'stencil = ##f
    % better parentheses in a TabStaff
    \override ParenthesesItem #'stencils = #parentheses-item::calc-tabstaff-parenthesis-stencils
    % no arpeggios
    \override Arpeggio #'stencil = ##f
  }
  \context {
    \TabVoice
    % remove stems, beams, dots and rests ...
    \override Stem #'stencil = ##f
    \override Beam #'stencil = ##f
    \override Dots #'stencil = ##f
    \override Rest #'stencil = ##f
    \override MultiMeasureRest #'stencil = ##f
    % ... all kinds of ties/slurs
    \override Tie  #'stencil = ##f
    \override RepeatTie #'stencil = ##f
    \override LaissezVibrerTie #'stencil = ##f
    \override Slur #'stencil = ##f
    \override PhrasingSlur #'stencil = ##f
    % 'tied to' fret numbers become invisible or parenthesized, respectively)
    \override Tie #'after-line-breaking = #tie::handle-tab-tie
    \override RepeatTie #'after-line-breaking = #repeat-tie::parenthesize-tab
    % ... and all kinds of markups, spanners etc.
    \override TupletBracket #'stencil = ##f
    \override TupletNumber #'stencil = ##f
    \override DynamicText #'transparent = ##t
    \override DynamicTextSpanner #'stencil = ##f
    \override TextSpanner #'stencil = ##f
    \override Hairpin #'transparent = ##t
    \override Script #'stencil = ##f
    \override TextScript #'stencil = ##f
    % the direction for glissando lines will be automatically corrected
    \override Glissando #'extra-dy = #glissando::calc-tab-extra-dy
    % dead notes in tablature and within chord constructs
    \override TabNoteHead #'glyph-name = #tab-note-head::calc-glyph-name
    \override TabNoteHead #'stencil = #tab-note-head::whiteout-if-style-set
  }
}
\version "2.13.3"

\include "tablature.ly"
\include "bend.ly"

\paper {
   indent = 0
   ragged-right = ##f }

%% the test

test = \relative c'' {
  \bendOn
  % First, some bends to see if they work from the topmost to the lowest string
  c4 ( d )( c2 )
  c4\2 ( d\2 )( c2\2 )
  c4\3 ( des\3 )( c2\3 ) \break
  c,4\4 ( d\4 )( c2\4 )
  c4\5 ( d\5 )( c2\5 )
  c4\6 ( d\6 )( c2\6 ) \break
  % is the bend amount displayed correctly? (should be ½ in both cases)
  c4 ( cis) d ( es )
  % grace notes
  \bendGrace c8(  d4 )( c4 ) r2
  % the distinction between \preBendOnly and \preBend is not very
  % elegant here, I hope that there will be a better solution...
  \bendGrace { \preBendOnly c8( } d2)  r2
  \bendGrace { \preBend c8( d)( } c2)  r2
  c4 ( es) e\2 ( gis\2 ) \break
  % quarter tone bends are not yet supported as they should be, but
  % the bend amount is calculated correctly ;-)
  c,4 ( cih ) c4 ( cisih )
  % I hope that in future releases the tie will recognize automagically
  % that he ties to a note which is bent, but I don't know how (yet).
  \bendGrace c'8 ( \holdBend d2 ) ~ d2 ( c1 ) 
  \bendOff
  % switching bends off works apparently
  c,4 ( e ) c4 ( f )
  c'4 ( b ) c4 ( a )
}

\score {
  <<
    \new Staff {
      \new Voice {
        \clef "G_8"
        \test
      }
    }
    \new TabStaff {
      \new TabVoice {
        \clef "tab"
        \test
      }
    }
  >>
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/