OpenMusic-Library zur regelbasierten Harmonie und Stimmführung.
Lorenz Lehmann
09.12.23 d780c2a220922d75a55569bfd619e8651700aabe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
;======================================
;OM-Lead, 2022-2023
;
;Library for Rule-based Voice-Leading
;Author: Lorenz Lehmann
;Supervision: Marlon Schumacher
;======================================
 
(in-package :omlead)
 
(om::defmethod! harmon-rhythm (harmon_progress measure_numerator measure_denominator n-bars n-harmonies tree-base1 &key tree-base2 tree-base3 tree-base4 (tempo 60) (legato 100) (chan-i1 1) (chan-i2 1) (chan-i3 1) (chan-i4 1) (vel-i1 100) (vel-i2 100) (vel-i3 100) (vel-i4 100) off-sets proportions pulses pause-tie avoid-pause-repetitions)
 
:icon 030719971
:numouts 5
;:indoc '("tree: a list of trees or a list of lists with trees (((tree) (tree) (tree)))/ (((tree1) (tree2)) ((tree1)))" "chords -> harmon-progress")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
(defun mat-trans_oml (list)
  (loop for y in (let (count-list)
                   (dotimes (i (length (car list))) 
                     (setq count-list (cons i count-list))) (nreverse count-list))
        collect (loop for x in list collect (nth y x)))) 
 
 
 
(defun n-pulses_oml (l)
  (labels ((pulses (liste)
             (if (null (car liste))
                 liste 
               (cond ((atom (car liste))
                      (cons 1
                            (pulses (cdr liste))))
                     (t (pulses (car liste)))))))
    (length (pulses l))))
 
 
(defun nth-rand_oml (liste)
  (nth (random (length liste)) liste))
 
 
(defun list_oml (seq list)
         
         (if (null seq)
             seq 
           (cons (butlast seq (- (length seq) (car list)))
                 (list_oml (nthcdr (car list) seq) (cdr list)))))
 
 
(defun flat_oml (liste)
  (cond 
         ((null (cdr liste))
          (if (atom (car liste)) 
              liste
            (flat_oml (car liste))))
 
 
         ((and (listp (car liste)) (not (listp (cadr liste))))
          (append (car liste)
                  (flat_oml (cdr liste))))
 
 
         ((and (not (listp (car liste))) (not (listp (cadr liste))))
          (append (list (car liste)) 
                  (flat_oml (cdr liste))))
 
         ((and (listp (car liste)) (listp (cadr liste)))
               (append (car liste)
                       (flat_oml (cdr liste))))
 
         ((and (not (listp (car liste))) (listp (cadr liste)))
               (append (list (car liste))
                       (flat_oml (cdr liste))))))
 
 
(defun find-pos_oml (item seq)
  (remove nil (loop for s in seq
        for x
        collect (if (equal item s) x))))
 
 
(defun replace_oml (positions item liste)
  (let ((positions (if (atom positions) (list positions) positions)))
    (loop for i in liste 
          for p 
          collect (if (find p positions) item i))))
 
 
(defun sum_oml (liste)
  (if (null (cdr liste))
      (car liste)
    (+ (car liste)
       (sum_oml (cdr liste)))))
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(let* ((n-harms (cond ((atom n-harmonies) (loop repeat n-bars collect n-harmonies))
                             ((< (length n-harmonies) n-bars) 
                              (append n-harmonies (loop repeat (- n-bars (length n-harmonies)) collect (car (last n-harmonies)))))
                             (t n-harmonies)))
       (voice-list
(loop repeat n-bars
 
 
      for trees1 in (cond ((< (length tree-base1) n-bars) 
                           (append tree-base1 (loop repeat (- n-bars (length tree-base1)) collect (car (last tree-base1)))))
                          (t tree-base1))
      for trees2 in (cond ((< (length tree-base2) n-bars) 
                           (append tree-base2 (loop repeat (- n-bars (length tree-base2)) collect (car (last tree-base2)))))
                          (t tree-base2))
      for trees3 in (cond ((< (length tree-base3) n-bars) 
                           (append tree-base3 (loop repeat (- n-bars (length tree-base3)) collect (car (last tree-base3)))))
                          (t tree-base3))
      for trees4 in (cond ((< (length tree-base4) n-bars) 
                           (append tree-base4 (loop repeat (- n-bars (length tree-base4)) collect (car (last tree-base4)))))
                          (t tree-base4))
 
      for chords in (list_oml (cond ((atom (car harmon_progress)) (loop repeat (* n-bars n-harmonies) collect harmon_progress))
                                    ((< (length harmon_progress) (* n-bars n-harmonies)) 
                                     (append harmon_progress
                                             (loop repeat (- (* n-bars n-harmonies) (length harmon_progress)) collect (car (last harmon_progress)))))
                                    (t harmon_progress)) n-harms)
      
 
 
      for n-harmony in n-harms
      for numerator in (cond ((atom measure_numerator) (loop repeat n-bars collect measure_numerator))
                             ((< (length measure_numerator) n-bars) 
                              (append measure_numerator (loop repeat (- n-bars (length measure_numerator)) collect (car (last measure_numerator)))))
                             (t measure_numerator))
      for denominator in (cond ((atom measure_denominator) (loop repeat n-bars collect measure_denominator))
                             ((< (length measure_denominator) n-bars) 
                              (append measure_denominator (loop repeat (- n-bars (length measure_denominator)) collect (car (last measure_denominator)))))
                             (t measure_denominator))
      for tempo in (cond ((atom tempo) (loop repeat n-bars collect tempo))
                         ((< (length tempo) n-bars) 
                          (append tempo (loop repeat (- n-bars (length tempo)) collect (car (last tempo)))))
                         (t tempo)) 
      for legato in (cond ((atom legato) (loop repeat n-bars collect legato))
                         ((< (length legato) n-bars) 
                          (append legato (loop repeat (- n-bars (length legato)) collect (car (last legato)))))
                         (t legato)) 
 
      for offs in (print (cond ((< (length off-sets) n-bars) 
                           (append off-sets (loop repeat (- n-bars (length off-sets)) collect (car (last off-sets)))))
                          (t off-sets)))
      for props in (cond ((< (length proportions) n-bars) 
                          (append proportions (loop repeat (- n-bars (length proportions)) collect (car (last proportions)))))
                         (t proportions))
      
      for puls in (cond ((< (length pulses) n-bars) 
                         (append pulses (loop repeat (- n-bars (length pulses)) collect (car (last pulses)))))
                        (t pulses))
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
collect
 
 
 
(let* 
    ((voice-num (length (car chords)))
    (midi-list (loop for instr to (1- voice-num)
                                           collect
                                           (mapcar #'(lambda (l) (list (nth instr l))) chords)))
     (trees (list trees1 trees2 trees3 trees4))
     (tree-list (loop for l in trees
                      for m in midi-list
                      while l
                      collect
                      ;Tree  BARS
                     (list 1 (list (list (list numerator denominator)
                            ;Proportions
                            (if (find -1 (flat_oml m))
                               (replace_oml (find-pos_oml '(-1) m) -1
 
                                (nth-rand_oml
                             (loop for r in l
                                   collect (if (= n-harmony (n-pulses_oml r)) r))))
                              (nth-rand_oml
                               (loop for r in l
                                     collect (if (= n-harmony (n-pulses_oml r)) r)))))))))
 
     (tree-list (cond (off-sets 
                       
                       (setf beats (nth-rand_oml puls))
                       (setf item (nth-rand_oml props))
                       (loop for tree in tree-list
                             
                             for x
                             for pattern in  (print (make-list (length beats)
                                                       :initial-element  (mapcar #'(lambda (pr pa) (* pr pa))
                                                                                item 
                                                                                (nth x
                                                       (loop for i in (nth-rand_oml offs)
                                                             collect (cond ((= 1 i) 1) ((= -1 i) -1) (t -1)) into instr1 
                                                             collect (cond ((= 2 i) 1) ((= -2 i) -1) (t -1)) into instr2 
                                                             collect (cond ((= 3 i) 1) ((= -3 i) -1) (t -1)) into instr3 
                                                             collect (cond ((= 4 i) 1) ((= -4 i) -1) (t -1)) into instr4 
                                                             
                                                             finally (return (mapcar #'(lambda (l) (if (= (count -1 l) (length l)) 'nil l)) 
                                                                                    (list instr1 instr2 instr3 instr4))))))))
                             do (setf beats (nth-rand_oml puls))
                             do (setf item (nth-rand_oml props))
                             collect
                             
                             
                             (om::subst-rhythm tree beats pattern)))
 
                      (t tree-list)))
 
 
 
     (midi-list
 
      (mapcar #'(lambda (l) (remove '(-1) l :test 'equal)) midi-list))
 
     (chord-lists 
      
      (loop for instr to (1- voice-num)
            collect (loop for m in (nth instr midi-list)
                          collect (om::make-instance 'om::chord 
                                                     :lmidic m
                                                     :lchan '(1)
                                                     :lvel '(100))))))
  
;ergebnis: list of chord-lists
 
;:::::.......
 
     
 
 
     (loop for instr to (1- voice-num)
           collect
           (om::make-instance 'om::voice 
                              :tree (nth instr tree-list)
                              :chords (nth instr chord-lists) 
                              :tempo tempo
                              :legato legato
                              )))))
 
(voices (loop for x in (mat-trans_oml voice-list)
              collect (reduce #'om::concat x))))
 
 
(values-list (list (reverse voices) (nth 0 voices) (nth 1 voices) (nth 2 voices) (nth 3 voices)))
 
 
;;;;;;;;;;;;;end::::::::::::::::::::::::::::::::::::::::::::::::
))