And the missing attachment.

2014-07-25 20:03 GMT+02:00 Janek Warchoł <janek.lilyp...@gmail.com>:
> Hi all,
>
> i got stuck when working on a function that creates custom context
> definitions.  The idea is to have a function \newInstrument that would
> take a list of settings and create new customized xxxStaff and
> xxxVoice contexts - something like this:
>
> newInstrument =
> #(define-scheme-function
>   (parser location instrName parentName settings)(string? ly:context-mod?)
>   ;; ...
>     #{
>       \layout {
>         \context {
>           ;; create "instrNameStaff" context, derived from "parentNameStaff",
>           ;; with default child "instrNameVoice", and modifications specified
>           ;; in "settings" argument
>         }
>         \context {
>           ;; create "instrNameVoice" context, derived from "parentNameVoice",
>         }
>       }
>     #})
>
> As you can see, i want to be able to specify the "parent" instrument
> from which the new instrument will "inherit" settings.  For example, i
> want to define a "Vocals" instrument (=> VocalsStaff and VocalsVoice
> contexts, derived from Staff and Voice, respectively) and a "Soprano"
> instrument derived from "Vocals" (=> SopranoStaff and SopranoVoice
> contexts, derived from VocalsStaff and VocalsVoice, respectively).
>
> I managed to write a function that does something like this, but I
> have two problems:
> 1) inside the function, i don't know how to get a context definition
> from its name (i.e. from a string).  Right now i have to pass parent
> contexts' definitions as separate arguments, but this means that i
> have three arguments instead of one.
> 2) i didn't manage to get midi stuff done inside the same function as
> the layout stuff - but i think that i'll be able to solve that if i
> have a solution to 1).
>
> I offer €25 bounty for solving 1).  I may also offer a bounty for 2)
> if i won't manage to do it myself :)
> See the attachment for the code that i already have.
>
> best,
> Janek
\version "2.19.10"

% Create a new xxxStaff and xxxVoice contexts with specified settings,
% derived from specified yyyStaff and yyyVoice contexts.
%
% TODO: instead of having 3 arguments: (parentstaff, parentvoice, parentname)
% the function should take just parentname and get parentstaff and parentvoice
% from that.
newLayoutInstrument =
#(define-scheme-function
  (parser location name parentstaff parentvoice parentname grouping staffsettings voicesettings)
  (string? ly:context-def? ly:context-def? string? ly:context-def? ly:context-mod? ly:context-mod?)
  (let ((staffname (string-append name "Staff"))
        (voicename (string-append name "Voice"))
        (parentstaffname (string-append parentname "Staff"))
        (parentvoicename (string-append parentname "Voice")))
    #{
      \layout {
        \context {
          #grouping
          \accepts #staffname
        }
        \context {
          #parentstaff
          \name #staffname
          \alias #parentstaffname
          \accepts #voicename % is it possible to make it accept Voices of derived instruments?
          \defaultchild #voicename

          #staffsettings
        }
        \context {
          #parentvoice
          \name #voicename
          \alias #parentvoicename

          #voicesettings
        }
      }
    #}))

% UGH!!! CODE DUPLICATION!!!
% This function is almost identical to the one above - obviously, they should be merged,
% but I didn't yet find a way to put both \layout and \midi stuff into one function :(
newMidiInstrument =
#(define-scheme-function
  (parser location name parentstaff parentvoice parentname grouping staffsettings voicesettings)
  (string? ly:context-def? ly:context-def? string? ly:context-def? ly:context-mod? ly:context-mod?)
  (let ((staffname (string-append name "Staff"))
        (voicename (string-append name "Voice"))
        (parentstaffname (string-append parentname "Staff"))
        (parentvoicename (string-append parentname "Voice")))
    #{
      \midi {
        \context {
          #grouping
          \accepts #staffname
        }
        \context {
          #parentstaff
          \name #staffname
          \alias #parentstaffname
          \accepts #voicename
          \defaultchild #voicename

          #staffsettings
        }
        \context {
          #parentvoice
          \name #voicename
          \alias #parentvoicename

          #voicesettings
        }
      }
    #}))


% define "instruments" - one generic and another one derived:

\layout {
  \newLayoutInstrument "Vocal" \Staff \Voice "" \ChoirStaff
  \with {
    \consists "Ambitus_engraver"
    instrumentName = "Vocals"
    shortInstrumentName = "Voc."
    \dynamicUp
    \tupletUp
  }
  \with { }
}
\midi {
  \newMidiInstrument "Vocal" \Staff \Voice "" \ChoirStaff
  \with {
    \remove "Staff_performer"
  }
  \with {
    \consists "Staff_performer"
    midiInstrument = "voice oohs"
  }
}

\layout {
  \newLayoutInstrument "Soprano" \VocalStaff \VocalVoice "Vocal" \ChoirStaff
  \with {
    instrumentName = "Soprano"
    shortInstrumentName = "S"
    \clef G
  }
  \with { }
}
\midi {
  \newMidiInstrument "Soprano" \VocalStaff \VocalVoice "Vocal" \ChoirStaff
  \with { }
  \with { }
}


% test:

\score {
  \new SopranoVoice \relative f' {
    c f c' f
  }
  \layout {
    \override Staff.Stem.thickness = 4
    \override VocalStaff.Stem.color = #blue
    \override SopranoVoice.NoteHead.color = #green
  }
  \midi {
    \set SopranoVoice.midiInstrument = "clarinet"
  }
}
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to