Re: [large/complex projects] where should transpositions go?
Hi Martin, > For quite a long time now I'm relying heavily on openlilylib's auto-transpose > module. In my experience it does play nicely together with the > edition-engraver. Oh, goodness… I think you may have shared this on the list before, but I didn’t quite understand how cool and powerful it was/is! > One caveat is its abuse of the \transposition command, which might throw > things off if you need midi output. But I don't do midi, so I wouldn't know... I outputted MIDI, and it clearly doesn’t work as expected. That *may* be a problem for me at some point in the future, but isn’t right now. > Attached is a silly little example I whacked together to make sure I wasn't > going to tell some nonsense. I jacked it up a bit — threw a few preliminary “curve balls” at it (e.g., separated global data into a variable, added an “internal” key change with “injected” transpositions around it, etc.) — and it handled them like a pro: SNIPPET BEGINS \version "2.25.10" \language "english" \include "oll-core/package.ily" \loadModule oll-misc.pitch.auto-transpose \loadPackage notation-fonts \loadPackage edition-engraver \addEdition test \consistToContexts #edition-engraver Score.Staff.Voice \editionMod test 4 0/4 trans.pose.Voice \transposition bf \editionMod test 8 0/4 trans.pose.Voice \transposition a \layout { \context { \Score \editionID ##f trans } } global = { \key d \major s1*5 \key f \major s1*5 } theNotes = { \repeat unfold 5 { d'1 } \repeat unfold 5 { f'1 } } \score { \new Staff \with { \editionID pose \autoTranspose } { << \global \theNotes >> \fine } \layout {} \midi {} } SNIPPET ENDS I’m 100% going to be using this in my framework — thank you so much!!! Kieren. __ My work day may look different than your work day. Please do not feel obligated to read or respond to this email outside of your normal working hours.
Re: [large/complex projects] where should transpositions go?
Hi Kieren, I'm somewhat late to the party, and hadn't looked to thoroughly at your example code, either, but I'd like to nevertheless share my take on one specific point: 3. Compare the voicing of m3 in the SATB and SA voicings: mm1-2 are different, but m3 is the same. How can I do this kind of thing with the least amount of code duplication? I don’t believe quoted music can be transposed directly (i.e., you need to create a second, pre-transposed, quotation); I can’t see how to inject a transposition (e.g., using the Edition-Engraver) into a specific part of a score/variable; I really don’t want to have to break every variable into multiple subvariables to handle every difference between voicings (nor do I want to have complete duplicates, one per voicing!); etc. For quite a long time now I'm relying heavily on openlilylib's auto-transpose module. In my experience it does play nicely together with the edition-engraver. One caveat is its abuse of the \transposition command, which might throw things off if you need midi output. But I don't do midi, so I wouldn't know... Attached is a silly little example I whacked together to make sure I wasn't going to tell some nonsense. All the best, Martin -- Wer mit dem gestern hier Vorgestellten hinreichend Erhellendes erfahren hat und auf den Geschmack gekommen ist, kann heute in den Wellenlängen des unserem Auge zugänglichen Bereiches der Elektromagnetischen Strahlung Pythagoräische Tripel suchen und einem Farbberater als Warteraumtapezierung vorschlagen.\version "2.25.12" \include "oll-core/package.ily" \loadModule oll-misc.pitch.auto-transpose \loadPackage notation-fonts \loadPackage edition-engraver \addEdition test \consistToContexts #edition-engraver Score.Staff.Voice \editionMod test 6 0/4 trans.pose.Voice \transposition bes \layout { \context { \Score \editionID ##f trans %edition-engraver-log = ##t } \context { \Voice %edition-engraver-log = ##t } } \new Staff \with { \editionID pose \autoTranspose } { \repeat unfold 10 { c'1 } \fine }
Re: [large/complex projects] where should transpositions go?
Hi Simon, > I’d like to share two approaches I’ve developed for such issues. Thanks for all this! > Firstly, I couldn’t take time to study your setup and how that makes these > approaches viable or not—sorry for that. No worries — I recognize it’s a lot for anyone to try to wrap their head around if they’re not already in it to begin with. > Secondly, if possible, I always try to use vanilla LilyPond tools Me, too! > I prefer using tags as far as they may take me over using the editionEngraver Me, too! I just: (a) consider the Edition-Engraver to fall under the “vanilla Lilypond” rubric in the same way as other bespoke Scheme code does; and (b) have a lower limit than other people on how far tags “optimally go”. ;) > I prefer complicated \include setups with Scheme conditionals over using > make. This is in an attempt to improve maintainability and reduce overhead. 100%. >> I don’t believe quoted music can be transposed directly (i.e., you need to >> create a second, pre-transposed, quotation) > What I’ve started doing after running into this problem is for example > > sop = { %{soprano music%} } > \addQuote "sop" \sop > \addQuote "sop8vb" \transpose c c, \sop Yes, that’s what I do (cf. “you need to create a second, pre-transposed, quotation”). I just wish it didn’t require that. > Recently I even put this into my standard include files to avoid having that > third (or more) lines from the example: That’s quite useful, actually. Thanks! (I really need to get more sugar in my Lilypond “diet”… I’m just working so hard on so many things that I never seem to have time to sit back and refine the sugar. ) > Another technique is this: > > %%% from my library/ly-utility.ily file > musicFunctionDummy = #(define-music-function (mus) (ly:music?) mus) > > addToplevelMusicFunctions = > #(define-scheme-function (names) (symbol-list-or-symbol?) >(let* ((name-list (if (list? names) names (list names))) > (lookup-function >(lambda (name) (let ((fn (ly:parser-lookup name))) > (if (equal? fn '()) > (begin > (ly:warning "Cannot find music function > ~a to add to toplevel functions.\n" name) > musicFunctionDummy) > fn > (fn-list (map lookup-function name-list))) > (set! toplevel-music-functions >(append fn-list toplevel-music-functions > %%% > > Example usage: > > %%% > transposer = \transpose g f \etc > enharmonicsChooser = \keepWithTag #'originalSpelling \etc > \addToplevelMusicFunctions transposer,enharmonicsChooser > %%% Currently I’m neither quite sure how this works, nor if/how it might be useful to me… but I appreciate the example, and will look into it! Thanks, Kieren. __ My work day may look different than your work day. Please do not feel obligated to read or respond to this email outside of your normal working hours.
Re: [large/complex projects] where should transpositions go?
Dear Kieren, I’d like to share two approaches I’ve developed for such issues. There’s two caveats: Firstly, I couldn’t take time to study your setup and how that makes these approaches viable or not—sorry for that. Secondly, if possible, I always try to use vanilla LilyPond tools, so I prefer using tags as far as they may take me over using the editionEngraver and I prefer complicated \include setups with Scheme conditionals over using make. This is in an attempt to improve maintainability and reduce overhead. On 27.01.24 23:03, Kieren MacMillan wrote: I don’t believe quoted music can be transposed directly (i.e., you need to create a second, pre-transposed, quotation) What I’ve started doing after running into this problem is for example sop = { %{soprano music%} } \addQuote "sop" \sop \addQuote "sop8vb" \transpose c c, \sop Recently I even put this into my standard include files to avoid having that third (or more) lines from the example: addQuote = #(define-void-function (name music) (string? ly:music?) (_i "Define @var{music} as a quotable music expression named @var{name}, along with transposed versions @var{name8va} and @var{name8vb}.") (add-quotable name music) (add-quotable (string-append name "8va") #{ \transpose c c' $music #}) (add-quotable (string-append name "8vb") #{ \transpose c c, $music #})) Another technique is this: %%% from my library/ly-utility.ily file musicFunctionDummy = #(define-music-function (mus) (ly:music?) mus) addToplevelMusicFunctions = #(define-scheme-function (names) (symbol-list-or-symbol?) (let* ((name-list (if (list? names) names (list names))) (lookup-function (lambda (name) (let ((fn (ly:parser-lookup name))) (if (equal? fn '()) (begin (ly:warning "Cannot find music function ~a to add to toplevel functions.\n" name) musicFunctionDummy) fn (fn-list (map lookup-function name-list))) (set! toplevel-music-functions (append fn-list toplevel-music-functions %%% Example usage: %%% transposer = \transpose g f \etc enharmonicsChooser = \keepWithTag #'originalSpelling \etc \addToplevelMusicFunctions transposer,enharmonicsChooser %%% All the best for your projects! Simon
Re: [large/complex projects] where should transpositions go?
Hi Valentin, I’m… a bit gobsmacked. > I think with large projects it is a good idea to establish a nice data flow. Agreed. > Basically your code does different things. For one thing you have musical > data, > for another thing you have formatting of said data, and then you also have > functions and stuff. Still on the same page with you. > Depending on your particular needs you can create you own way of specifying > data, layouts, stylesheets and such, and the cleaner you can separate these > the better you will be able to transparently do complex things. 100% >> 1. Should I have one output file per score, or use \book? I assume if it’s >> multiple files, and I want to keep them synchronized, I would want to use >> make (or similar) to trigger a compilation of all of them at once? > > Depends on what you want. Okay, I figured as much. ;) >> 2. Am I <<>>-ing the \global at the best spot(s)? > You could also add \global once in a toplevel DevNull Now *that* is a use of DevNull I’ve never considered (or even seen) before. Fascinating! > With such small differences it might be useful to notate chords by voices << > ... >> instead. I love this idea! > Here is a sketch demonstrating a few concepts of how you could specify data > and have custom music function make sense of it Here’s where my gob got smacked. If I understand correctly what you’ve done here — and TBH it will still take me a little time and testing to fully get my head around exactly how it’s working and the full scope/applicability — this approach is exactly the level of abstraction and reuse/adjustability I need. Thank you so much! I’ll get back to you if I have any questions. Best, Kieren. __ My work day may look different than your work day. Please do not feel obligated to read or respond to this email outside of your normal working hours.
Re: [large/complex projects] where should transpositions go?
Hi Kieren, I think with large projects it is a good idea to establish a nice data flow. Basically your code does different things. For one thing you have musical data, for another thing you have formatting of said data, and then you also have functions and stuff. Depending on your particular needs you can create you own way of specifying data, layouts, stylesheets and such, and the cleaner you can separate these the better you will be able to transparently do complex things. > 1. Should I have one output file per score, or use \book? I assume if it’s > multiple files, and I want to keep them synchronized, I would want to use > make (or similar) to trigger a compilation of all of them at once? Depends on what you want. > 2. Am I <<>>-ing the \global at the best spot(s)? You could also add \global once in a toplevel DevNull > 3. Compare the voicing of m3 in the SATB and SA voicings: mm1-2 are > different, but m3 is the same. How can I do this kind of thing with the > least amount of code duplication? I don’t believe quoted music can be > transposed directly (i.e., you need to create a second, pre-transposed, > quotation); I can’t see how to inject a transposition (e.g., using the > Edition-Engraver) into a specific part of a score/variable; I really don’t > want to have to break every variable into multiple subvariables to handle > every difference between voicings (nor do I want to have complete > duplicates, one per voicing!); etc. With such small differences it might be useful to notate chords by voices << ... >> instead. Here is a sketch demonstrating a few concepts of how you could specify data and have custom music function make sense of it: %% %% replaceWithTag = #(define-music-function (tags rep music) (symbol-list-or-symbol? ly:music? ly:music?) (music-map (lambda (x) (if ((tags-remove-predicate tags) x) x rep)) music)) alternatives = #(define-music-function (names musics) (symbol-list? ly:music?) (ly:music-set-property! musics 'alternatives names) musics) selectAlternative = #(define-music-function (alt music) (symbol? ly:music?) (music-map (lambda (x) (if (ly:music-property x 'alternatives #f) (assoc-get alt (map cons (ly:music-property x 'alternatives) (ly:music-property x 'elements))) x)) music)) preferredClef = \tag preferred-clef \clef "treble" reflow = #(define-music-function (style music) (list? ly:music?) #{ \transpose #(ly:make-pitch 0 0) #(ly:make-pitch (assoc-get 'octave style 0) 0) \removeWithTag #(assoc-get 'removes style '()) \selectAlternative #(assoc-get 'alternative style 'default) \replaceWithTag preferred-clef \clef #(assoc-get 'preferred-clef style "treble") #music #}) styles.tenor.preferred-clef = "treble_8" styles.tenor.octave = -1 styles.bass.preferred-clef = "bass" styles.bass.octave = -1 styles.choir_satb.alternative = #'sa styles.choir_sa.alternative = #'satb \language "english" global = { \tempo "Fast" \key c \major s1 \tag full { s1 } \bar "||" \key d \major s1 \bar "|." } voice.michael = { \preferredClef c''4 4 4 4 \tag full { g'4 4 a'4 4 } d'4 4 4 4 } voice.chorus = \new Voice << { c'4 4 4 4 \tag full { b4 4 cs'4 4 } d'4 4 4 4 } { e'4 4 4 4 \tag full { d'4 4 e'4 4 } fs'4 4 4 4 } { \alternatives satb,sa << { g4 4 4 4 \tag full { g4 4 a4 4 } } { g'4 4 4 4 \tag full { g'4 4 a'4 4 } } >> a4 4 4 4 } >> \score { << \new Devnull \global \new Staff { \voice.michael } \new Staff \reflow \styles.tenor { \voice.michael } \new Staff \reflow \styles.bass { \voice.michael } \new Staff \reflow \styles.choir_satb { \voice.chorus } \new Staff \reflow \styles.choir_sa { \voice.chorus } >> } %% %% Cheers, Valentin signature.asc Description: This is a digitally signed message part.
Re: [large/complex projects] where should transpositions go?
Hi Timothy, > If I have understood Kieren correctly, he wants the option to configure his > score with a part either sung by a tenor voice at written pitch, or a treble > voice one octave higher. Correct. > The attached files illustrate a couple of suggestions that might help. > • Set up new contexts (TrebleStaff, TenorStaff) that automatically > insert the right clef, and transpose the notes up an octave in the > TrebleStaff. > • Use a tag group that is adjusted to build the various styles of > score, while keeping the definition of the scores fixed. This is a very interesting approach, which I will consider seriously for many of the applications I have. In particular, it is superior to my current “manually insert \transpose commands all over the place“ method. (And, p.s., I love the small but important abstractions you also implemented, like \KMTags — every reduction in duplication helps in such a complex/complicated structure!) The one constraint/situation this might not handle is when the transposition/octavation happens *mid-system*. I could, of course, just accept that I always have to end a system and French the staves appropriately… but at this stage of investigation, I want to know all of my options, and the pros/cons of each approach. Many thanks for this solution! Kieren. __ My work day may look different than your work day. Please do not feel obligated to read or respond to this email outside of your normal working hours.
Re: [large/complex projects] where should transpositions go?
On 28/01/2024 22:16, Wol wrote: On 28/01/2024 21:56, Timothy Lanfear wrote: Set up new contexts (TrebleStaff, TenorStaff) that automatically insert the right clef, and transpose the notes up an octave in the TrebleStaff. Are the notes supposed to be PLAYED an octave higher/lower, or just written. If I have understood Kieren correctly, he wants the option to configure his score with a part either sung by a tenor voice at written pitch, or a treble voice one octave higher. -- Timothy Lanfear, Bristol, UK.
Re: [large/complex projects] where should transpositions go?
On 28/01/2024 21:56, Timothy Lanfear wrote: Set up new contexts (TrebleStaff, TenorStaff) that automatically insert the right clef, and transpose the notes up an octave in the TrebleStaff. Are the notes supposed to be PLAYED an octave higher/lower, or just written. Cause if they're just to be written, then don't transpose, just use the treble_8 or treble^8 clefs (not sure whether I've got the latter right :-) But I use treble_8 all the time for my trombone music ... Cheers, Wol
Re: [large/complex projects] where should transpositions go?
On 27/01/2024 22:03, Kieren MacMillan wrote: Hi all, So… At the bottom of this email, I’ve included a somewhat-M W E of something I’m wrestling with around all this stuff. You’ll see I have a ScoreMarks.ily file (one of many \includes, but needed here because the structure of the vc and pc are slightly different!), a notes.ily file (with all the note-code), and output files. There are *so* many variables on the input side in this industry (musical theatre): show version (cuts, etc.), voicing (different characters can be played by people singing in different clefs), chorus voicing (SATB? just SA?), etc. I’m trying to come up with a structure/workflow/plan that gives me maximum control and flexibility with minimum complexity (all terms relative, obviously!). Questions: 1. Should I have one output file per score, or use \book? I assume if it’s multiple files, and I want to keep them synchronized, I would want to use make (or similar) to trigger a compilation of all of them at once? 2. Am I <<>>-ing the \global at the best spot(s)? 3. Compare the voicing of m3 in the SATB and SA voicings: mm1-2 are different, but m3 is the same. How can I do this kind of thing with the least amount of code duplication? I don’t believe quoted music can be transposed directly (i.e., you need to create a second, pre-transposed, quotation); I can’t see how to inject a transposition (e.g., using the Edition-Engraver) into a specific part of a score/variable; I really don’t want to have to break every variable into multiple subvariables to handle every difference between voicings (nor do I want to have complete duplicates, one per voicing!); etc. Given Lilypond’s current powers and limitations, what’s my best path forward? At this point, even a high-level discussion would be really appreciated: As you can probably imagine, the number of permutations and combinations are ganging up on me, and I can’t grapple with them all myself. Thanks, Kieren. The attached files illustrate a couple of suggestions that might help. * Set up new contexts (TrebleStaff, TenorStaff) that automatically insert the right clef, and transpose the notes up an octave in the TrebleStaff. * Use a tag group that is adjusted to build the various styles of score, while keeping the definition of the scores fixed. -- Timothy Lanfear, Bristol, UK. \version "2.25.10" \language "english" global = { \tempo "Fast" \key c \major s1 \tag #'full { s1 } \bar "||" \key d \major s1 \bar "|." } Michael_notes = { c'4 4 4 4 \tag #'full { g4 4 a4 4 } d4 4 4 4 } chorus_notes = { \tag #'satb { 4 4 4 4 \tag #'full { 4 4 4 4 } 4 4 4 4 } \tag #'sa { 4 4 4 4 \tag #'full { 4 4 4 4 } 4 4 4 4 } } theChords = \chordmode { c1 \tag #'full { g2 a } d1 } acc_notes_upper = { c''4 4 4 4 \tag #'full { g'4 4 a'4 4 } d'4 4 4 4 } acc_notes_lower = { \clef bass c4 4 4 4 \tag #'full { g,4 4 a,4 4 } d,4 4 4 4 } vox = << \new \MichaelStaff \new Voice << \global \Michael_notes >> \new Staff \new Voice << \global \chorus_notes >> %% there would potentially be a lot of other vocal/choral parts in this blob >> vc = << \new ScoreMarks \global \new ChordNames \theChords \vox >> pc = << \new ScoreMarks \global \vox \new PianoStaff << \new Staff << \global \acc_notes_upper >> \new ChordNames \theChords \new Staff << \global \acc_notes_lower >> >> >> \version "2.25.10" \language "english" \paper { tagline = ##f ragged-bottom = ##t indent = 0 } Octave_transpose_engraver = #(lambda(context) (make-engraver (listeners ; transpose note-event ((note-event engraver event) (ly:music-transpose (ly:event-property event 'music-cause) (ly:make-pitch 1 0 0)) \layout { \context { \Staff \name TrebleStaff \alias Staff \accepts Voice \clef "treble" \with { \consists \Octave_transpose_engraver } } \context { \Staff \name TenorStaff \alias Staff \accepts Voice \clef "treble_8" } \inherit-acceptability TenorStaff Staff \inherit-acceptability TrebleStaff Staff } %%% ScoreMarks.ily \layout { \context { \type "Engraver_group" \name ScoreMarks keepAliveInterfaces = #'( metronome-mark-interface ) rehearsalMarkFormatter = #format-mark-box-alphabet \consists "Axis_group_engraver" \override VerticalAxisGroup.staff-affinity = #DOWN \override VerticalAxisGroup.nonstaff-relatedstaff-spacing = #'((basic-distance . 3) (minimum-distance . 3) (padding . 1.5)) \consists "Metronome_mark_engraver" \override MetronomeMark.Y-offset = #0 \override MetronomeMark.outside-staff-priority = #50 \override MetronomeMark.break-align-symbols = #'(left-edge staff-bar clef time-signature key-signature) \override MetronomeMark.non-break-align-symbols = #'(paper-column-interface) \consists "Mark_engraver"