Hi again,

I didn't actually tell what the engraver is actually for:
The "autoTranspose"-engraver transposes music automatically, if there
are three context-properties set:
* instrumentTransposition is the pitch, which is set by \transposition
* music-concert-pitch tells whether the music in this context is
provided in concert-pitch (boolean)
* print-concert-pitch tells whether the music shall be printed in
concert-pitch (boolean)

Now, if you set music-concert-pitch to #t and print-concert-pitch to #f,
the music is transposed by instrumentTransposition. There are no extra
transpose{}-constructs needed and \instrumentSwitch may set
'instrumentTransposition.

Cheers, Jan-Peter

Am 12.05.2014 11:16, schrieb Jan-Peter Voigt:
> Hi there,
> 
> I read a few of the messages regarding the given subject. I don't have a
> once-and-for-all-solution, but I want bring in another scheme-engraver:
> 
> It uses context-properties 'instrumentTransposition, (newly defined)
> 'music-concert-pitch' and 'print-concert-pitch'. If the music in the
> staff is in concert-pitch, but it shall be displayed in
> instrument-pitch, it is transposed from concert-pitch to
> instrument-pitch and vice versa. The transposition is done on
> note-events and key-change-events. Propably the engraver needs to listen
> to a few more.
> 
> Two problems:
> 1. If the music is in instrument-pitch and shall be displayed in
> concert-pitch, the transposition is still active - so the midi is wrong
> 2. The engraver doesn't create a key-signature yet, if
> 'instrumentTransposition changes.
> 
> Now, what do you think?
> 
> Best, Jan-Peter

\version "2.18.2"

% taken from "scm/define-context-properties.scm"
#(define (translator-property-description symbol type? description)
   (if (not (and
             (symbol? symbol)
             (procedure? type?)
             (string? description)))
       (throw 'init-format-error))

   (if (not (equal? #f (object-property symbol 'translation-doc)))
       (ly:error (_ "symbol ~S redefined" symbol)))

   (set-object-property! symbol 'translation-type? type?)
   (set-object-property! symbol 'translation-doc description)
   (set! all-translation-properties (cons symbol all-translation-properties))
   symbol)
% add context properties descriptions
%   music-concert-pitch
%   print-concert-pitch
#(translator-property-description 'music-concert-pitch boolean? "music is in concert pitch")
#(translator-property-description 'print-concert-pitch boolean? "print it in concert pitch")

% engraver to automatically transpose music
autoTranspose =
#(lambda (context)
   (let ((base (ly:make-pitch 0 0 0)) ; pitch c'
          (lasttransp (ly:context-property context 'instrumentTransposition))) ; last instrument transposition
     (define (cond-transp engraver music)
       (let ((mcp (ly:context-property context 'music-concert-pitch)) ; music is in concert-pitch t/f
              (pcp (ly:context-property context 'print-concert-pitch)) ; print it in concert-pitch t/f
              (transp (ly:context-property context 'instrumentTransposition)) ; instrument transposition
              (keysig (ly:context-property context 'keySignature)) ; key-signature
              (tonic (ly:context-property context 'tonic))) ; key-signature tonic

         (define (do-transp m)
           (cond
            ; music in concert-pitch / display in instrument pitch
            ((and mcp (not pcp) (ly:pitch? transp))
             (ly:music-transpose m (ly:pitch-diff base transp)))
            ; music in instrument pitch / display in concert pitch
            ((and (not mcp) pcp (ly:pitch? transp))
             (ly:music-transpose m transp))
            ))
         
         ; TODO: if instrument transposition changed, produce key signature
         (if (not (equal? transp lasttransp))
             (let ((key-sig (make-music 'KeyChangeEvent 'pitch-alist keysig 'tonic tonic)))
               (ly:broadcast (ly:context-event-source context)
                 (ly:make-stream-event 'key-change-event `((music-cause . ,key-sig)) ))
               ))
         (set! lasttransp transp)
         
         ; execute transposition
         (do-transp music)
         ))
     
     ; create engraver
     (make-engraver
      (listeners
       ; transpose note-event
       ((note-event engraver event)
        (cond-transp engraver (ly:event-property event 'music-cause)))
       ; transpose key-signature
       ((key-change-event engraver event)
        (cond-transp engraver (ly:event-property event 'music-cause)))
       )
      )
     ))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% demo music
bach = \relative c'' { bes a c b }

\addInstrumentDefinition #"eb-clarinet"
  #`((instrumentTransposition . ,(ly:make-pitch 0 2 -1/2))
     (shortInstrumentName . "Es-Kl")
     (clefGlyph . "clefs.G")
     (middleCPosition . -6)
     (clefPosition . -2)
     (instrumentCueName . "Es-Kl")
     (midiInstrument . "clarinet"))

\addInstrumentDefinition #"b-clarinet"
  #`((instrumentTransposition . ,(ly:make-pitch -1 6 -1/2))
     (shortInstrumentName . "Kl")
     (clefGlyph . "clefs.G")
     (middleCPosition . -6)
     (clefPosition . -2)
     (instrumentCueName . "Kl")
     (midiInstrument . "clarinet"))
  
%%% demo score
\score {
  \new Staff \with {
    \remove "Key_engraver"
    \consists #autoTranspose
    \consists "Key_engraver"
  } {
    % if music and print are equal, do nothing
    % else transpose according to transp (up or down)
    \set Staff.music-concert-pitch = ##t
    \set Staff.print-concert-pitch = ##f
    % if music is given in instrument-pitch, but shall be printed in concert-pitch,
    %   midi pitch is false - instrumentTransposition should be "turned off" for midi(?)
    \key f \major
    \bach
    \instrumentSwitch "b-clarinet"
    \bach
    \instrumentSwitch "eb-clarinet"
    \bach
  }
  \layout {}
  \midi { \tempo 4=120 }
}

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to