\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 } }