| [ << Automatic notation ] | [Top][Contents] | [ Breaks >> ] |
| [ < Fixation arbitraire du numéro de repère de départ ] | [ Up: Automatic notation ] | [ Suppression des bécarres superflus > ] |
Génération en Scheme de partitions complètes (y compris des parties d’ouvrage) sans utiliser l’analyseur ¶
Une partition LilyPond, de manière interne, n’est rien d’autre qu’une expression Scheme générée par l’analyseur syntaxique de LilyPond. Il est donc possible, à l’aide de Scheme, de générer automatiquement une partition sans fichier source. Une expression musicale en Scheme sera transformée en partition par un appel à
(scorify-music music)
Ceci aura pour effet de générer un objet score auquel sera
appliqué un bloc layout comportant la fonction
(let* ((layout (ly:output-def-clone $defaultlayout))) ; modification de la mise en forme, puis assignation : (ly:score-add-output-def! score layout))
Il suffit alors de transmettre ce score à LilyPond pour qu’il le
grave. Les trois fonctions – (add-score score),
(add-text text) et (add-music music) – définies dans le
code ci-dessous permettent de transmettre à LilyPond, aux fins de les
graver, une partition complète, un markup ou simplement de la
musique.
Cet exemple permet aussi de graver les pièces contenues dans un bloc
\book { … } ainsi que des partitions de niveau
supérieur. Chaque partition destinée à être gravée est alors ajoutée à
la liste des partitions de niveau supérieur ; le
toplevel-book-handler – fonction Scheme appelée pour traiter un
book dès que le bloc \book { … } est clôturé –
s’adapte pour prendre en charge tous les éléments score jusque là
collectés dans l’ouvrage.
Attention : Pour des raisons techniques, seul le premier \book
sera rendu puisque les autres commandes \book génèrent des
fichiers additionnels.
#(define-public (add-score score) (ly:parser-define! 'toplevel-scores (cons score (ly:parser-lookup 'toplevel-scores)))) #(define-public (add-text text) (add-score (list text))) #(define-public (add-music music) (collect-music-aux (lambda (score) (add-score score)) music)) #(define-public (toplevel-book-handler book) (map (lambda (score) (ly:book-add-score! book score)) (reverse! (ly:parser-lookup 'toplevel-scores))) (ly:parser-define! 'toplevel-scores (list)) (print-book-with-defaults book)) #(define-public (book-score-handler book score) (add-score score)) #(define-public (book-text-handler book text) (add-text text)) #(define-public (book-music-handler book music) (add-music music)) % Some example code to show how to use these functions. Each call to % `\oneNoteScore` constructs a global markup followed by a single % staff with a single quarter note. The pitch of this note is taken % from the variable `pitch`; the start value 0 corresponds to pitch C. % After emitting the score, variable `pitch` gets increased by 1. % % `\oneNoteScore` calls Scheme function `add-one-note-score` to do all % the work. #(define add-one-note-score #f) #(let ((pitch 0)) (set! add-one-note-score (lambda () (let* ((music (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1/1) 'pitch (ly:make-pitch 0 pitch 0))))) (score (scorify-music music)) (layout (ly:output-def-clone $defaultlayout)) (note-name (case pitch ((0) "do") ((1) "ré") ((2) "mi") ((3) "fa") ((4) "sol") ((5) "la") ((6) "si") (else "huh"))) (title (markup #:large #:line ("Score with a" note-name)))) (ly:score-add-output-def! score layout) (add-text title) (add-score score)) (set! pitch (modulo (1+ pitch) 7))))) oneNoteScore = #(define-void-function () () (add-one-note-score)) \book { \oneNoteScore \paper { tagline = ##f } } \book { \oneNoteScore \oneNoteScore \paper { tagline = ##f } } % Top-level scores are also handled correctly. \oneNoteScore \oneNoteScore \paper { tagline = ##f }
| [ << Automatic notation ] | [Top][Contents] | [ Breaks >> ] |
| [ < Fixation arbitraire du numéro de repère de départ ] | [ Up: Automatic notation ] | [ Suppression des bécarres superflus > ] |