lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

tablature.ly - please test and comment


From: Marc Hohl
Subject: tablature.ly - please test and comment
Date: Fri, 22 May 2009 09:58:56 +0200
User-agent: Thunderbird 2.0.0.21 (X11/20090318)

[ok, the mail was too big, I removed the attached pdf output]
I attach the latest version of tablature.ly together with a test file.
Please have a look at it and reply any corrections/improvements/changes
/etc.
before I will send patches to Carl.

Remember that you have to add

(define-public (add-new-clef clef-name clef-glyph clef-position
octavation c0-position)
  "Append the entries for a clef symbol to supported clefs and
c0-pitch-alist"
  (set! supported-clefs
        (acons clef-name (list clef-glyph clef-position octavation)
supported-clefs))
  (set! c0-pitch-alist
        (acons clef-glyph c0-position c0-pitch-alist)))

into scm/parser-clef.scm (for now, I think it will be part of the next
release).

tablature.ly provides:

1) two commands to switch between tablature notation with and without stems
2) a sans serif tab clef
3) a double stemmed half note (of course only when stems are enabled)
4) fret numbers that are 'tied to' are now (mostly) invisible.
5) commands for palm mute and dead notes are available
6) glissando lines in tablature have now the right slope when sliding from
higher to lower frets.

Greetings

Marc

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


% some publications use the triangled note head 
% for palm mute, so here we go:
palmMuteOn = { \set shapeNoteStyles = #(make-vector 7 'do) }
palmMuteOff = { \unset shapeNoteStyles }
% for single notes (or groups of notes within { ...} :
palmMute =  #(define-music-function (parser location notes) (ly:music?)
      #{
         \palmMuteOn
         $notes
         \palmMuteOff
      #})

% x-tab-format uses a "x" instead of the fret number:
#(define (x-tab-format str context event)
    (make-whiteout-markup
      (make-vcenter-markup
        (markup #:musicglyph "noteheads.s2cross"))))

% dead notes are marked with a cross-shape note head,
% both in normal notation and in tablature:
deadNotesOn = {
   \override NoteHead #'style = #'cross
   \set tablatureFormat = #x-tab-format
}
deadNotesOff = {
   \unset tablatureFormat
   \revert NoteHead #'style
}
% for single notes or groups of notes within {...}:
deadNotes = #(define-music-function (parser location notes) (ly:music?)
   #{
      \deadNotesOn
      $notes
      \deadNotesOff
   #})

% 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 (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)
   ;; is the note a (dotted) half note?
   (if (= 1 (ly:grob-property grob 'duration-log))
       ;; yes -> draw double stem
       (ly:stencil-combine-at-edge
           (ly:stem::print grob) 0   1
           (ly:stem::print grob) 0.5 0 )
       ;; no -> draw simple stem
       (ly:stem::print grob)))

% 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))
          (left-staff-position (ly:grob-property left-bound 'staff-position))
          (right-staff-position (ly:grob-property right-bound 'staff-position)))

     (if (and (= left-staff-position right-staff-position)
              (< (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
% or -after a line break - put in parentheses. Since this is not (easily?)
% possible in lilypond, we offer three commands:
%
% \clearTabTieBreaks simply makes all tied numbers invisible,
% \drawTabTieBreaks draws numbers that follow a line break
% \markTabTieBreaks draws a red fret number and gives a 
%     warning message on the terminal, so the user can put the
%     parentheses manually and finally changes \mark... with \draw...

#(define (tie::tab-clear-tied-fret-numbers grob)
         (let* ((tied-fret-nr (ly:spanner-bound grob RIGHT)))
               (ly:grob-set-property! tied-fret-nr 'transparent #t)))

#(define (tie::tab-draw-tied-fret-numbers grob)
         (let* ((original (ly:grob-original grob))
                (tied-fret-nr (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 -> make fret number visible
                   (ly:grob-set-property! tied-fret-nr 'transparent #f)
                   ;; tie is not split -> make fret number invisible
                   (ly:grob-set-property! tied-fret-nr 'transparent #t))))

#(define (tie::tab-mark-tied-fret-numbers grob)
         (let* ((original (ly:grob-original grob))
                (tied-fret-nr (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 -> change fret number color to red and print 
a message
                   (begin (display "\nSplit tie appears in tablature.")
                          (display "\nAffected fret number is marked red.\n")
                          (ly:grob-set-property! tied-fret-nr 'color red))
                   ;; tie is not split -> make fret number invisible
                   (ly:grob-set-property! tied-fret-nr 'transparent #t))))

clearTabTieBreaks = {
  \override Tie #'after-line-breaking = #tie::tab-clear-tied-fret-numbers
}

drawTabTieBreaks = {
  \override Tie #'after-line-breaking = #tie::tab-draw-tied-fret-numbers
}

markTabTieBreaks = {
  \override Tie #'after-line-breaking = #tie::tab-mark-tied-fret-numbers
}

% commands for switching between tablature with numbers only...
tabNumbersOnly = {
   % no time signature
   \override TabStaff.TimeSignature #'stencil = ##f
   % no stems, beams, dots, ties and slurs
   \override TabVoice.Stem #'stencil = ##f
   \override TabVoice.Beam #'stencil = ##f
   \override TabVoice.Dots #'stencil = ##f
   \override TabVoice.Tie  #'stencil = ##f
   \override TabVoice.Slur #'stencil = ##f
   % no tuplet stuff
   \override TabVoice.TupletBracket #'stencil = ##f
   \override TabVoice.TupletNumber #'stencil = ##f
   % no dynamic signs, text spanners etc.
   \override DynamicText #'transparent = ##t 
   \override DynamicTextSpanner #'stencil = ##f
   \override TextSpanner #'stencil = ##f
   \override Hairpin #'transparent = ##t
   % no rests
   \override TabVoice.Rest #'stencil = ##f
   \override TabVoice.MultiMeasureRest #'stencil = ##f
   % no markups
   \override TabVoice.Script #'stencil = ##f
   \override TabVoice.TextScript #'stencil = ##f
}
% and the full notation
tabFullNotation = {
   % time signature
   \revert TabStaff.TimeSignature #'stencil
   % stems
   \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.Slur #'stencil
   % tuplet stuff
   \revert TabVoice.TupletBracket #'stencil
   \revert TabVoice.TupletNumber #'stencil
   % dynamic signs
   \revert DynamicText #'transparent
   \override DynamicTextSpanner #'stencil = ##f
   \revert TabVoice.DynamicTextSpanner #'stencil
   \revert TabVoice.Hairpin #'transparent
   % rests
   \revert TabVoice.Rest #'stencil
   \revert TabVoice.MultiMeasureRest #'stencil
   % markups
   \revert TabVoice.Script #'stencil
   \revert TabVoice.TextScript #'stencil
}

% the defaults for tablature:
% the clef handler will be included and the tablature
% is displayed \tabNumbersOnly-style:
\layout {
   \context {
      \TabStaff
      % the clef handler
      \override Clef #'stencil = #clef::print-modern-tab-if-set
      % no time signature
      \override TimeSignature #'stencil = ##f
      % behaviour of split ties
      \override Tie #'after-line-breaking = #tie::tab-clear-tied-fret-numbers
   }
   \context {
      \TabVoice
      \override Stem #'stencil = ##f
      \override Beam #'stencil = ##f
      \override Dots #'stencil = ##f
      \override Tie  #'stencil = ##f
      \override Slur #'stencil = ##f
      % the direction for glissando lines will be automatically corrected
      \override Glissando #'extra-dy = #glissando::calc-tab-extra-dy
      \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 Rest #'stencil = ##f
      \override MultiMeasureRest #'stencil = ##f
      \override Script #'stencil = ##f
      \override TextScript #'stencil = ##f
   }
}
\version "2.13.0"
\include "tablature.ly"

\paper {
   indent = 0 }
% for testing purposes only; in newer versions of lilypond, they will be
% already defined:
#(define-public guitar-seven-string-tuning '(4 -1 -5 -10 -15 -20 -25))
#(define-public guitar-drop-d-tuning       '(4 -1 -5 -10 -15 -22))
#(define-public bass-four-string-tuning    '(-17 -22 -27 -32))
#(define-public bass-drop-d-tuning         '(-17 -22 -27 -34))
#(define-public bass-five-string-tuning    '(-17 -22 -27 -32 -37))
#(define-public bass-six-string-tuning     '(-12 -17 -22 -27 -32 -37))

\markup{tablature.ly - test version 2009/05/22}

alotofstuff = { 
   \time 3/4
   c4^"test" d( e) 
   f4\f g a^\fermata
   c8\< c16 c ~ c2\!
   c'2.
   \mark \default
   R2.
   r4 d4 r8 r
   \times 3/4 { b4 c d c }
   c4. d-_( e\varcoda)
   ->f g~ a\prall g\thumb e-. f-. g-.
   \times 3/4 { b4  c \glissando d\5 \glissando c }
   \bar "|."
}
\markup { \justify { Here is the (nearly) standard way of how lilypond handles 
tablature.
(Nearly, because here the glissando lines have the right slope, and half notes 
are double-stemmed
to distinguish them from quarter notes.} }

\score {
   <<
      \new Staff { \clef "G_8"  \alotofstuff }
      \new TabStaff { \tabFullNotation \clef "tab" \alotofstuff }
   >>
}

\markup{ \justify { When we invoke \typewriter { \char #92 tabNumbersOnly } , 
it looks better
(this will be the default setting when tablature.ly is included.} }

\score {
   <<
      \new Staff { \clef "G_8" \alotofstuff }
      \new TabStaff   { \tabNumbersOnly \alotofstuff }
   >>
}

\markup{ \justify { tablature.ly supports an easy way to mark notes as played 
palm mute-style...} }

palmmute = \relative c, {
    \time 4/4
    e8^\markup { \musicglyph #"noteheads.u2do"  = palm mute } \palmMuteOn e e 
\palmMuteOff  e e  \palmMute e e e
    e8 \palmMute { e e e } e e e e 
    \palmMuteOn
    < e b' e>8 e e e <e b' e>2
    \bar "|."
}

\score {
   <<
      \new Staff { \clef "G_8" \palmmute }
      \new TabStaff  { \clef "tab"
                       \palmmute }
   >>
}

\markup {... or dead notes:}

deadnotes = \relative c,, {
   e8. \deadNotesOn e16 \deadNotesOff g4 a b
   e8. \deadNotes e16 g4 a b
   e,4. \deadNotes { e8 e e } e4
   \bar "|."
}

\score {
   <<
      \new Staff { \clef "bass_8" \deadnotes }
      \new TabStaff  { \set TabStaff.stringTunings =  #bass-four-string-tuning
                       \clef "tab"
                       \deadnotes }
   >>
}

\markup { \justify { The new moderntab-Clef supports tablatures from 4 to 7 
strings.
You simply call \typewriter { \char #92 clef \char #34 moderntab \char #34 } } }
% some stuff 
bass = \relative c,, {
   e4 g a b
   b4 f g d'
   \bar "|."
}
\markup{Four strings:}
\score {
   <<
      \new Staff { \clef "bass_8" \bass }
      \new TabStaff   { \clef "moderntab"
                        \set TabStaff.stringTunings =   #bass-four-string-tuning
                        \bass }
   >>
}

\markup{Five strings:}
\score {
   <<
      \new Staff { \clef "bass_8" \bass }
      \new TabStaff   { \clef "moderntab"
                        \set TabStaff.stringTunings =  #bass-five-string-tuning
                        \bass }
   >>
}

guitar = \relative c {
   c4 d e f
   g4 a b c 
   \bar "|."
}

\markup { Six strings:}
\score {
   <<
      \new Staff { \clef "G_8" \guitar }
      \new TabStaff   { \clef "moderntab"
                        \set TabStaff.stringTunings = #guitar-tuning
                        \guitar }
   >>
}

\markup { Seven strings:}
\score {
   <<
      \new Staff { \clef "G_8" \guitar }
      \new TabStaff   { \clef "moderntab"  
                        \set TabStaff.stringTunings = 
#guitar-seven-string-tuning
                        \guitar }
   >>
}

\markup { Seven strings, staff space set to 1.2 for testing purposes:}
\score {
   <<
      \new Staff { \clef "G_8" \guitar }
      \new TabStaff   { \clef "moderntab" \override TabStaff.StaffSymbol 
#'staff-space = #1.2
                        \set TabStaff.stringTunings =  
#guitar-seven-string-tuning
                        \guitar }
   >>
}

tietest = \relative c {
       f2 ~ f4  e
       g8 g ~ g g ~ g g~ g g ~
       g1
       c1 ~ \break  c2 ~ c
       < c\3 e\2 g\1 >4 < c\3 e\2 g\1 > ~ < c\3 e\2 g\1 > < c\3 e\2 g\1 >
       \bar "|."
       }

parenthesizedtietest = \relative c {
       f2 ~ f4  e
       g8 g ~ g g ~ g g~ g g ~
       g1
       c1 ~ \break  \parenthesize c2 ~ c
       < c\3 e\2 g\1 >4 < c\3 e\2 g\1 > ~ < c\3 e\2 g\1 > < c\3 e\2 g\1 >
       \bar "|."
       }


\markup { \justify { By default, tied fret numbers are now invisible. There 
seems to be at least
no easy way to parenthesize fret numbers automatically and even then, 
parentheses
around chords are not implemented yet, so we use another strategy:


By invoking \typewriter { \char #92 markTabTieBreaks }, the fret numbers that 
are tied and follow
a line break are marked red so you can easily spot them and parenthesize the
tab number manually} }

\score {
   << \new Staff { \clef "G_8" \tietest }
      \new TabStaff { \clef "tab" \markTabTieBreaks \tietest }
   >>
}
\markup { \justify { by invoking \typewriter {\char #92 clearTabTieBreaks }, 
every tied fret number is cleared, even if it follows a line break} }

\score {
   << \new Staff { \clef "G_8" \tietest }
      \new TabStaff { \clef "tab" \clearTabTieBreaks \tietest }
   >>
}

\markup { \justify { by invoking \typewriter {\char #92 drawTabTieBreaks } , 
the «broken» fret numbers are drawn in normal style. (Here, the parentheses 
are inserted manually.)} }
\score {
   << \new Staff { \clef "G_8" \tietest }
      \new TabStaff { \clef "tab" \drawTabTieBreaks \parenthesizedtietest }
   >>
}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]