[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
pitched-rests-tab-01.png
Description: PNG image