If have done some programing some time ago, a function that produces diatonic chords from a scale. Check it out, maybe you can combine it with Thomas' code.
\version "2.19.37"
\language "deutsch"
%% create diatonic chords from a scale
%% enter the steps of the scale as lily music
%% and chose the number of notes the chords should have
#(define (music-elts x)
(if (not (ly:music? x))
'()
(ly:music-property x 'elements)))
#(define (music-name x)
(if (not (ly:music? x))
#f
(ly:music-property x 'name)))
%% convert pitchlist to a music chord
#(define (pitches->chord plist)
(make-music 'EventChord 'elements
(if (list? plist)
(map (lambda (p)
(make-music
'NoteEvent 'duration (ly:make-duration 0)
'pitch p))
plist)
(make-music
'NoteEvent 'duration (ly:make-duration 0)
'pitch plist)
)))
%% convert pitchlist to plain music
#(define (pitches->music plist)
(if (list? plist)
(make-music 'SequentialMusic 'elements
(map (lambda (p)
(make-music
'NoteEvent 'duration (ly:make-duration 0)
'pitch p))
plist))
(make-music 'SequentialMusic 'elements
(make-music
'NoteEvent 'duration (ly:make-duration 0)
'pitch plist))))
#(define (stacked-intervals the-scale list-or-number-or-pair)
;; the-scale: music from which the pitchlist is constructed
;; usually a scale, but could be any music
;; duplicate pitches are removed and sorting according to pitch height is done
;; list-or-number-or-pair: tells the programm which intervals to produce
;; list: a list of chords, 3=third, 4=forth etc. '(2 4) creates a quart-sext chord
;; pair: '(a . b) a: how many notes the chord contains, b: the interval, 3=third, 4=forth
;; number: terzes are stapled, 3=triad, 4=tetrads, 5=pentachord etc
;; a list of intervals is created by picking notes in the order they appear
;; in the scale leaving gaps defined by the list
(let* ((scpi (music-pitches the-scale))
(pili (sort
(delete-duplicates scpi) ly:pitch<?))
(m (length pili))
(elist (cond
((list? list-or-number-or-pair)
;; we need to add an element to the list
;; otherwise the last element of the list would not appear
;; in the result
(append list-or-number-or-pair '(1)))
((pair? list-or-number-or-pair)
;; car: number of notes
;; cdr: distance, 3=third, 4=forth etc.
(make-list (car list-or-number-or-pair) (cdr list-or-number-or-pair)))
((number? list-or-number-or-pair)
;; standard definition: chord consists of thirds
(make-list list-or-number-or-pair 3))))
(n (length elist)))
(map
(lambda (w)
(let ((u 0))
(map
(lambda (x)
(let* ((y (modulo (+ u w) m))
(q (quotient (+ u w) m))
(z (list-ref pili y))
(a (ly:pitch-alteration z))
(o (ly:pitch-octave z))
(n (ly:pitch-notename z))
(p (ly:make-pitch (+ o q) n a)))
(set! u (+ u (list-ref elist x) -1))
p))
(iota n))))
(iota m))))
CreateIntervals=
#(define-music-function (the-scale pair-list-number)(ly:music? scheme?)
;; creates the pure music without chordnames and other staff
(make-sequential-music
(map (lambda(x) (pitches->chord x))
(stacked-intervals the-scale pair-list-number))))
%% Examples of usage
CMajor=\relative c' { c d e f g a h }
CMinor = \relative c' { c d es f g as h }
\markup "Diatonic Pentachords in C-major"
\CreateIntervals \relative c' \CMajor #5
\markup "Create Quart-Sext-Chords in C-major"
\CreateIntervals \CMajor #'(4 3)
\markup "stack four fifths in C-minor"
{
\new Staff \key es \major
\CreateIntervals \CMinor #'(5 . 5)
}
Greetings,
Manuela