OpenMusic-Library zur regelbasierten Harmonie und Stimmführung.
Lorenz Lehmann
09.12.23 4fb37d02ea50dd3ea0858feafe99f6ba65a50e57
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
;======================================
;OM-Lead, 2022-2023
;
;Library for Rule-based Voice-Leading
;Author: Lorenz Lehmann
;Supervision: Marlon Schumacher
;======================================
 
(in-package :omlead)
 
 
(om::defmethod! gen-harmonies ((pitch-set-list list) (instr1 list) (instr2 list) (instr3 list) (instr4 list) &key (fundamental 6000) (skala (list 100)) (permutations t) (register-list '(0)))
 
:icon 030719972
:initvals '('((0)) '(6000 7200) nil nil nil)    
:indoc '("a list of lists of intervals respective to a base not in midi-cents" "range-list with the lowest and highest note of the instrument in midi-cents" "range-list with the lowest and highest note of the instrument in midi-cents" "range-list with the lowest and highest note of the instrument in midi-cents" "range-list with the lowest and highest note of the instrument in midi-cents" "list of intervals based on the virtual fundamental which defines the <octave> for register-transposition")
 
:numouts 1
 
:doc "creates a list of chords, that contains all possible transpositions & permutations of the given pitch-sets"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
(defun circular_oml (items) 
(setf (cdr (last items)) items)
items)
 
 
(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 get-pos_oml (positions seq)
  (let ((positions (if (atom positions) (list positions) positions)))
    (mapcar #'(lambda (it) (nth it seq)) seq)))
    
 
(defun permutations_oml (bag)
 
(if (null bag)
'(())
 
(mapcan #'(lambda (e)
            (mapcar #' (lambda (p) (cons e p))
                    (permutations_oml (remove e bag :count 1 :test #'eq))))
        bag)))
 
 
(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 modulo_oml (pos liste)
(append
(nthcdr pos liste)
(butlast liste (- (length liste) pos))))
 
 
(defun register-permut_oml (register-list)
(remove-duplicates
                           (om::flat 
                            (loop for r in register-list
                                  collect 
                                  (mapcar #'(lambda (l) (permutations_oml 
                                                         (append (make-list l :initial-element r) 
                                                                 (make-list (- (length register-list) l) :initial-element 0)))) 
                                          (loop for x from 1 to (length register-list)
                                                collect x))) 2) :test 'equal))
 
 
(defun find-pos_oml (item seq)
  (remove nil (loop for s in seq
        for x
        collect (if (equal item s) x))))
 
 
(defun sum_oml (liste)
  (if (null (cdr liste))
      (car liste)
    (+ (car liste)
       (sum_oml (cdr liste)))))
 
(defun variations_oml (liste pcl)
  (let* ((liste (remove-duplicates liste))
         (liste (make-list pcl :initial-element liste)))
    (apply #'alexandria:map-product #'list liste)))
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(let* (
 
       (instr-list (sort (flat_oml (remove nil (list instr1 instr2 instr3 instr4))) '<))
       (total-range (cons (car instr-list) (last instr-list)))
       (trans-skala (let* ((grundton fundamental)
                           (tief (car total-range))
                           (hoch (cadr total-range))
                           (skala-up skala)
                           (skala-down (reverse skala-up))
                           (endless-up (circular_oml skala-up))
                           (endless-down (circular_oml skala-down))
                           (skala-up (loop for i in endless-up
                                           sum i into delta
                                           until (> (+ delta grundton) hoch)
                                           collect i))
                           (skala-down (loop for i in endless-down
                                             sum i into delta
                                             until (< (- grundton delta) tief)
                                             collect i))
                           (transpositionsliste-up (list grundton))
                           (transpositionsliste-down (list grundton)))
                      
                      (loop for i in skala-up 
                            do (push (+ (car transpositionsliste-up) i) transpositionsliste-up))
                      (loop for i in skala-down 
                            do (push (- (car transpositionsliste-down) i) transpositionsliste-down))
                      
                      (append (butlast transpositionsliste-down) (reverse transpositionsliste-up))
                      ))
 
       (harmon-database (om::flat 
                         (loop for pitch in trans-skala
                               collect
                               (loop for set in pitch-set-list
                                     collect
                                     (mapcar #'(lambda (l) (+ pitch l)) set))) 1))
 
       (harmon-database (cond (permutations (om::flat (loop for l in harmon-database
                              collect (permutations_oml l)) 1))
                              (t harmon-database)))
 
 
       (harmon-database (remove-duplicates (om::flat (loop for a in harmon-database 
                                                          collect
                                                          (loop for reg in (variations_oml register-list (length a))
                                                                collect (mapcar #'(lambda (r p) (+ r p)) reg a))) 1) :test 'equal))
       (instr-list2  (remove nil (list instr1 instr2 instr3 instr4)))
       (harmon-database (loop for a in harmon-database
                              collect (loop for p in a
                                            for count to (1- (length instr-list2))
 
                                            collect (if (or (< p  (car (nth count instr-list2)))
                                                            (> p (cadr (nth count instr-list2)))) nil p))))
       (harmon-database (remove nil (loop for a in harmon-database
                                          collect (if (> (count nil a) 0) nil a)))))
harmon-database))