Simon, you wrote Friday, September 02, 2016 1:34 AM
Hi Simon,
>On 24.08.2016 11:51, Trevor Daniels wrote:
>> David Kastrup wrote Wednesday, August 24, 2016 7:48 AM
>>> "Trevor Daniels"<[email protected]> writes:
>>>> Prompted by the recent discussion on lute tablature, I tried coding a
>>>> Scheme engraver to create the duration grobs but quickly ran into a
>>>> problem. I need to collect information from both a Listener and an
>>>> Acknowledger so the obvious place to build the grob is in
>>>> stop-translator-timestep,
>>> No, no, no. stop-translator-timestep really is only for cleanup work.
>>> Stuff is no longer in working order then. You want process-acknowledged
>>> here I think.
>>>
>>> There will always be a call to process-acknowledged whenever grobs have
>>> been created, and_reading_ stuff from grobs should be delayed until
>>> then since other acknowledgers might_write_ stuff into a grob even
>>> after your personal acknowledger has been called. So the basic workflow
>>> is to use the various acknowledgers to_record_ the grobs you are
>>> interested in and_write_ stuff into them (or do read/write stuff that
>>> more or less is accumulative and/or really unrelated to other
>>> engravers), and then use the process-acknowledged hook for processing
>>> (including_reading_) the grobs you had recorded.
>>>
>>> You can create new grobs in process-acknowledged. That will lead to a
>>> new cycle of acknowledger calls followed by process-acknowledged. Only
>>> when all those cycles are over is stop-translator-timestep called, and
>>> then creating grobs is no longer an option.
>>
>> Thanks David. That's beautifully clear.
>
> I just caught up with all the mailing lists, being back from holiday,
> and I’d be interested in a working example for this solution. Would you
> mind sharing it?
There already is a helpful working example in the code base. See
input/regression/scheme-engraver.ly
This doesn't go as far as creating new grobs, so I've attached a
simple example that does. This is a bit of a hack, used as part of
a learning process, and a bit messy as it evolved from an earlier
attempt, but it illustrates one way.
Actually, comments from the experts on this would be very helpful.
Trevor
\version "2.19.40"
% Example of using Scheme engraver to add markup based on note duration
% Avoids repeated durations on both chords and consecutive notes
%{
TODO
Handle notes with different durations at one musical moment better
Add dots
Add bass courses
%}
#(define (t->m t)
"Return the current moment of translator object @var{t}."
(ly:context-current-moment (ly:translator-context t)))
% persistent variables for Lute_tab_duration_engraver
#(define previous-duration-log #f) % to supress repeated durations
#(define ev #f) % event
#(define en #f) % engraver
Lute_tab_duration_engraver =
#(make-engraver
((initialize translator)
(format 1 "\n\n~16a: (initialize)\n" (t->m translator)))
((start-translation-timestep translator)
(set! ev #f)
(set! en #f)
(format 1 "~16a: (start-translation-timestep)\n" (t->m translator)))
(listeners
((note-event engraver event)
; Save just the last event at each timestep
;TODO save shortest duration event?
(set! ev event)
(set! en engraver)
(format 1 "~16a: detected this note event: ~a\n "
(t->m engraver) event)))
(acknowledgers
((note-head-interface engraver grob source-engraver)
(format 1 "~16a: saw ~a coming from ~a\n"
(t->m engraver) grob source-engraver)))
(end-acknowledgers
((beam-interface engraver grob source-engraver)
(format 1 "~16a: saw end of ~a coming from ~a\n"
(t->m engraver) grob source-engraver)))
((process-music translator)
(format 1 "~16a: (process-music)\n" (t->m translator))
(if ev
(let ((duration-log
(ly:duration-log (ly:event-property ev 'duration))))
(display duration-log)
(if (not (equal? duration-log previous-duration-log))
(let ((grob (ly:engraver-make-grob en 'TextScript ev)))
(set! previous-duration-log duration-log)
(ly:grob-set-property! grob 'direction UP)
(ly:grob-set-property! grob 'text
(case duration-log
((2) (markup (#:musicglyph "rests.M2mensural")))
((3) (markup (#:musicglyph "flags.mensuralu03")))
((4) (markup (#:musicglyph "flags.mensuralu04")))
((5) (markup (#:musicglyph "flags.mensuralu05")))
((6) (markup (#:musicglyph "flags.mensuralu06")))
(else (markup " ")))))))))
((process-acknowledged translator)
(format 1 "~16a: (process-acknowledged)\n" (t->m translator)))
((stop-translation-timestep translator)
(format 1 "~16a: (stop-translation-timestep)\n" (t->m translator)))
((finalize translator)
(format 1 "~16a: (finalize)\n" (t->m translator))))
notes = \relative c'' {
\time 3/4
\partial 4.
a8 r a |
<f d>4. f8 <g e>4 |
\break
\time 4/4
c1 |
cis2 d4 ees8 e16 f32 fis64 g64 |
gis16 a16 bes8 c cis d ees e f |
fis g gis a bes b c cis |
}
\score {
<<
\new Staff {
\new Voice {
\notes
}
}
\new TabStaff
\with {
% Use letters to indicate frets
tablatureFormat = #fret-letter-tablature-format
% Usual string tuning for 6-course Baroque lute
stringTunings = #`(,(ly:make-pitch 1 3 NATURAL)
,(ly:make-pitch 1 1 NATURAL)
,(ly:make-pitch 0 5 NATURAL)
,(ly:make-pitch 0 3 NATURAL)
,(ly:make-pitch 0 1 NATURAL)
,(ly:make-pitch -1 5 NATURAL))
% Choose a suitable font for fret letters
\override TabNoteHead.font-name = #"Fronimo Gavotta"
\override Flag.style = #'straight
\revert TextScript.stencil
}
{
\new TabVoice
\with {
% Baroque tab uses slurs
\consists "Fingering_engraver"
\consists "New_fingering_engraver"
\consists \Lute_tab_duration_engraver
\revert Slur.stencil
}
{
\textLengthOn
% \applyMusic #(lambda (x) (music-map add-duration x))
\notes
}
}
>>
}
%{
convert-ly.py (GNU LilyPond) 2.19.43 convert-ly.py: Processing `'...
Applying conversion: 2.13.10, 2.13.16, 2.13.18, 2.13.20, 2.13.27,
2.13.29, 2.13.31, 2.13.36, 2.13.39, 2.13.40, 2.13.42, 2.13.44,
2.13.46, 2.13.48, 2.13.51, 2.14.0, 2.15.7, 2.15.9, 2.15.10, 2.15.16,
2.15.17, 2.15.18, 2.15.19, 2.15.20, 2.15.25, 2.15.32, 2.15.39,
2.15.40, 2.15.42, 2.15.43, 2.16.0, 2.17.0, 2.17.4, 2.17.5, 2.17.6,
2.17.11, 2.17.14, 2.17.15, 2.17.18, 2.17.19, 2.17.20, 2.17.25,
2.17.27, 2.17.29, 2.17.97, 2.18.0, 2.19.2, 2.19.7, 2.19.11, 2.19.16,
2.19.22, 2.19.24, 2.19.28, 2.19.29, 2.19.32, 2.19.40
%}
_______________________________________________
lilypond-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-devel