lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: overriding voiceOne to add properties to that specific voice context


From: Lukas-Fabian Moser
Subject: Re: overriding voiceOne to add properties to that specific voice context
Date: Thu, 20 Aug 2020 01:54:54 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0

Hi Maurits,

I am receiving the note events through listeners on the voice context, and have 
access to the voice context itself through (ly:translator-context engraver).
Is there a way that I can override / replace the default \voiceX and \oneVoice 
commands with versions that both do their default task as well as set a voice 
context property which would allow me to read the voice number back later as 
part of the specific voice context properties?

I have been trying a few things with (context-spec-music) but as I don't really 
understand what it returns (or does) exactly, it is a bit hard to know what to 
do exactly.

I don't have much experience with custom engravers, but I think one can define a new context property and upgrade the \voiceX / \oneVoice commands to also set this context property:

\version "2.21.0"

% tool for defining new context properties
% (from https://www.mail-archive.com/lilypond-user@gnu.org/msg133263.html)

#(define (define-translator-property symbol type? description)
  (if (not (and (symbol? symbol)
                (procedure? type?)
                (string? description)))
      (ly:error "error in call of define-translator-property"))
  (if (not (equal? (object-property symbol 'translation-doc) #f))
      (ly:error (_ "symbol ~S redefined") symbol))

  (set-object-property! symbol 'translation-type? type?)
  (set-object-property! symbol 'translation-doc description)
  symbol)

% define a new context property "structuralVoice"
#(for-each
  (lambda (x)
    (apply define-translator-property x))
    `((structuralVoice
       ,integer?
       "The current voice is a first/second/... voice (1,2,3,4) or single voice (empty list)")))

setStructuralVoice =
#(define-scheme-function (num) (integer?)
   (make-apply-context
     (lambda (context)
     (let ((fontSize (ly:context-property context 'fontSize)))
       (ly:context-set-property! context 'structuralVoice (if (> num 0) num '()))))))

oneVoice = { \setStructuralVoice 0 \oneVoice }
voiceOne = { \setStructuralVoice 1 \voiceOne }
voiceTwo = { \setStructuralVoice 2 \voiceTwo }
voiceThree = { \setStructuralVoice 3 \voiceThree }
voiceFour = { \setStructuralVoice 4 \voiceFour }

displayCurrentStructuralVoice = \applyContext
#(lambda (context)
   (pretty-print
    (ly:context-property context 'structuralVoice)))

\relative {
  \displayCurrentStructuralVoice % not yet defined
  a'4
  \voiceTwo e f
  \displayCurrentStructuralVoice
  \voiceOne e' f
  \displayCurrentStructuralVoice
  \oneVoice e d c b a g f
  \displayCurrentStructuralVoice
}

Note that this does not work yet with voice distinctions created using the \\ shorthand.

Best
Lukas




reply via email to

[Prev in Thread] Current Thread [Next in Thread]