Re: Help with Scheme engraver please
Trevor Daniels wrote Saturday, September 17, 2016 9:57 PM > Thomas Morley wrote Friday, September 09, 2016 11:31 PM > >> 2016-09-08 0:07 GMT+02:00 Trevor Daniels: >>> >>> But I don't understand why you >>> used a rather complicated procedure to obtain durations. Could you >>> not simply extract the durations from note events? >> >> In my opinion the historic lute tablatures were written disregarding >> any polyphony as far as rhythmy are concerned, yes. >> But this polyphony was always _meant_ and the player should respect it. >> >> For our coding this means an example like >> >> upper = { d'2 d' } >> middle = { \override Rest.staff-position = #-1.5 r8 f r8 f r8 f r8 f } >> lower = { a,4\rest d a,4\rest d } >> >> \score { >> << >> \new Staff << \clef "G_8" \upper \\ \lower \\ \middle >> >> >> \new TabStaff >> << \clef "G_8" \upper \\ \lower \\ \middle >> >> >> >> \layout { >>\context { >>\TabStaff >> stringTunings = \stringTuning >>} >> } >> } >> >> should return proper polyphonic in Staff, and in TabStaff only a >> single 8th indication for the overall rhythm should be printed. >> This can be achieved with my proposal and would warrant the principle >> of one source-code for Staff _and_ TabStaff. >> I didn't found a method to do so with simple durations. > > OK, I see now why you need to extract the interval between a note and the > subsequent note even when they are split between several voices. > This interval then should be displayed as the "duration" of the first of the > pair > (unless it is unchanged from the previous one, of course) > > I agree this can't be done by looking solely at the duration of individual > notes. > > However, your code doesn't quite work in all situations. If you replace the > first f in the middle voice with a rest we should have a duration of 4 > followed > by one of 8, but the 8 is missing. > >> You seems to be of different opinion, for some cases you let >> explicitely print the warning: >> "Polyphony is not supported in lute tab" > > Well, I meant it wasn't supported in my simple implementation, not > that it shouldn't be. > > I need now to study your approach to polyphony in greater detail to understand > the logic. Having thought about polyphony in tab a little more I realise now there is a fundamental difficulty: it is quite possible to have an interval in time between two adjacent notes that cannot be represented as a single duration. In staff representation ties would be used to do this, but I don't think ties were used in baroque tab, were they? Even if they were, implementing them at this early stage would be a step too far, at least for me. So I plan to sidestep polyphony at present and concentrate on implementing lute tab from a single voice. There's plenty to do yet to achieve that in a form suitable for a LP patch. Trevor ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
Thomas Morley wrote Friday, September 09, 2016 11:31 PM Hi Harm back now from my week away ... > 2016-09-08 0:07 GMT+02:00 Trevor Daniels: >> >> But I don't understand why you >> used a rather complicated procedure to obtain durations. Could you >> not simply extract the durations from note events? > > In my opinion the historic lute tablatures were written disregarding > any polyphony as far as rhythmy are concerned, yes. > But this polyphony was always _meant_ and the player should respect it. > > For our coding this means an example like > > upper = { d'2 d' } > middle = { \override Rest.staff-position = #-1.5 r8 f r8 f r8 f r8 f } > lower = { a,4\rest d a,4\rest d } > > \score { > << > \new Staff << \clef "G_8" \upper \\ \lower \\ \middle >> > > \new TabStaff > << \clef "G_8" \upper \\ \lower \\ \middle >> > >> > \layout { >\context { >\TabStaff > stringTunings = \stringTuning >} > } > } > > should return proper polyphonic in Staff, and in TabStaff only a > single 8th indication for the overall rhythm should be printed. > This can be achieved with my proposal and would warrant the principle > of one source-code for Staff _and_ TabStaff. > I didn't found a method to do so with simple durations. OK, I see now why you need to extract the interval between a note and the subsequent note even when they are split between several voices. This interval then should be displayed as the "duration" of the first of the pair (unless it is unchanged from the previous one, of course) I agree this can't be done by looking solely at the duration of individual notes. However, your code doesn't quite work in all situations. If you replace the first f in the middle voice with a rest we should have a duration of 4 followed by one of 8, but the 8 is missing. > You seems to be of different opinion, for some cases you let > explicitely print the warning: > "Polyphony is not supported in lute tab" Well, I meant it wasn't supported in my simple implementation, not that it shouldn't be. > Always printing the duration at the start of every bar even if > unchanged happens sometimes, but sometimes not, Maybe let it depend on > a context-property? Yes, a sensible later step. > For the bass courses. > I didn't understand this point in your former mails. Now with your > code its clearer to me. > But why you do it this way? Isn't my implementation of > https://sourceforge.net/p/testlilyissues/issues/4768/ > sufficient? Well, to be honest I'd forgotten about this. But unfortunately it is incompatible with the nice fret number glyphs from Fronimo as that font doesn't include a '/'. However, as we can't adopt the Fronimo fonts anyway I'll revert to using your implementation in any future work. I need now to study your approach to polyphony in greater detail to understand the logic. Trevor ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
Hi Trevor, 2016-09-08 0:07 GMT+02:00 Trevor Daniels <t.dani...@treda.co.uk>: > > - Original Message - > From: "Thomas Morley" <thomasmorle...@gmail.com> > To: "Trevor Daniels" <t.dani...@treda.co.uk> > Cc: "Lily-Devel List" <lilypond-devel@gnu.org> > Sent: Sunday, September 04, 2016 7:28 AM > Subject: Re: Help with Scheme engraver please > > >> 2016-09-03 19:29 GMT+02:00 Thomas Morley <thomasmorle...@gmail.com>: >> >>> I've put some work on it. See attached duration-as-markup-5b-harm.ly >>> The general work should be clear from comments and descriptions. >>> There's some ugly code in it, although it works so far, wide room for >>> improvements still there. >>> Nevertheless it works now even in polyphonic. >> >> Please replace the coding in `stop-translation-timestep' with: >> > [snip] >> >> This will cure a bug with last notes starting at some moment, but with >> different durations. > > Thanks Harm, for this and the preceding mail. I've found them very > helpful. In particular, a simpler way to set stringTuning and how to set > persistent variables within engravers. But I don't understand why you > used a rather complicated procedure to obtain durations. Could you > not simply extract the durations from note events? In my opinion the historic lute tablatures were written disregarding any polyphony as far as rhythmy are concerned, yes. But this polyphony was always _meant_ and the player should respect it. For our coding this means an example like upper = { d'2 d' } middle = { \override Rest.staff-position = #-1.5 r8 f r8 f r8 f r8 f } lower = { a,4\rest d a,4\rest d } \score { << \new Staff << \clef "G_8" \upper \\ \lower \\ \middle >> \new TabStaff << \clef "G_8" \upper \\ \lower \\ \middle >> >> \layout { \context { \TabStaff stringTunings = \stringTuning <a, d f a d' f'> } } } should return proper polyphonic in Staff, and in TabStaff only a single 8th indication for the overall rhythm should be printed. This can be achieved with my proposal and would warrant the principle of one source-code for Staff _and_ TabStaff. I didn't found a method to do so with simple durations. You seems to be of different opinion, for some cases you let explicitely print the warning: "Polyphony is not supported in lute tab" > Actually I'd got quite a bit further than the simple example I posted, > and my current state is attached, extracting durations and pitches > from note-events, and detecting the start of bars by acknowledging > barline grobs. This version draws duration grobs whenever the > duration changes, and at the start of every bar, bass course > grobs below the tab, adds fingering and laissez vibrer slurs (I think > that's what they are used for.) Always printing the duration at the start of every bar even if unchanged happens sometimes, but sometimes not, Maybe let it depend on a context-property? For the bass courses. I didn't understand this point in your former mails. Now with your code its clearer to me. But why you do it this way? Isn't my implementation of https://sourceforge.net/p/testlilyissues/issues/4768/ sufficient? Didn't dive into it further, hopefully during the upcoming weekend ... Cheers, Harm ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
- Original Message - From: "Thomas Morley" <thomasmorle...@gmail.com> To: "Trevor Daniels" <t.dani...@treda.co.uk> Cc: "Lily-Devel List" <lilypond-devel@gnu.org> Sent: Sunday, September 04, 2016 7:28 AM Subject: Re: Help with Scheme engraver please > 2016-09-03 19:29 GMT+02:00 Thomas Morley <thomasmorle...@gmail.com>: > >> I've put some work on it. See attached duration-as-markup-5b-harm.ly >> The general work should be clear from comments and descriptions. >> There's some ugly code in it, although it works so far, wide room for >> improvements still there. >> Nevertheless it works now even in polyphonic. > > Please replace the coding in `stop-translation-timestep' with: > [snip] > > This will cure a bug with last notes starting at some moment, but with > different durations. Thanks Harm, for this and the preceding mail. I've found them very helpful. In particular, a simpler way to set stringTuning and how to set persistent variables within engravers. But I don't understand why you used a rather complicated procedure to obtain durations. Could you not simply extract the durations from note events? Actually I'd got quite a bit further than the simple example I posted, and my current state is attached, extracting durations and pitches from note-events, and detecting the start of bars by acknowledging barline grobs. This version draws duration grobs whenever the duration changes, and at the start of every bar, bass course grobs below the tab, adds fingering and laissez vibrer slurs (I think that's what they are used for.) There's quite a lot still wrong with this example, although it works in simple cases. You can see these problems listed in the TODOs. And the code needs some tidying up too as bits of it are rather messy (to say the least!). And it would probably be better to separate the generation of the two types of grobs into two engravers. You'll see I use the Fronimo glyphs for the bass course indications, and mensural flags for the durations. These are just for demonstration: we'd need a set of lute tab glyphs of our own to be defined at some stage. But this is now pretty close to Phase I which I defined in the note dated 22 Nov 2009, in this thread: http://lilypond-s-support-for-tablatures.3383434.n2.nabble.com/Baroque-lute-tablature-td4008032.html I probably will be somewhat unresponsive for 10 days or so, as we are away on a belated summer break next week. Trevor \version "2.19.46" % Example of using Scheme engravers to add markup based on % note duration and pitch % Avoids repeated durations on both chords and consecutive notes % Always prints duration at start of bar % Adds dots % Adds string indication in bar 3 % Adds stroke finger indications % Makes dots height not vary with duration % Adds glyphs for minims and semibreves % Fixes error message with avoid-slur % Adds string finger indications % Adds glissando to show repeated finger % (not good - each has to be positioned) % Removes debugging printouts in Lute_tab_duration_engraver % Uses note names in stringTuning (thanks Harm) % Places persistent variables inside engraver (thanks Harm) % Adds bass courses %{ TODO Error when finger is specified with slur Warning when bass course pitch is specified Handle notes with different durations at one musical moment better Need better way of linking notes with repeated right finger could this be detected and added automatically? Bass course pitches should not be hard-coded %} #(define (t->m t) "Return the current moment of translator object @var{t}." (ly:context-current-moment (ly:translator-context t))) #(define (duration-markup duration) "Returns flags corresponding to duration as markup, avoiding repeated symbol if duration has not changed." (define flag-glyph "") (define dots-glyph "") (let ((duration-log (ly:duration-log duration)) (duration-dots (ly:duration-dot-count duration))) ; obtain flag glyph (case duration-log ; TODO: replace with more suitable glyphs ((0) (set! flag-glyph (markup #:note "1" UP))) ((1) (set! flag-glyph (markup #:note "2" UP))) ((2) (set! flag-glyph (markup #:musicglyph "rests.M2mensural"))) ((3) (set! flag-glyph (markup #:musicglyph "flags.mensuralu03"))) ((4) (set! flag-glyph (markup #:musicglyph "flags.mensuralu04"))) ((5) (set! flag-glyph (markup #:musicglyph "flags.mensuralu05"))) ((6) (set! flag-glyph (markup #:musicglyph "flags.mensuralu06"))) (else (begin (ly:warning "Duration glyph not available for duration-log of ~a" duration-log) (set! flag-glyph " " ; obtain dots glyp
Re: Help with Scheme engraver please
2016-09-03 19:29 GMT+02:00 Thomas Morley: > I've put some work on it. See attached duration-as-markup-5b-harm.ly > The general work should be clear from comments and descriptions. > There's some ugly code in it, although it works so far, wide room for > improvements still there. > Nevertheless it works now even in polyphonic. Please replace the coding in `stop-translation-timestep' with: ((stop-translation-timestep translator) ; (format 1 "~16a: (stop-translation-timestep)\n" (t->m translator)) ;; needs to be here, otherwise the moments are not completely collected (let* (;; The last note-events may start at the same time-step, but ;; may have different durations. Thus we need to select the ;; one with the longest duration, to detemine which ;; duration-string should be used for make-note-markup in tab (last-notes-amount (length (car ((@@ (lily) split-at-predicate) equal? m-n (longest-last-ev (last (sort (take ev last-notes-amount) (lambda (e1 e2) (ly:durationduration-string x '())) moments-diffs) (list (ly:duration->string (ly:event-property longest-last-ev 'duration)) (for-each (lambda (g strg) (if (string-null? strg) (ly:grob-suicide! g) (begin (ly:grob-set-property! g 'direction UP) (ly:grob-set-property! g 'text (markup #:override '(style . mensural) #:note strg UP) (reverse grobs) (replace-adjacent-duplicates moment-diff-strings '() This will cure a bug with last notes starting at some moment, but with different durations. Cheers, Harm ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
2016-09-02 23:34 GMT+02:00 Trevor Daniels: > > Thomas Morley wrote Friday, September 02, 2016 8:22 PM > > >> 2016-09-02 13:05 GMT+02:00 Trevor Daniels : >>> >>> 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. >> >> I stumbled across you're printing a rest-glyph for a quarter-note. >> >> Eventually I might have some ideas, but there are a plethora of >> variants for historic tablaures. Which glyphs do you want to be >> printed above the TabStaff for the code below. Only flags, flags with >> stems, stems only for quarters, what to do for notes longer than a >> quarter? >> >> m = { \compressFullBarRests c'\maxima \longa \breve 1 2 4 8 16 32 } >> >> << >> \new MensuralVoice \m >> \new TabStaff \with { \revert TextScript.stencil } >> \new TabVoice >>\with { >> \consists \Lute_tab_duration_engraver >>} \m > > I really know very little about lute tablature, but I believe there are many > different styles. Should this ever get close to operational we'd need > to discuss which styles to support and what glyphs would be needed. > But I fear that's some way in the future. The mensural (and rest) glyphs > I used in this little example are just markers really, while I explore how to > deal with other aspects - fingering, bass courses, articulations, etc. > > Trevor Hi Trevor, I've put some work on it. See attached duration-as-markup-5b-harm.ly The general work should be clear from comments and descriptions. There's some ugly code in it, although it works so far, wide room for improvements still there. Nevertheless it works now even in polyphonic. For the ornaments you may be interested in Nicolas' engraver. Attached you'll find my fix to make it compile with newer devel-versions. Though I didn't do any testings for ornaments in TabStaff. You may notice the little bug I detected (close to the red exclamation mark in pdf), no clue how to fix this. Cheers, Harm \version "2.19.42" %% taken from: %% https://github.com/nsceaux/nenuvar/blob/master/common/side-ornementations.ily %% and adapted for v2.19.42 %%% %%% Utilities for defining new grobs, grob properties and music event types %%% (there should be built-in commands to do that in LilyPond) %%% #(define (define-grob-definition grob-name grob-entry) "Define a new grob and add it to `all-grob-definitions', after scm/define-grobs.scm fashion. After grob definitions are added, use: \\layout { \\context { \\Global \\grobdescriptions #all-grob-descriptions } } to register them." (let* ((meta-entry (assoc-get 'meta grob-entry)) (class(assoc-get 'class meta-entry)) (ifaces-entry (assoc-get 'interfaces meta-entry))) (set-object-property! grob-name 'translation-type? ly:grob-properties?) (set-object-property! grob-name 'is-grob? #t) (set! ifaces-entry (append (case class ((Item) '(item-interface)) ((Spanner) '(spanner-interface)) ((Paper_column) '((item-interface paper-column-interface))) ((System) '((system-interface spanner-interface))) (else '(unknown-interface))) ifaces-entry)) (set! ifaces-entry (uniq-list (sort ifaces-entry symbolhttp://lilypond.1069038.n5.nabble.com/crash-moving-DotColumn-td190493.html (set! (ly:grob-property dot-column 'positioning-done) (lambda (grob) (ly:dot-column::calc-positioning-done grob) (ly:grob-translate-axis! grob orn-width X) #t) ornementation)) #(define (head-ornementation-engraver-acknowledge-note-head engraver note-grob source-engraver) "Note head acknowledge method for the head ornementation engraver. When the note head event attached to the note head grob has ornementation events among its articulations, then create a HeadOrnementation grob" (let* ((note-event (ly:grob-property note-grob 'cause))) (for-each (lambda (articulation) (if (memq 'head-ornementation-event (ly:event-property articulation 'class)) (begin (if (markup? (ly:event-property articulation 'text-left)) (make-head-ornementation engraver
Re: Help with Scheme engraver please
Thomas Morley wrote Friday, September 02, 2016 8:22 PM > 2016-09-02 13:05 GMT+02:00 Trevor Daniels: >> >> 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. > > I stumbled across you're printing a rest-glyph for a quarter-note. > > Eventually I might have some ideas, but there are a plethora of > variants for historic tablaures. Which glyphs do you want to be > printed above the TabStaff for the code below. Only flags, flags with > stems, stems only for quarters, what to do for notes longer than a > quarter? > > m = { \compressFullBarRests c'\maxima \longa \breve 1 2 4 8 16 32 } > > << > \new MensuralVoice \m > \new TabStaff \with { \revert TextScript.stencil } > \new TabVoice >\with { > \consists \Lute_tab_duration_engraver >} \m I really know very little about lute tablature, but I believe there are many different styles. Should this ever get close to operational we'd need to discuss which styles to support and what glyphs would be needed. But I fear that's some way in the future. The mensural (and rest) glyphs I used in this little example are just markers really, while I explore how to deal with other aspects - fingering, bass courses, articulations, etc. Trevor ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
2016-09-02 13:05 GMT+02:00 Trevor Daniels: > > Simon, you wrote Friday, September 02, 2016 1:34 AM >> 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. Hi Trevor, I stumbled across you're printing a rest-glyph for a quarter-note. Eventually I might have some ideas, but there are a plethora of variants for historic tablaures. Which glyphs do you want to be printed above the TabStaff for the code below. Only flags, flags with stems, stems only for quarters, what to do for notes longer than a quarter? m = { \compressFullBarRests c'\maxima \longa \breve 1 2 4 8 16 32 } << \new MensuralVoice \m \new TabStaff \with { \revert TextScript.stencil } \new TabVoice \with { \consists \Lute_tab_duration_engraver } \m >> Cheers, Harm ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
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"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
Re: Help with Scheme engraver please
Hi Trevor, On 24.08.2016 11:51, Trevor Daniels wrote: David Kastrup wrote Wednesday, August 24, 2016 7:48 AM "Trevor Daniels"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? Best, Simon ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
"Trevor Daniels"writes: > David Kastrup wrote Wednesday, August 24, 2016 7:48 AM > > >> "Trevor Daniels" 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, and much better than the rather > terse sentence in the CG which misled me: > > "If useful things are to be done to the acknowledged grobs, this > should be deferred until all the acknowledging has finished, i.e., > store the acknowledged grobs and process the information in a > process-acknowledged () or stop-translation-timestep () function." > > I took what appeared to be the stop-translation-timestep option. You can still "process" parts of the grob there (if that means just reading out properties and possibly setting context properties based on them) but stop-translation-timestep is a cleanup hook, and other engravers might have already cleaned up stuff you might have wanted to use. And _creating_ grobs in there is clean out since engravers and other code may no longer be in a state where they could process them. -- David Kastrup ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
David Kastrup wrote Wednesday, August 24, 2016 7:48 AM > "Trevor Daniels"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, and much better than the rather terse sentence in the CG which misled me: "If useful things are to be done to the acknowledged grobs, this should be deferred until all the acknowledging has finished, i.e., store the acknowledged grobs and process the information in a process-acknowledged () or stop-translation-timestep () function." I took what appeared to be the stop-translation-timestep option. I'll take a time-out and prepare a patch for the CG based on your mail. Trevor ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
"Trevor Daniels"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. -- David Kastrup ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Help with Scheme engraver please
Hi Trevor, On Tue, Aug 23, 2016 at 3:54 PM, Trevor Danielswrote: > 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, but my > attempts all result in a LilyPond crash. I'm on Windows Vista, so the crash > code is not very helpful - 1073741819. > > Minimal examples below. The first creates a grob from the Listener and works > fine. The second tries to create a grob from stop-translator-timestep and > fails. > > What am I doing wrong? I can't explain what's wrong, but creating the grob in process-music works for me. You ought to check that you have an event with ly:stream-event? Hope this helps a little, David ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel
Help with Scheme engraver please
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, but my attempts all result in a LilyPond crash. I'm on Windows Vista, so the crash code is not very helpful - 1073741819. Minimal examples below. The first creates a grob from the Listener and works fine. The second tries to create a grob from stop-translator-timestep and fails. What am I doing wrong? This works: \version "2.19.46" engraver_demo = #(make-engraver (listeners ((note-event engraver event) (let ((grob (ly:engraver-make-grob engraver 'TextScript event))) (ly:grob-set-property! grob 'text "hi") \layout { \context { \Voice \consists \engraver_demo } } \relative { c'8 } This fails: \version "2.19.46" #(define ev #f) engraver_demo = #(make-engraver (listeners ((note-event engraver event) (set! ev event))) ((stop-translation-timestep engraver) (let ((grob (ly:engraver-make-grob engraver 'TextScript ev))) (ly:grob-set-property! grob 'text "hi" \layout { \context { \Voice \consists \engraver_demo } } \relative { c'8 } Thanks, Trevor ___ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel