Re: [tablatures] slides

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


Carl Sorensen schrieb:

On 9/14/09 1:30 PM, "Marc Hohl" <marc@xxxxxxxxxx> wrote:

Carl Sorensen schrieb:
[...]

No question it's the right way to do it for 2.13.4.

But the whole thin (including the alists) could be copied to tablature.ly
for immediate use with 2.12, couldn't it?

Carl
Hm, after a bit of investigating I can only produce error messages.
What I did: I included the definition of c0-pitch-alist together with
the definition for add-new-clef in tablature.ly, which didn't work:

In procedure cdr in expression (cdr (assoc # c0-pitch-alist)):
/home/marc/lilypond/usr/share/lilypond/current/scm/parser-clef.scm:119:45:
Wrong type (expecting pair): #f
(by the way, I don't understand this error, because when I #(display
c0-pitch-alist), I looks
as it should be)

(assoc # c0-pitch-alist)  looks fishy to me.

I think that the error comes from the cdr call, which needs a pair, but the
assoc call returns #f.
Yes, and my first thought was that there were error building up the alist,
but the list seems to be ok...

Then I added the supported-clefs list to the file with the result that
the error message went away, but lilypond still claims that the clef
"moderntab" can't be found.

Then again, I tried to hardcode the values for the moderntab clef,
and this resulted in the attached file, but it still doesn't work. I
also tried to
include the definition for make-clef-set from scm/parser-clef.scm
in tablature.ly, but the function string-match is not known at this stage.

I didn't get an attachment with this file, so I don't know how to
troubleshoot it  for you.
Oh, yes, I wanted to attach the file ... I hope in some years from now the
email clients are clever enough to warn you if you mention "attached" or
"send ... to you" that there is propably some attachment missing :-)

Here it is. Thanks in advance for your support!

Marc
Thanks,

Carl





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

%a copy of the alists from scm/parser-clef.scm
% because it isn't defined as -public (the moderntab
% entry is inserted):
#(define-public c0-pitch-alist
  '(("clefs.G" . -4)
    ("clefs.C" . 0)
    ("clefs.F" . 4)
    ("clefs.percussion" . 0)
    ("clefs.tab" . 0 )
    ("clefs.vaticana.do" . 0)
    ("clefs.vaticana.fa" . 4)
    ("clefs.medicaea.do" . 0)
    ("clefs.medicaea.fa" . 4)
    ("clefs.hufnagel.do" . 0)
    ("clefs.hufnagel.fa" . 4)
    ("clefs.hufnagel.do.fa" . 0)
    ("clefs.mensural.c" . 0)
    ("clefs.mensural.f" . 4)
    ("clefs.mensural.g" . -4)
    ("clefs.neomensural.c" . 0)
    ("clefs.petrucci.c1" . 0)
    ("clefs.petrucci.c2" . 0)
    ("clefs.petrucci.c3" . 0)
    ("clefs.petrucci.c4" . 0)
    ("clefs.petrucci.c5" . 0)
    ("clefs.petrucci.f" . 4)
    ("clefs.petrucci.g" . -4)
    ("markup.moderntab" . 0)))

#(define-public supported-clefs
  '(("treble" . ("clefs.G" -2 0))
    ("violin" . ("clefs.G" -2 0))
    ("G" . ("clefs.G" -2 0))
    ("G2" . ("clefs.G" -2 0))
    ("french" . ("clefs.G" -4 0))
    ("soprano" . ("clefs.C" -4 0))
    ("mezzosoprano" . ("clefs.C" -2 0))
    ("alto" . ("clefs.C" 0 0))
    ("C" . ("clefs.C" 0 0))
    ("tenor" . ("clefs.C" 2 0))
    ("baritone" . ("clefs.C" 4 0))
    ("varbaritone" . ("clefs.F" 0 0))
    ("bass" . ("clefs.F" 2 0))
    ("F" . ("clefs.F" 2 0))
    ("subbass" . ("clefs.F" 4 0))
    ("percussion" . ("clefs.percussion" 0 0))
    ("tab" . ("clefs.tab" 0 0))
    ("moderntab" . ("markup.moderntab" 0 0))

    ;; should move mensural stuff to separate file?
    ("vaticana-do1" . ("clefs.vaticana.do" -1 0))
    ("vaticana-do2" . ("clefs.vaticana.do" 1 0))
    ("vaticana-do3" . ("clefs.vaticana.do" 3 0))
    ("vaticana-fa1" . ("clefs.vaticana.fa" -1 0))

    ("vaticana-fa2" . ("clefs.vaticana.fa" 1 0))
    ("medicaea-do1" . ("clefs.medicaea.do" -1 0))
    ("medicaea-do2" . ("clefs.medicaea.do" 1 0))
    ("medicaea-do3" . ("clefs.medicaea.do" 3 0))
    ("medicaea-fa1" . ("clefs.medicaea.fa" -1 0))
    ("medicaea-fa2" . ("clefs.medicaea.fa" 1 0))
    ("hufnagel-do1" . ("clefs.hufnagel.do" -1 0))
    ("hufnagel-do2" . ("clefs.hufnagel.do" 1 0))
    ("hufnagel-do3" . ("clefs.hufnagel.do" 3 0))
    ("hufnagel-fa1" . ("clefs.hufnagel.fa" -1 0))
    ("hufnagel-fa2" . ("clefs.hufnagel.fa" 1 0))
    ("hufnagel-do-fa" . ("clefs.hufnagel.do.fa" 4 0))
    ("mensural-c1" . ("clefs.mensural.c" -2 0))
    ("mensural-c2" . ("clefs.mensural.c" 0 0))
    ("mensural-c3" . ("clefs.mensural.c" 2 0))
    ("mensural-c4" . ("clefs.mensural.c" 4 0))
    ("mensural-f" . ("clefs.mensural.f" 2 0))
    ("mensural-g" . ("clefs.mensural.g" -2 0))
    ("neomensural-c1" . ("clefs.neomensural.c" -4 0))
    ("neomensural-c2" . ("clefs.neomensural.c" -2 0))
    ("neomensural-c3" . ("clefs.neomensural.c" 0 0))
    ("neomensural-c4" . ("clefs.neomensural.c" 2 0))
    ("petrucci-c1" . ("clefs.petrucci.c1" -4 0))
    ("petrucci-c2" . ("clefs.petrucci.c2" -2 0))
    ("petrucci-c3" . ("clefs.petrucci.c3" 0 0))
    ("petrucci-c4" . ("clefs.petrucci.c4" 2 0))
    ("petrucci-c5" . ("clefs.petrucci.c5" 4 0))
    ("petrucci-f3" . ("clefs.petrucci.f" 0 0))
    ("petrucci-f4" . ("clefs.petrucci.f" 2 0))
    ("petrucci-f" . ("clefs.petrucci.f" 2 0))
    ("petrucci-g" . ("clefs.petrucci.g" -2 0))))


% 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 (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))))

% 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)
  (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"

% some stuff 
bass = \relative c,, {
   e4 g a b
   b4 f g d'
   \bar "|."
}

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


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