Am So., 19. Mai 2024 um 21:28 Uhr schrieb Carolyn Beeton
<carolyn.bee...@icloud.com>:
>
> I would like to include some Staff and Voice context settings in the \midi 
> block only if a flag is set to ##t and I have not been able to figure out how 
> to do this.  When I try to wrap the \context blocks in a code block with 
> #{…#} I get this error:
> trackPerVoiceMWE.ly:31:16: error: syntax error, unexpected '{', expecting 
> SCM_IDENTIFIER or SCM_TOKEN or STRING or SYMBOL
>       \context                 {
> Is there any way to conditionally change the Staff_performer based on a flag 
> setting?
>
> This is my non-working MWE:
>
> \version "2.24.0"
> \include "english.ly"
>
> global = {
>   \key c \major
>   \time 4/4
> }
> TrackPerVoice = ##t
> \score {
>   \new ChoirStaff <<
>     \new Staff <<
>       \new Voice = "soprano" <<
>         \global
>         \relative c' { c'4 d e f << g1 \\ { g4 f e2 } >> }
>       >>
>       \new Voice = "alto" <<
>         \global
>         \voiceTwo
>         \relative c' { c'4 b a g | f e d2 }
>       >>
>     >>
>   >>
>   \layout {}
>   \midi {
>     #(display (format #f "TrackPerVoice is ~a\n" TrackPerVoice))
>     #(if TrackPerVoice #{
>       #(display "One track per Voice (may make too many voices with 
> polyphony)")
>       #(display "Turn this off to get sop and alto combined in one track.")
>       \context {
>         \Staff
>         \remove "Staff_performer"
>       }
>       \context {
>         \Voice
>         \consists "Staff_performer"
>       }
>     #} )
>   }
> }
>
> Thanks,
> Carolyn

Here my take on this. Modeled after `enablePolymeter`. Prpbably
overkill, though...

\version "2.24.3"

enableVoicePerformer =
#(define-void-function (do-it) (boolean?)
  (when do-it
    (display "One track per Voice (may make too many voices with polyphony)")
    (display "Turn this off to get sop and alto combined in one track.")
    (let ((module (current-module))
          (cmod-remove (ly:make-context-mod))
          (cmod-consists (ly:make-context-mod)))
     (if (not (output-module? module))
         (ly:parser-error (G_ "Not in an output definition")))
     (ly:add-context-mod cmod-remove (list 'remove 'Staff_performer))
     (ly:add-context-mod cmod-consists (list 'consists 'Staff_performer))
     ;; FIXME: any chance to use ly:output-find-context-def here?  The
     ;; problem is that we don't have access to the context def, just
     ;; its scope (module).
     (module-map
      (lambda (_sym var)
       (if (variable-bound? var)
           (let ((cdef (variable-ref var)))
             (if (ly:context-def? cdef)
                 (let* ((context-name
                          (ly:context-def-lookup cdef 'context-name))
                        (aliases (ly:context-def-lookup cdef 'aliases))
                        (all-names (cons context-name aliases)))
                   (cond
                    ((memq 'Staff all-names)
                     (variable-set!
                       var
                       (ly:context-def-modify cdef cmod-remove)))
                    ((memq 'Voice all-names)
                     (variable-set!
                       var
                       (ly:context-def-modify cdef cmod-consists)))))))))
      module))))

global = {
  \key c \major
  \time 4/4
}

TrackPerVoice = ##t

\score {
  \new ChoirStaff <<
    \new Staff
    \with { midiInstrument = "acoustic grand" }
    <<
      \new Voice = "soprano"
      \with { midiInstrument = "marimba" }
       <<
        \global
        \relative c' { c'4 d e f << g1 \\ { g4 f e2 } >> }
      >>
      \new Voice = "alto"
      \with { midiInstrument = "violin" }
      <<
        \global
        \voiceTwo
        \relative c' { c'4 b a g | f e d2 }
      >>
    >>
  >>
  \layout {}
  \midi {
    \enableVoicePerformer \TrackPerVoice
  }
}


Cheers,
  Harm

Reply via email to