| [ << Scheme ] | [Top][Contents] | [ Spacing >> ] |
| [ < Génération de notes aléatoires ] | [ Up: Scheme ] | [ Répétition en pourcent isolée > ] |
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 }
| [ << Scheme ] | [Top][Contents] | [ Spacing >> ] |
| [ < Génération de notes aléatoires ] | [ Up: Scheme ] | [ Répétition en pourcent isolée > ] |