8

I want to define a Lilypond function that will interpolate two notes. The function should take as inputs: the first note, the last note, the step (in semitones), and whether flats or sharps should be used.

For example:

\sequence a g 1 sharp

should create the chromatic scale:

a ais b c cis d dis e f fis g

Similarly,

\sequence f a -2 flat

should create the sequence descending by whole tones:

f ees des b a

Any ideas?

Elements in Space
  • 10,785
  • 2
  • 23
  • 67
scaramouche
  • 231
  • 1
  • 3
  • 2
    I suspect that you might need to get involved in Scheme programming here. There is very little info about using Scheme within Lilypond, but there are a number of questions [here on StackOverflow](http://stackoverflow.com/questions/tagged/lilypond), that might indicate that asking the question there could get some interest. – Old John Dec 19 '15 at 08:37
  • Thank you, @OldJohn, I have now posted the same question here: http://stackoverflow.com/questions/34374593/lilypond-function-to-interpolate-two-notes. Let's see what happens. – scaramouche Dec 19 '15 at 19:38
  • You might also consider posting this to the Lilypond mail list. A few kind souls there have created Scheme functions to meet my needs in the past and in general it's a friendly place with several of Lilypond's main developers always present. – bfootdav Dec 20 '15 at 16:00

2 Answers2

3

Here's a small library I wrote to write scales for my students that does somewhat what you are asking.

\version "2.18.2" 


%{ 
    Before: scaleNotes is an AssociationList mapping all integers from 0 to n  
            (where n is a natural number) to legal note names 
    Value:  A function usable in lilypond code that takes two numbers and maps  
            the range between them according to the scaleNotes mapping. Also  
            takes a third number which defines the length value of the note. 
%} 
#(define (numsToNotes scaleNotes step)  
  (define-music-function 
     (parser location start end dur)  
        (number? number? number?)  
        #{  
            $(ly:parser-include-string  
               parser  
               (get-scale start end scaleNotes dur step)) 
        #} 
       ) 
  ) 
#(define (get-note x scale)  
   (cdr (assoc (modulo x (length scale)) scale)) 
   ) 
#(define (get-scale start end scale dur step) 
   (foldr string-append  
          (cons (string-append (get-note start scale)  
                               (number->string dur))  
                (map (lambda (x) (string-append " " (get-note x scale)))  
                     (range ((if (< start end) + -) start step) end step))) 
   ) 
  ) 


%{ Standard utility functions  %} 
#(define (foldr func li) 
   (define (h x li) 
     (if (null? li) 
       x 
       (h (func x (car li)) (cdr li)))) 
   (h (func (car li) (car (cdr li))) (cdr (cdr li)))) 

#(define (range x y st) 
   (define (h li x st cmp)  
     (if (cmp x y)   
       li 
       (h (cons x li) (+ x st) st cmp))) 
   (reverse (h '() x (if (< x y) (abs st) (* -1 (abs st))) (if (< x y) > <)))) 

To use it to write the sequence you're asking for

#(define Chr-sharp-notes
  '((0 . "c") 
    (1 . "cis")
    (2 . "d")
    (3 . "dis")
    (4 . "e") 
    (5 . "f")
    (6 . "fis") 
    (7 . "g")  
    (8 . "gis")
    (9 . "a")
    (10 . "ais")
    (11 . "b")))
#(define Chr-flat-notes
  '((0 . "c") 
    (1 . "des")
    (2 . "d") 
    (3 . "es") 
    (4 . "e") 
    (5 . "f") 
    (6 . "ges")
    (7 . "g") 
    (8 . "as") 
    (9 . "a") 
    (10 . "bes")
    (11 . "b")))

flatChromatic = #(numsToNotes Chr-flat-notes 2)
sharpChromatic = #(numsToNotes Chr-sharp-notes 1)



\score{ 
    \relative c' { 
       \sharpChromatic #9 #19 #4
       \flatChromatic #17 #9 #4
    }
}

Just copy-paste the codeblocks to the same file and compile it to see the notes.

This is less usable than what you asked for and what you're asking for is actually a quite nice idea for a library so hopefully I'll find time to improve this.

Get_Schwifty
  • 200
  • 2
  • 7
0
\version "2.19.65"

myscale.sharp = #(make-semitone->pitch
                  (music-pitches #{ c cis d dis e f fis g gis a ais b #}))
myscale.flat = #(make-semitone->pitch
                 (music-pitches #{ c des d es e f ges g as a bes b #}))

sequence =
#(define-music-function (start end step scale)
  (ly:pitch? ly:pitch? number? symbol?)
  #{ $@(map #{ \myscale.#scale #}
            (iota (1+ (/ (modulo (- (ly:pitch-semitones end)
                                    (ly:pitch-semitones start))
                                 (if (negative? step) -12 12))
                         step))
                  (ly:pitch-semitones start)
                  step))
      #})

\displayLilyMusic \sequence a g 1 sharp
\displayLilyMusic \sequence f a -2 flat
Dom
  • 47,095
  • 22
  • 150
  • 281