lilypond-user
[Top][All Lists]
Advanced

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

Re: pitched rests in TabStaff !?


From: Thomas Morley
Subject: Re: pitched rests in TabStaff !?
Date: Sun, 30 Oct 2016 12:35:58 +0100

2016-10-30 2:15 GMT+02:00 Thomas Morley <address@hidden>:
> Hi,
>
> is it really true we have no viable method to use pitched rests in TabStaff?
> Or am I overlooking something?
>
> Some code to play with:
>
> \version "2.19.49"
>
> ps = { e,4 f, g, a, b, c d e f g a b c' d' e' f' g' a' b' c'' }
>
> <<
>   \new TabStaff \ps
>   \new TabStaff \with { \revert Rest.stencil }
>     \transpose c c'
>     $(make-sequential-music
>       (map
>         (lambda (p)
>           (make-music 'RestEvent 'duration (ly:make-duration 2) 'pitch p))
>         (event-chord-pitches ps)))
>>>
>
> What would be a reasonable method to implement (or work around) it?
>
> One could think of using staff-position, but I _want_ the rests transposable.
> Maybe creating a restToFretFunction like noteToFretFunction, not sure
> where the noteToFretFunction gets it's arguments from, though.
> Likely from Tab_note_heads_engraver. That would mean to write a
> Tab_rest_engraver
>
> Any other hints?
>
> Thanks,
>   Harm

Ok, I've defined a PitchedTabRestEngraver:

\version "2.19.49"

PitchedTabRestEngraver =
#(lambda (context)
  (let ((string-numbers '())
        (fingerings '())
        (rest-events '())
        (rest-grobs '())
        (line-count #f))
    (make-engraver
      ((start-translation-timestep trans)
        (set! fingerings '())
        (set! rest-events '())
        (set! rest-grobs '())
        (set! string-numbers '()))
      (listeners
        ((rest-event engraver event)
         (if (not (null? (ly:event-property event 'pitch)))
             (set! rest-events (cons event rest-events))))
        ((string-number-event engraver event)
          (set! string-numbers (cons event string-numbers)))
        ((fingering-event engraver event)
          (set! fingerings (cons event fingerings))))
      (acknowledgers
        ((rest-interface engraver grob source-engraver)
         (set! rest-grobs (cons grob rest-grobs)))
        ((staff-symbol-interface engraver grob source-engraver)
         (set! line-count (ly:grob-property grob 'line-count))))
      ((stop-translation-timestep trans)
        (let* ((rest-arts
                 (map
                   (lambda (nv) (ly:event-property nv 'articulations))
                   rest-events))
               (rest-strings-from-articulations
                 (map
                   (lambda (a)
                     (filter
                       (lambda (x)
                         (member
                           'string-number-event
                           (ly:event-property x 'class)))
                       a))
                   rest-arts))
                (rest-strings
                   (if (every null? rest-strings-from-articulations)
                       string-numbers
                       rest-strings-from-articulations))
                (rest-strings-to-determine-frets
                  (if (null? rest-strings)
                      (list (make-list (length rest-events) '()))
                      rest-strings))
                (rest-fingers-from-articulations
                  (map
                    (lambda (a)
                     (filter
                      (lambda (x)
                        (member 'fingering-event (ly:event-property x 'class)))
                      a))
                    rest-arts))
                (rest-fingers
                  (if (every null? rest-fingers-from-articulations)
                      fingerings
                      rest-fingers-from-articulations))
                (rest-fingers-to-determine-frets
                  (if (null? rest-fingers)
                      (list (make-list (length rest-events) '()))
                      rest-fingers))
                (unnest-list-one-level
                  (lambda (ls)
                    (append-map (lambda (x) (if (pair? x) x (list x))) ls)))
                (rest-list-for-determine-frets
                    (list
                      (unnest-list-one-level rest-strings-to-determine-frets)
                      (unnest-list-one-level rest-fingers-to-determine-frets)))
                (rest-string-fret-fingers
                  ((ly:context-property context 'noteToFretFunction)
                    context
                    rest-events
                    rest-list-for-determine-frets)))
          (for-each
            (lambda (tnh strg-frt-fngr)
              (if (and (list? strg-frt-fngr)
                       (number? (car strg-frt-fngr)))
                  (ly:grob-set-property! tnh 'staff-position
                    (list-ref
                      (iota line-count (- (1- line-count)) 2)
                      (abs (- (car strg-frt-fngr) line-count))))))
            rest-grobs
            rest-string-fret-fingers)))
      ((finalize trans)
       (set! line-count #f)))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper { indent = 40 }

\layout {
  %\context {
  %  \Score
  %  \consists \PitchedTabRestEngraver
  %}
  \context {
    \TabStaff
    %% nicer output:
    \override VerticalAxisGroup.staff-staff-spacing.basic-distance = #13
    \revert Rest.stencil
    \revert MultiMeasureRest.stencil
    \revert Tie.after-line-breaking
    %minimumFret = #5
    %restrainOpenStrings = ##t
  }
}

%% Only defined to get the example small
pitchedRestToRest =
#(define-music-function (m)(ly:music?)
"Transform pitched rests to simple rests"
(for-each
  (lambda (r) (ly:music-set-property! r 'pitch '()))
  (extract-named-music m 'RestEvent))
m)

m = {
    \key c \minor
    \time 2/4
    g8\rest g g g
    ees2\fermata
    f8\rest f f f
    d2~
    d\fermata
    R2
    R2
    ees'8\rest ees' ees' ees'
    c'2~
    c'4 c'\rest
    R1
    f'8\rest f' f' f'
    d'2~
    d'8 g' g' f'
    ees'2(
    d'8) g' g' f'
    ees'2(
    d'8) g' g' f'
    ees'4 ees'4\rest
    c' c'\rest
    g'2\fermata
}

<<
  \new Staff
    \with {
        instrumentName =
        \markup
          \center-column { "Default rests" "in" "Staff" }
    }
    { \clef "G_8" \pitchedRestToRest \m }
  \new TabStaff
    \with {
        instrumentName =
        \markup
          \center-column { "Default rests" "in" "TabStaff" }
    }
    { \pitchedRestToRest \m }
  \new TabStaff
    \with {
        instrumentName =
        \markup
          \center-column { "Pitched rests" "without" "PitchedTabRestEngraver" }
    }
    \m
  \new TabStaff
    \with {
        \consists \PitchedTabRestEngraver
        instrumentName =
        \markup
          \center-column { "Pitched rests" "with" "PitchedTabRestEngraver" }
    }
    \m
>>

Cheers,
  Harm

Attachment: pitched-rests-tab-01.png
Description: PNG image


reply via email to

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