Re: [large/complex projects] where should transpositions go?

2024-02-07 Thread Kieren MacMillan
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?

2024-02-06 Thread Martin Neubauer

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?

2024-01-30 Thread Kieren MacMillan
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?

2024-01-29 Thread Simon Albrecht

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?

2024-01-29 Thread Kieren MacMillan
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?

2024-01-29 Thread Valentin Petzel
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?

2024-01-29 Thread Kieren MacMillan
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?

2024-01-29 Thread Timothy Lanfear

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?

2024-01-28 Thread Wol

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?

2024-01-28 Thread Timothy Lanfear

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"