Re: Enharmonically override key signature

2021-04-02 Thread Kieren MacMillan
Hi Jean,

> you need \new Voice here or separate staves are created.

D'oh! Just wasn’t thinking… Thanks.

> Other than that, it seems to work fine -- amended input and output attached.

Nice!

> Is there anything wrong with it

I’ll go back to some of my more complicated multi-instrumentalist pieces and 
see if it solves those. If not, I’ll send an MWCE (Minimal Working 
Counter-Example).

> other than the aforementioned \relative issue?

Oh, imma gonna keep my mouth shut about that…  ;)

Thanks,
Kieren.


Kieren MacMillan, composer (he/him/his)
‣ website: www.kierenmacmillan.info
‣ email: kie...@kierenmacmillan.info




Re: Enharmonically override key signature

2021-04-02 Thread Jean Abou Samra


Le 02/04/2021 à 22:15, Kieren MacMillan a écrit :

Hi Jean,


Something like the attached?

It breaks when I abstract the keys:

%%%
global = {
   \key aeses \major
   s1
   \key cis \minor
   s1
}

notes = \relative {
   aeses'8 beses ces deses eeses fes ges aeses
   cis, dis e fis gis a bis cis
}

music = <<
   << \global \notes >>


Well, you need \new Voice here or separate staves
are created. Other than that, it seems to work
fine -- amended input and output attached. Is
there anything wrong with it, other than the
aforementioned \relative issue?

Best,
Jean
\version "2.22.0"

#(use-modules (ice-9 receive))

#(define possible-naturalizations
   (list
 #{ deses #}
 #{ bis #}))

#(define no-naturalization
   #{ c #})


#(define (key-alterations context pitch-alist)
   "Compute alterations in the key, based on the pitch-alist.

This replicates the action of Key_engraver::read_event in lily/key-engraver.cc."
   (let loop ((alist (list-copy pitch-alist))
  (order (ly:context-property context 'keyAlterationOrder))
  (accidentals '()))
 (if (or (null? alist)
 (null? order))
 (append
   (filter-map
 (lambda (entry)
   (and (not (zero? (cdr entry)))
; No, don't warn, because we may get very
; weird accidentals in the process of finding
; the best key.
entry))
 alist)
   (reverse! accidentals))
 (let* ((entry (car order))
(head (member entry alist))
(found (and head (car head)))
(remaining-order (cdr order)))
   (if found
   (loop (delete! found alist)
 remaining-order
 (cons found accidentals))
   (loop alist
 remaining-order
 accidentals))


#(define (alteration-number accidentals)
   "Compute the number of accidentals in this key, taking double accidentals into account."
   (* 2 (apply + (map abs (map cdr accidentals)

#(define (best-naturalization context tonic pitch-alist alterations)
   "Determine best tonic to minimize the number of alterations.

Receives pre-computed alterations for the base tonic, to avoid calculating
them again.  Returns the best alterations found, for the same reason.

This applies a very simple-minded algorithm: try two possible ways to
naturalize, changing flats to sharps or sharps to flats, and return the
best one among the default and these two."
   (let loop ((best-naturalization-found tonic)
  (best-alterations-found alterations)
  (changed #f)
  (naturalizations-to-try possible-naturalizations))
 (if (null? naturalizations-to-try)
 (values best-naturalization-found best-alterations-found changed)
 (let* ((naturalization (car naturalizations-to-try))
(remaining-naturalizations (cdr naturalizations-to-try))
(new-pitch (ly:pitch-transpose tonic naturalization))
(new-pitch-alist (ly:transpose-key-alist pitch-alist naturalization))
(new-alterations (key-alterations context new-pitch-alist)))
   (if (< (alteration-number new-alterations)
  (alteration-number best-alterations-found))
   (loop naturalization
 new-alterations
 #t
 remaining-naturalizations)
   (loop best-naturalization-found
 best-alterations-found
 changed
 remaining-naturalizations))


#(define (naturalize-note! event naturalization)
   (ly:event-set-property!
 event
 'pitch
 (ly:pitch-transpose (ly:event-property event 'pitch)
 naturalization)))


#(define (reset-naturalization! context)
   (ly:context-set-property! context 'currentNaturalization no-naturalization))


#(set-object-property! 'currentNaturalization 'translation-type? ly:pitch?)

#(define (Naturalize_engraver context)
   (let ((notes-with-original-pitches '()))
 (make-engraver
   (listeners
 ((note-event engraver event)
(set! notes-with-original-pitches
  (cons
(cons event
  (ly:event-property event 'pitch))
notes-with-original-pitches))
(naturalize-note! event
  (ly:context-property context 'currentNaturalization)))
 ((key-change-event engraver event)
(let* ((tonic (ly:event-property event 'tonic))
   (pitch-alist (ly:event-property event 'pitch-alist))
   (default-alterations
 (key-alterations context pitch-alist)))
  ; Find the best key to minimize accidentals.  If it
  ; is different from what we had (that is, we managed
   

Re: Enharmonically override key signature

2021-04-02 Thread Jean Abou Samra

Hello,

Le 30/03/2021 à 03:33, Kieren MacMillan a écrit :

Hi Craig,


That worked for my over-simplified MWE. But here's my real-world problem with 
multiple key changes. There are only some that need to be over-ridden 
enharmonically. See bar 2 of the Alto Sax where I'd like to override this key 
signature without changing the whole global setup. Is this possible?


I have to say that in 99.99% of cases, "Is this
possible?" is a rhetorical question in LilyPond.


If it is, I can’t wait to see the solution… As the composer and arranger of 
musical theatre and other multi-instrumentalist music, Lilypond’s awkward 
handling of key signatures and transposition is a long-time thorn in my side.

David K once devised a rather brilliant almost-solution (cf. 
),
 but it wasn’t able to handle the high abstraction of my Lilypond code. There was a 
suggestion that an “enharmonize-engraver” might solve the problem, but I don’t think 
anyone tackled that.



Something like the attached? While admittedly ugly and
in need for more testing, it should provide
a start. I would be curious of better approaches
others may think of.

There is a big drawback: \relative changes behavior
in the naturalized version. I haven't investigated
how to fix it yet.

Regards,
Jean

\version "2.22.0"

#(use-modules (ice-9 receive))

#(define possible-naturalizations
   (list
 #{ deses #}
 #{ bis #}))

#(define no-naturalization
   #{ c #})


#(define (key-alterations context pitch-alist)
   "Compute alterations in the key, based on the pitch-alist.

This replicates the action of Key_engraver::read_event in lily/key-engraver.cc."
   (let loop ((alist (list-copy pitch-alist))
  (order (ly:context-property context 'keyAlterationOrder))
  (accidentals '()))
 (if (or (null? alist)
 (null? order))
 (append
   (filter-map
 (lambda (entry)
   (and (not (zero? (cdr entry)))
; No, don't warn, because we may get very
; weird accidentals in the process of finding
; the best key.
entry))
 alist)
   (reverse! accidentals))
 (let* ((entry (car order))
(head (member entry alist))
(found (and head (car head)))
(remaining-order (cdr order)))
   (if found
   (loop (delete! found alist)
 remaining-order
 (cons found accidentals))
   (loop alist
 remaining-order
 accidentals))


#(define (alteration-number accidentals)
   "Compute the number of accidentals in this key, taking double accidentals into account."
   (* 2 (apply + (map abs (map cdr accidentals)

#(define (best-naturalization context tonic pitch-alist alterations)
   "Determine best tonic to minimize the number of alterations.

Receives pre-computed alterations for the base tonic, to avoid calculating
them again.  Returns the best alterations found, for the same reason.

This applies a very simple-minded algorithm: try two possible ways to
naturalize, changing flats to sharps or sharps to flats, and return the
best one among the default and these two."
   (let loop ((best-naturalization-found tonic)
  (best-alterations-found alterations)
  (changed #f)
  (naturalizations-to-try possible-naturalizations))
 (if (null? naturalizations-to-try)
 (values best-naturalization-found best-alterations-found changed)
 (let* ((naturalization (car naturalizations-to-try))
(remaining-naturalizations (cdr naturalizations-to-try))
(new-pitch (ly:pitch-transpose tonic naturalization))
(new-pitch-alist (ly:transpose-key-alist pitch-alist naturalization))
(new-alterations (key-alterations context new-pitch-alist)))
   (if (< (alteration-number new-alterations)
  (alteration-number best-alterations-found))
   (loop naturalization
 new-alterations
 #t
 remaining-naturalizations)
   (loop best-naturalization-found
 best-alterations-found
 changed
 remaining-naturalizations))


#(define (naturalize-note! event naturalization)
   (ly:event-set-property!
 event
 'pitch
 (ly:pitch-transpose (ly:event-property event 'pitch)
 naturalization)))


#(define (reset-naturalization! context)
   (ly:context-set-property! context 'currentNaturalization no-naturalization))


#(set-object-property! 'currentNaturalization 'translation-type? ly:pitch?)

#(define (Naturalize_engraver context)
   (let ((notes-with-original-pitches '()))
 (make-engraver
   

Re: Enharmonically override key signature

2021-04-02 Thread Kieren MacMillan
Hi Jean,

> Something like the attached?

It breaks when I abstract the keys:

%%%
global = {
  \key aeses \major
  s1
  \key cis \minor
  s1
}

notes = \relative {
  aeses'8 beses ces deses eeses fes ges aeses
  cis, dis e fis gis a bis cis
}

music = <<
  << \global \notes >>
  \transpose ees c << \global \notes >>
>>
%%%

Any thoughts about that?

Thanks,
Kieren.


Kieren MacMillan, composer (he/him/his)
‣ website: www.kierenmacmillan.info
‣ email: kie...@kierenmacmillan.info




Re: Enharmonically override key signature

2021-03-30 Thread Christian Masser
Hi Craig!

You might try to tag the key signatures:

\version "2.20.00"
\language "english"

\include "enharmonic.ly"

fluteNotes = { \repeat unfold 3 { c'4 d' e' f' } }

altosaxNotes = \transpose c' ef
{ \repeat unfold 3 { c'4 d' e' f' } }

global = {
  \key bf \major
  s1
  \tag #'flatMusic { \key cf \major }
  \tag #'generalMusic { \key b \major }
  s1
  \key ef \major
  s1
}

\score {
  <<
\new Staff {
  \set Staff.instrumentName = "Flute"
  <<
\keepWithTag #'generalMusic \global
\fluteNotes
  >>
}
\new Staff {
  \set Staff.instrumentName = "Alto Sax"
  \transpose ef c'
  <<
\keepWithTag #'flatMusic \global
\altosaxNotes
  >>
  }
  >>
}

It's not as elegant as having it automated, but it worked for me at the few
occasions, where I had that problem. You only need to be cautious about
using \global without a \keepWithTag, but Lilypond will give you a warning
about colliding key signatures then.

All the best
Christian

Am Di., 30. März 2021 um 01:43 Uhr schrieb Craig Dabelstein <
craig.dabelst...@gmail.com>:

> Thanks Kieren. That worked for my over-simplified MWE. But here's my
> real-world problem with multiple key changes. There are only some that need
> to be over-ridden enharmonically. See bar 2 of the Alto Sax where I'd like
> to override this key signature without changing the whole global setup. Is
> this possible?
>
> All the best,
>
> Craig
>
> %%%
>
> \version "2.20.00"
> \language "english"
>
> \include "enharmonic.ly"
>
> fluteNotes = { \repeat unfold 3 { c'4 d' e' f' } }
>
> altosaxNotes = \transpose c' ef
> { \repeat unfold 3 { c'4 d' e' f' } }
>
> global = {
>   \key bf \major
>   s1
>   \key b \major
>   s1
>   \key ef \major
>   s1
> }
>
> \score {
>   <<
> \new Staff {
>   \set Staff.instrumentName = "Flute"
>   <<
> \global
> \fluteNotes
>   >>
> }
> \new Staff {
>   \set Staff.instrumentName = "Alto Sax"
>   \transpose ef c'
>   <<
> \global
> \altosaxNotes
>   >>
>   }
>   >>
> }
>
> %%
>
>
> Craig Dabelstein
> Owner, Maxime's Music
> cr...@concertbandmusicstore.com
> 19 Twelfth Ave, Kedron QLD 4031
> 
> [image: App Social Buttons Image]
>    [image: App Social
> Buttons Image] 
> Maxime's Music [image: arrow] 
> Create your own email signature
> 
>
> On Tue, 30 Mar 2021 at 09:23, Kieren MacMillan <
> kieren_macmil...@sympatico.ca> wrote:
>
>> Hi Craig,
>>
>> > In this snippet, how can I override the Alto Sax key signature so it
>> displays as A-flat major instead of G-sharp major?
>>
>> \transpose ds c'
>>
>> But then you’ll probably want the old “naturalize notes” snippet
>> (wherever that is…).
>>
>> Hope that helps!
>> Kieren.
>> 
>>
>> Kieren MacMillan, composer (he/him/his)
>> ‣ website: www.kierenmacmillan.info
>> ‣ email: kie...@kierenmacmillan.info
>>
>>


Re: Enharmonically override key signature

2021-03-29 Thread Kieren MacMillan
Hi Craig,

> That worked for my over-simplified MWE. But here's my real-world problem with 
> multiple key changes. There are only some that need to be over-ridden 
> enharmonically. See bar 2 of the Alto Sax where I'd like to override this key 
> signature without changing the whole global setup. Is this possible?

If it is, I can’t wait to see the solution… As the composer and arranger of 
musical theatre and other multi-instrumentalist music, Lilypond’s awkward 
handling of key signatures and transposition is a long-time thorn in my side.

David K once devised a rather brilliant almost-solution (cf. 
),
 but it wasn’t able to handle the high abstraction of my Lilypond code. There 
was a suggestion that an “enharmonize-engraver” might solve the problem, but I 
don’t think anyone tackled that. And of course, that thread is nearly a decade 
old — there may have been improvements since then which make the problem easier 
to tackle. (Aaron: Up for the challenge? LOL)

Cheers,
Kieren.


Kieren MacMillan, composer (he/him/his)
‣ website: www.kierenmacmillan.info
‣ email: kie...@kierenmacmillan.info




Re: Enharmonically override key signature

2021-03-29 Thread Craig Dabelstein
Thanks Kieren. That worked for my over-simplified MWE. But here's my
real-world problem with multiple key changes. There are only some that need
to be over-ridden enharmonically. See bar 2 of the Alto Sax where I'd like
to override this key signature without changing the whole global setup. Is
this possible?

All the best,

Craig

%%%

\version "2.20.00"
\language "english"

\include "enharmonic.ly"

fluteNotes = { \repeat unfold 3 { c'4 d' e' f' } }

altosaxNotes = \transpose c' ef
{ \repeat unfold 3 { c'4 d' e' f' } }

global = {
  \key bf \major
  s1
  \key b \major
  s1
  \key ef \major
  s1
}

\score {
  <<
\new Staff {
  \set Staff.instrumentName = "Flute"
  <<
\global
\fluteNotes
  >>
}
\new Staff {
  \set Staff.instrumentName = "Alto Sax"
  \transpose ef c'
  <<
\global
\altosaxNotes
  >>
  }
  >>
}

%%


Craig Dabelstein
Owner, Maxime's Music
cr...@concertbandmusicstore.com
19 Twelfth Ave, Kedron QLD 4031 
[image: App Social Buttons Image]
   [image: App Social
Buttons Image] 
Maxime's Music [image: arrow] 
Create your own email signature


On Tue, 30 Mar 2021 at 09:23, Kieren MacMillan <
kieren_macmil...@sympatico.ca> wrote:

> Hi Craig,
>
> > In this snippet, how can I override the Alto Sax key signature so it
> displays as A-flat major instead of G-sharp major?
>
> \transpose ds c'
>
> But then you’ll probably want the old “naturalize notes” snippet (wherever
> that is…).
>
> Hope that helps!
> Kieren.
> 
>
> Kieren MacMillan, composer (he/him/his)
> ‣ website: www.kierenmacmillan.info
> ‣ email: kie...@kierenmacmillan.info
>
>


Re: Enharmonically override key signature

2021-03-29 Thread Kieren MacMillan
Hi Craig,

> In this snippet, how can I override the Alto Sax key signature so it displays 
> as A-flat major instead of G-sharp major?

\transpose ds c'

But then you’ll probably want the old “naturalize notes” snippet (wherever that 
is…).

Hope that helps!
Kieren.


Kieren MacMillan, composer (he/him/his)
‣ website: www.kierenmacmillan.info
‣ email: kie...@kierenmacmillan.info




Enharmonically override key signature

2021-03-29 Thread Craig Dabelstein
Hi all,

In this snippet, how can I override the Alto Sax key signature so it
displays as A-flat major instead of G-sharp major?

\version "2.20.00"
\language "english"

fluteNotes = { c'4 d' e' f' }

altosaxNotes = \transpose c' ef
{ c'4 d' e' f' }

global = {
  \key b \major
}

\score {
  <<
\new Staff {
  <<
\global
\fluteNotes
  >>
}
\new Staff {
  \transpose ef c'
  <<
\global
\altosaxNotes
  >>
}
  >>
}


Craig Dabelstein
Owner, Maxime's Music
cr...@concertbandmusicstore.com
19 Twelfth Ave, Kedron QLD 4031 
[image: App Social Buttons Image]
   [image: App Social
Buttons Image] 
Maxime's Music [image: arrow] 
Create your own email signature