|
From: | lilypond |
Subject: | RE: Generate pitches between pitches |
Date: | Fri, 29 Nov 2019 16:18:21 +0100 |
From: lilypond-user <lilypond-user-bounces+lilypond=address@hidden> On Behalf Of Paolo Prete Hello, given two pitches, for example: c' and c'', is there a way to automatically generate all the pitches between them? In three different ways: 1) all the "white keys" between them: d' e' f' g' a' b' 2) all the "black keys" between them: des' ees' ges' aes' bes' 3) all the pitches: des' d' ees' e' f' ges' g' aes' a' bes' b' This feature would be very useful for simulating (piano) glissandos with MIDI. thanks. [>] Like this? \version "2.19.83" glisando = #(define-music-function (parser location arg1 arg2) (ly:music? ly:music? ) (letrec ((first-note-fn (lambda (lst) (cond ((ly:music? lst) lst) ((null? lst) '()) ((not (pair? lst)) '()) (else (car lst))))) (last-note-fn (lambda (lst) (cond ((ly:music? lst) lst) ((null? lst) '()) ((not (pair? lst)) '()) ((null? (cdr lst)) (car lst)) (else (last-note-fn (cdr lst))))))) (let* ((lst1 (ly:music-property arg1 'elements)) (lst2 (ly:music-property arg2 'elements)) (pp-pitch '((0 . (0 . 0)) (1 . (1 . -1/2 )) (2 . (1 . 0)) (3 . (2 . -1/2 )) (4 . (2 . 0)) (5 . (3 . 0)) (6 . (4 . -1/2 )) (7 . (4 . 0)) (8 . (5 . -1/2 )) (9 . (5 . 0)) (10 . (6 . -1/2 )) (11 . (6 . 0)))) (make-pitch (lambda (p) (let* ((note (assoc-get (modulo p 12) pp-pitch)) (octave (quotient p 12))) (ly:make-pitch octave (car note) (cdr note))))) (first-note (last-note-fn lst1)) (last-note (first-note-fn lst2)) (first-pitch (ly:music-property first-note 'pitch)) (last-pitch (ly:music-property last-note 'pitch)) (first-duration (ly:duration-log (ly:music-property first-note 'duration))) (first-type (ly:music-property first-note 'name)) (last-type (ly:music-property last-note 'name))) (cond ((null? first-note) (throw 'glisando-err "arg1 must be a music _expression_ with notes")) ((null? last-note) (throw 'glisando-err "arg2 must be a music _expression_ with notes")) ((not (equal? first-type 'NoteEvent))(throw 'glisando-err "arg1 must end with a note")) ((not (equal? last-type 'NoteEvent))(throw 'glisando-err "arg2 must begin with a note")) (else (let* ((ps-first (ly:pitch-semitones first-pitch)) (ps-last ( - (ly:pitch-semitones last-pitch) 1)) (dir (if (> ps-first ps-last) 1+ 1- )) (glis '())) (do ((p ps-last (dir p)))((equal? p ps-first)) (set! glis (cons (make-music 'NoteEvent 'pitch (make-pitch p) 'duration (ly:make-duration first-duration) ) glis))) (make-music 'SequentialMusic 'elements (append (list arg1) glis (list arg2) )))) )))) \glisando { e'2 d' c'32 } { c''4 b' a'} |
[Prev in Thread] | Current Thread | [Next in Thread] |