;;********************************************

;;********************************************

;;////////////////////////////////////////////

;;Atonal Melodic expectation model

;;////////////////////////////////////////////

;;Mauricio Rodriguez - 2009

;;////////////////////////////////////////////

;;marod@stanford.edu

;;////////////////////////////////////////////

;;********************************************

;;********************************************

;;============================================

;; Shared file: Tonal-Key-Finder.lisp

;;============================================

;;////////////////////////////////////////////

;;Pearson Correlation Algorithm to find Tonal Key

;;////////////////////////////////////////////

;;Mauricio Rodriguez - 2009

;;////////////////////////////////////////////

#|

******************************

******************************

Use and copying of this software and preparation of derivative works

based upon this software are prohibited unless permission of the author.

marod@ccrma.stanford.edu

******************************

******************************

|#

;;Main:

;;atonal-melodic-expectancy-random-generation [n harmonic-seed interval-reservoir &optional starting-note]

;;(atonal-melodic-expectancy-random-generation 8 '(48 59 63 74) '(1 2 3 4 10 11))

;;Code:

#|

(defun average-value (list)

(let ((current-list (remove-if #'(lambda (x) (= 0 x)) list)))

(float (/ (apply #'+ current-list) (length current-list)))))

|#

(defun average-value (list)

(float (/ (apply #'+ list) (length list))))

(defun pearson-correlation* (average-x average-y pitch-list weight-list)

(if (or (endp pitch-list) (endp weight-list))

nil

(cons (list (- (first pitch-list) average-x)

(- (first weight-list) average-y))

(pearson-correlation*

average-x

average-y

(rest pitch-list)

(rest weight-list)))))

(defun pearson-correlation** (average-x average-y pitch-list weight-list)

(let* ((correlation (pearson-correlation* average-x average-y pitch-list weight-list))

(part-a (apply #'+ (loop for x in correlation

collect (* (first x) (second x)))))

(part-b (apply #'+ (loop for x in correlation

collect (expt (first x) 2))))

(part-c (apply #'+ (loop for x in correlation

collect (expt (second x) 2)))))

(/ part-a (sqrt (* part-b part-c)))))

(defun pearson-correlation*** (pitch-list weight-list)

(pearson-correlation** (average-value pitch-list)

(average-value weight-list)

pitch-list

weight-list))

(defun rotate-list (list)

(do ((count (length list) (- count 1))

(current-list list (append (last current-list) (butlast current-list)))

(output nil (cons current-list output)))

((= count 0) (reverse output))))

(defun pearson-correlation**** (pitch-list weight-list)

(let ((rotation (rotate-list weight-list)))

(loop for x in rotation

collect (pearson-correlation*** pitch-list x))))

(defun major-key-label (list)

(loop for x in '(C-Major

Db-Major

D-Major

Eb-Major

E-Major

F-Major

F#-Major

G-Major

Ab-Major

A-Major

Bb-Major

B-Major)

for y in list

collect (list x y)))

(defun minor-key-label (list)

(loop for x in '(C-Minor

C#-Minor

D-Minor

Eb-Minor

E-Minor

F-Minor

F#-Minor

G-Minor

G#-Minor

A-Minor

Bb-Minor

B-Minor)

for y in list

collect (list x y)))

(defun key-finder* (pitch-list major-weight minor-weight)

(append

(major-key-label (pearson-correlation**** pitch-list major-weight))

(minor-key-label (pearson-correlation**** pitch-list minor-weight))))

(defun search-max-in-compound-list (list)

(let ((maxima

(apply #'max (loop for z in list

collect (second z)))))

(loop for x in list

for y = (second x)

when (= maxima y )

return (first x))))

(defun key-finder (pitch-list major-weight minor-weight)

(search-max-in-compound-list

(key-finder* pitch-list major-weight minor-weight)))

#|

;;Krumhansl-Kessler probe-tone profiles:

(key-finder

'(8 0 0 0 2 11 0 5 7 0 5 2)

'(6.35 2.23 3.48 2.33 4.38 4.09 2.52 5.19 2.39 3.66 2.29 2.88)

'(6.33 2.68 3.52 5.38 2.60 3.53 2.54 4.75 3.98 2.69 3.34 3.17))

;;============================================

;;Aarden-Essen continuity profiles:

(key-finder

'(8 0 0 0 2 11 0 5 7 0 5 2)

'(17.7661 0.145624 14.9265 0.160186 19.8049 11.3587 0.291248 22.062 0.145624 8.15494 0.232998 4.95122)

'(18.2648 0.737619 14.0499 16.8599 0.702494 14.4362 0.702494 18.6161 4.56621 1.93186 7.37619 1.75623))

;;============================================

;;Temperley-Kostka-Payne chord-based profiles:

(key-finder

'(8 0 0 0 2 11 0 5 7 0 5 2)

'(0.748 0.060 0.488 0.082 0.670 0.460 0.096 0.715 0.104 0.366 0.057 0.400)

'(0.712 0.084 0.474 0.618 0.049 0.460 0.105 0.747 0.404 0.067 0.133 0.330))

|#

;;////////////////////////////////////////////

;;============================================

;;////////////////////////////////////////////

(defun key-map (key)

(case key

(C-Major '(0 2 4 5 7 9 11))

(Db-Major '(1 3 5 6 8 10 0))

(D-Major '(2 4 6 7 9 11 1))

(Eb-Major '(3 5 7 8 10 0 2))

(E-Major '(4 6 8 9 11 1 3))

(F-Major '(5 7 9 10 0 2 4))

(F#-Major '(6 8 10 11 1 3 5))

(G-Major '(7 9 11 0 2 4 6))

(Ab-Major '(8 10 0 1 3 5 7))

(A-Major '(9 11 1 2 4 6 8))

(Bb-Major '(10 0 2 3 5 7 9))

(B-Major '(11 1 3 4 6 8 10))

(C-Minor '(0 2 3 5 7 8 10))

(C#-Minor '(1 3 4 6 8 9 11))

(D-Minor '(2 4 5 7 9 10 0))

(Eb-Minor '(3 5 6 8 10 11 1))

(E-Minor '(4 6 7 9 11 0 2))

(F-Minor '(5 7 8 10 0 1 3))

(F#-Minor '(6 8 9 11 1 2 4))

(G-Minor '(7 9 10 0 2 3 5))

(G#-Minor '(8 10 11 1 3 4 6))

(A-Minor '(9 11 0 2 4 5 7))

(Bb-Minor '(10 0 1 3 5 6 8))

(B-Minor '(11 1 2 4 6 7 9))))

(defun tag-key-map (key)

(loop for x in (key-map key)

for y in '(1 2 3 4 5 6 7)

collect (list x y)))

(defun get-modulo (midi-note-value)

(mod midi-note-value 12))

(defun search-for-modulo (key midi-note-value)

(loop for x in (tag-key-map key)

when (= (first x) (get-modulo midi-note-value))

return (second x)))

(defun get-stability (key midi-note-value)

(let ((current-value (search-for-modulo key midi-note-value)))

(case current-value

(1 6)

(3 5)

(5 5)

(2 4)

(4 4)

(6 4)

(7 4)

('nil 2))))

(defun absolute-difference (x y)

(abs (- x y)))

(defun get-proximity (note-value-1 note-value-2)

(let ((current-difference (absolute-difference note-value-1 note-value-2)))

(case current-difference

(0 36)

(1 36)

(2 32)

(3 25)

(4 20)

(5 16)

(6 12)

(7 9)

(8 6)

(9 4)

(10 2)

(11 1)

(12 0.25)

(13 0.02)

(14 0.01)

(t 0.01))))

;;////////////////////////////////////////////

;;Direction results are ordered by continuation, reversal and repetition weightings

;;////////////////////////////////////////////

(defun get-direction (note-value-1 note-value-2)

(let ((current-difference (absolute-difference note-value-1 note-value-2)))

(case current-difference

(0 '(6 0 2))

(1 '(20 0 7))

(2 '(12 0 4))

(3 '(6 0 2))

(4 '(0 0 0))

(5 '(0 6 2))

(6 '(0 12 4))

(7 '(0 25 8))

(8 '(0 36 12))

(9 '(0 52 17))

(10 '(0 75 25))

(t '(0 75 25)))))

(defun get-mobility (note-value-1 note-value-2)

(if (= (absolute-difference note-value-1 note-value-2) 0)

(/ 2.0 3.0)

1.0))

(defun interval-direction (note-value-1 note-value-2)

(let ((current-difference (- note-value-1 note-value-2)))

(cond ((< current-difference 0) '>)

((> current-difference 0) '<)

((= current-difference 0) '=))))

;;////////////////////////////////////////////

(defun take-by-number (n list)

(unless (< (length list) n)

(reverse (do ((input-list list (rest input-list))

(result nil (cons (first input-list) result))

(counter n (- counter 1)))

((= counter 0) result)))))

(defun filtering-by-number (number list)

(if (< (length list) number)

nil

(cons (take-by-number number list) (filtering-by-number number (rest list)))))

(defun get-logic-direction (filtered-melodic-cell)

(let ((direction-list (get-direction (first filtered-melodic-cell) (second filtered-melodic-cell)))

(first-interval (interval-direction (first filtered-melodic-cell)

(second filtered-melodic-cell)))

(second-interval (interval-direction (second filtered-melodic-cell)

(third filtered-melodic-cell))))

(cond ((or (and (equal first-interval second-interval)

(not (equal '= first-interval))

(not (equal '= second-interval)))

(and (equal '= first-interval)

(or (equal '> second-interval)

(equal '< second-interval))))

(first direction-list))

((and (not (equal first-interval second-interval))

(or (equal '= first-interval)

(and (or (equal '> second-interval)

(equal '< second-interval)))))

(second direction-list))

((or (and (equal first-interval second-interval)

(equal '= first-interval)

(equal '= second-interval))

(and (or (equal '> first-interval)

(equal '< first-interval))

(equal '= second-interval)))

(third direction-list)))))

(defun melodic-expectancy (key melodic-cell)

(+ (* (get-stability key (third melodic-cell))

(get-proximity (second melodic-cell) (third melodic-cell))

(get-mobility (second melodic-cell) (third melodic-cell)))

(get-logic-direction melodic-cell)))

;;============================================

;;============================================

;;////////////////////////////////////////////

;;============================================

;;////////////////////////////////////////////

(defun note-name* (note-number)

(list (elt '(c c# d d# e f f# g g# a a# b)

(rem note-number 12))

(- (truncate (/ note-number 12)) 1)))

(defun note-name (note-number)

(first

(remove #\space

(write-to-string

(note-name* note-number))))))

;;============================================

;;============================================

(defun melodic-expectancy-values (key melody)

(loop for x in (filtering-by-number 3 melody)

collect (list (third x)

(note-name (third x))

(melodic-expectancy key x))))

;;============================================

;;============================================

;;////////////////////////////////////////////

(defun get-up-down-octave (note-value)

(loop for x in '(-12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12)

collect (+ note-value x)))

(defun build-test-melodic-cells (interval)

(let ((up-down-octave (get-up-down-octave (second interval))))

(loop for x in up-down-octave

collect (append interval (list x)))))

(defun melodic-expectancy-test-values (key test-cells)

(loop for x in test-cells

collect (list (third x)

(note-name (third x))

(melodic-expectancy key x))))

(defun sorting (input-list)

(if (< (length input-list) 2)

input-list

(append (sorting (remove-if-not #'(lambda (x)

(<= x (first input-list)))

(rest input-list)))

(list (first input-list))

(sorting (remove-if #'(lambda (x)

(<= x (first input-list)))

(rest input-list))))))

(defun order-expectany-values (list)

(reverse

(sorting

(loop for x in list

collect (third x)))))

(defun order-expectancy-melodic-cells (compound-list)

(do ((sort-values

(order-expectany-values compound-list)

(rest sort-values))

(current-list

compound-list

(remove-if #'(lambda (x) (= (first sort-values) (third x))) current-list :count 1))

(output

nil

(cons (loop for x in current-list

for y = (first sort-values)

when (= y (third x))

return x)

output)))

((endp sort-values) (reverse output))))

(defun generate-and-order-expectancy-values (key interval)

(order-expectancy-melodic-cells

(melodic-expectancy-test-values

key

(build-test-melodic-cells interval))))

#|

(loop for x in (generate-and-order-expectancy-values 'c-major '(60 69))

collect (third x))

|#

(defun test-melodic-expectancy-cells-ordered (key interval)

(let* ((ordered-expectancy-values (generate-and-order-expectancy-values key interval))

(expectancy-values (loop for x in ordered-expectancy-values

collect (first x))))

(loop for y in expectancy-values

collect (append interval (list y)))))

;;============================================

;;============================================

;;(test-melodic-expectancy-cells-ordered 'c-major '(60 69))

;;(test-melodic-expectancy-cells-ordered 'c-major '(61 70))

;;============================================

;;============================================

(defun implicative-denial (key interval)

(let* ((expectancy-list (generate-and-order-expectancy-values key interval))

(high-expectancy-value (third (first expectancy-list)))

(denial-value (loop for x in expectancy-list

collect (- high-expectancy-value (third x)))))

(loop for y in expectancy-list

for z in denial-value

collect (append (butlast y) (list z)))))

;;////////////////////////////////////////////

(defun get-ordered-expectancy-values (key interval)

(let ((expectancy-values (test-melodic-expectancy-cells-ordered key interval)))

(loop for x in expectancy-values

collect (third x))))

;;////////////////////////////////////////////

;; Shared functions:

;;////////////////////////////////////////////

(defun integers-down (number)

(reverse (loop for x from 1 to number collect x)))

(defun sum-list (list)

(do ((sum 0 (+ sum (first local-list)))

(local-list list (rest local-list)))

((not local-list) sum)))

(defun fibo-process* (list)

(if (= (length list) 1) list

(do ((sum (first list) (+ sum (first local-list)))

(local-list (rest list) (rest local-list))

(output-list nil (cons sum output-list)))

((not local-list) (reverse (cons (+ (first (last list)) (first output-list)) output-list))))))

(defun weight-for-list (list)

(let ((pure-weight (/ 1.0 (sum-list (integers-down (length list))))))

(mapcar #'list list (fibo-process* (mapcar #'(lambda (x) (* x pure-weight)) (integers-down (length list)))))))

(defun uniform-random-weight (table)

(let ((x (random 1.0)))

(loop for d in table

for p = (second d)

when (<= x p )

return (first d))))

#|

(loop repeat 100

collect

(uniform-random-weight

'((11 0.25) (10 0.46428573) (9 0.6428572) (8 0.7857143) (6 0.8928572) (3 0.9642858) (1 1.0000001))))

|#

(defun linear-random-weight (table)

(let ((x (/ (+ (random 1.0) (random 1.0)) 2.0)))

(loop for d in table

for p = (second d)

when (<= x p )

return (first d))))

#|

(loop repeat 100

collect

(uniform-random-weight

'((11 0.25) (10 0.46428573) (9 0.6428572) (8 0.7857143) (6 0.8928572) (3 0.9642858) (1 1.0000001))))

|#

;;////////////////////////////////////////////

;; Melodic Generation on Expectancy Values - Tonal Context

;;////////////////////////////////////////////

(defun melodic-generation-by-high-expectancy-value (n key interval-seed)

(do* ((counter (- n 1) (decf counter))

(current-interval-reference interval-seed (list (second output) (first output)))

(output (cons (first (get-ordered-expectancy-values key current-interval-reference))

(reverse interval-seed))

(cons

(first

(get-ordered-expectancy-values key current-interval-reference))

output)))

((= 0 counter) (reverse output))))

;;Weighted random selection

;;Uniform

(defun melodic-expectancy-random-generation (n key interval-seed)

(do* ((counter (- n 1) (decf counter))

(current-interval-reference interval-seed (list (second output) (first output)))

(output (cons

(uniform-random-weight

(weight-for-list

(get-ordered-expectancy-values key current-interval-reference)))

(reverse interval-seed))

(cons

(uniform-random-weight

(weight-for-list

(get-ordered-expectancy-values key current-interval-reference)))

output)))

((= 0 counter) (reverse output))))

;;============================================

;;(melodic-expectancy-random-generation 10 'c-major '(60 69))

;;============================================

;;////////////////////////////////////////////

;; Melodic Expectancy - Atonal Context

;;////////////////////////////////////////////

;;============================================

;; Shared file: melodic-generation-harmony.lisp

;;============================================

;;////////////////////////////////////////////

;; Melodic generation by harmonization

;;////////////////////////////////////////////

;; Mauricio Rodriguez 2009

;;////////////////////////////////////////////

;; marod@stanford.edu

;;////////////////////////////////////////////

(defun invert-interval-list (reservoir)

(loop for x in reservoir

collect (* x -1)))

(defun build-melodic-intervals* (reference-note reservoir)

(let ((interval-reservoir (append (reverse reservoir)

(invert-interval-list reservoir))))

(loop for x in interval-reservoir

collect (+ reference-note x))))

(defun build-melodic-intervals** (chord reservoir)

(loop for x in chord

append (build-melodic-intervals* x reservoir)))

(defun build-melodic-intervals (chord reservoir)

(sort (remove-duplicates (append chord (build-melodic-intervals** chord reservoir))) #'>))

;;///Shared function(s): sorting///

#|

(defun sorting (input-list)

(if (< (length input-list) 2)

input-list

(append (sorting (remove-if-not #'(lambda (x)

(<= x (first input-list)))

(rest input-list)))

(list (first input-list))

(sorting (remove-if #'(lambda (x)

(<= x (first input-list)))

(rest input-list))))))

|#

(defun build-harmonic-entities-with-melodic-intervals (chord reservoir)

(let ((built-melodic-patterns (build-melodic-intervals chord reservoir)))

(loop for x in built-melodic-patterns

collect (sorting (cons x chord)))))

;;///Shared function(s): reduce-to-modulo, make-pairs*, make-pairs, absolute-difference,

;;intervalic-difference, all-members-in-list-p*, nil-as-member-p, all-members-in-list-p,

;;equal-to-threshold-p, check-for-repeated-arguments-p, check-interval-content-and-non-repetition-modulo,

;;filter-repeated-arguments, flat-list, take-by-number, filtering-by-number, chord-interval-relations///

(defun reduce-to-modulo (harmonic-entiity)

(loop for x in harmonic-entiity

collect (mod x 12)))

(defun make-pairs* (list)

(if (endp list)

nil

(cons (List (first list) (second list))

(make-pairs* (rest list)))))

(defun make-pairs (list)

(let ((current-list (make-pairs* list)))

(loop for x in current-list

when (not (equal (second x) nil))

collect x)))

#|

(defun absolute-difference (x y)

(abs (- x y)))

|#

(defun intervalic-difference (list)

(mapcar #'(lambda (x) (absolute-difference (first x) (second x))) (make-pairs list)))

(defun all-members-in-list-p* (members list)

(mapcar #'(lambda (x) (find x list)) members))

(defun nil-as-member-p (list)

(cond ((endp list) t)

((equal (first list) 'nil) nil)

(t (nil-as-member-p (rest list)))))

(defun all-members-in-list-p (members list)

(nil-as-member-p (all-members-in-list-p* members list)))

(defun equal-to-threshold-p (number)

(if (>= number 2)

t

nil))

(defun check-for-repeated-arguments-p (list)

(do ((current-list list (rest current-list))

(output nil (cons (count (first current-list) list) output)))

((endp current-list) (some #'equal-to-threshold-p (reverse output)))))

(defun check-interval-content-and-non-repetition-modulo (harmonic-entity interval-reservoir)

(if (and (not (check-for-repeated-arguments-p (reduce-to-modulo harmonic-entity)))

(all-members-in-list-p (intervalic-difference harmonic-entity) interval-reservoir))

t

nil))

(defun filter-repeated-arguments (list)

(cond ((endp list)

nil)

((check-for-repeated-arguments-p (first list))

(filter-repeated-arguments (rest list)))

(t (cons (first list)

(filter-repeated-arguments (rest list))))))

(defun flat-list (list)

(loop for x in list

append x))

#|

(defun take-by-number (n list)

(unless (< (length list) n)

(reverse (do ((input-list list (rest input-list))

(result nil (cons (first input-list) result))

(counter n (- counter 1)))

((= counter 0) result)))))

(defun filtering-by-number (number list)

(if (< (length list) number)

nil

(cons (take-by-number number list) (filtering-by-number number (rest list)))))

|#

(defun chord-interval-relations* (list)

(filter-repeated-arguments

(remove-duplicates

(mapcar #'(lambda (z) (sort z '<))

(flat-list (loop for x in (filtering-by-number 1 list)

collect (mapcar #'(lambda (y) (append x (list y)))

list))))

:test #'equal)))

(defun chord-interval-relations (list)

(remove-duplicates

(sort (loop for x in (chord-interval-relations* list)

append (intervalic-difference x)) #'<)))

(defun reduce-to-modulo-with-reservoir (harmonic-entiity reservoir)

(loop for x in harmonic-entiity

collect (if (<= x (apply #'max reservoir))

x

(mod x 12))))

(defun check-chord-interval-relations-with-reservoir** (chord-list reservoir)

(all-members-in-list-p

(reduce-to-modulo (chord-interval-relations chord-list))

reservoir))

(defun check-chord-interval-relations-in-harmony-list* (list reservoir-list)

(cond ((endp list)

nil)

((check-for-repeated-arguments-p (first list))

(cons (first list)

(check-chord-interval-relations-in-harmony-list* (rest list) reservoir-list)))

((check-chord-interval-relations-with-reservoir** (first list) reservoir-list)

(cons (first list)

(check-chord-interval-relations-in-harmony-list* (rest list) reservoir-list)))

(t (check-chord-interval-relations-in-harmony-list* (rest list) reservoir-list))))

(defun check-chord-harmony-list-with-melodic-pattern (chord reservoir-interval-list)

(check-chord-interval-relations-in-harmony-list*

(build-harmonic-entities-with-melodic-intervals chord reservoir-interval-list)

reservoir-interval-list))

#|

(defun get-melody-from-harmony (chord-reference harmony-list)

(loop for x in harmony-list

collect (set-difference x chord-reference)))

|#

(defun get-repeated-argument* (chord chord-clon)

(cond ((endp chord) nil)

((= 2 (count (first chord) chord-clon)) (list (first chord)))

(t (get-repeated-argument* (rest chord) chord-clon))))

(defun get-repeated-argument (chord)

(get-repeated-argument* chord chord))

(defun get-melody-from-harmony (chord-reference harmony-list)

(cond ((endp harmony-list)

nil)

((get-repeated-argument (first harmony-list))

(cons (get-repeated-argument (first harmony-list))

(get-melody-from-harmony chord-reference (rest harmony-list))))

(t

(cons (set-difference (first harmony-list) chord-reference)

(get-melody-from-harmony chord-reference (rest harmony-list))))))

(defun melodic-interval-relations* (list)

(filter-repeated-arguments

(flat-list (loop for x in (filtering-by-number 1 list)

collect (mapcar #'(lambda (y) (append x (list y)))

list)))))

(defun check-melodic-interval-relations-in-harmony-list* (list reservoir-list)

(cond ((endp list)

nil)

((check-for-repeated-arguments-p (first list))

(cons (first list)

(check-melodic-interval-relations-in-harmony-list* (rest list) reservoir-list)))

((check-chord-interval-relations-with-reservoir** (first list) reservoir-list)

(cons (first list)

(check-melodic-interval-relations-in-harmony-list* (rest list) reservoir-list)))

(t (check-melodic-interval-relations-in-harmony-list* (rest list) reservoir-list))))

(defun melodic-interval-relations** (list)

(loop for x in list

collect (list x list)))

(defun expand-and-filter-melodic-relations* (index-list)

(filter-repeated-arguments

(loop for x in (second index-list)

collect (cons (first index-list) (list x)))))

#|

(defun get-melodic-net (chord-reference interval-reservoir)

(let* ((melodic-reservoir

(flat-list (get-melody-from-harmony

chord-reference

(check-chord-harmony-list-with-melodic-pattern chord-reference interval-reservoir))))

(interval-relations

(melodic-interval-relations** melodic-reservoir)))

(loop for x in interval-relations

append (check-melodic-interval-relations-in-harmony-list*

(expand-and-filter-melodic-relations* x)

interval-reservoir))))

|#

(defun build-node-and-paths (list)

(if (equal 'nil list)

nil

(list (first (first list))

(loop for x in list

collect (second x)))))

(defun get-melodic-net (chord-reference interval-reservoir)

(let* ((melodic-reservoir

(flat-list (get-melody-from-harmony

chord-reference

(check-chord-harmony-list-with-melodic-pattern chord-reference interval-reservoir))))

(interval-relations

(melodic-interval-relations** melodic-reservoir)))

(loop for x in interval-relations

collect (build-node-and-paths

(check-melodic-interval-relations-in-harmony-list*

(expand-and-filter-melodic-relations* x)

interval-reservoir)))))

;;============================================

;;(get-melodic-net '(59 60 63) '(1 2 3 4 10 11 13 14))

;;(get-melodic-net '(48 59 63 76) '(1 2 3 4 10 11 13 14))

;;(get-melodic-net '(48 59 63 74) '(1 2 3 4 10 11 13 14))

;;============================================

#|

(loop for x in (get-melodic-net '(48 59 63 74) '(1 2 3 4 10 11 13 14))

do (print x))

|#

(defun get-melodic-field (harmonic-seed interval-reservoir)

(reverse

(flat-list (get-melody-from-harmony

harmonic-seed

(check-chord-harmony-list-with-melodic-pattern harmonic-seed interval-reservoir)))))

;;============================================

;;(get-melodic-field '(48 59 63 76) '(1 2 3 4 10 11 13 14))

;;(get-melodic-field '(48 59 63 74) '(1 2 3 4 10 11 13 14))

;;(get-melodic-field '(48 59 63 74) '(1 2 3 4 5 10 11 13 14))

;;============================================

(defun check-generated-chords-in-modulo-reduction (harmonic-seed interval-reservoir)

(loop for x in (build-harmonic-entities-with-melodic-intervals harmonic-seed interval-reservoir)

collect (chord-interval-relations (reduce-to-modulo x))))

(defvar *melodic-net* nil)

#|

*melodic-net*

|#

(defun define-net (harmonic-seed interval-reservoir)

(setf *melodic-net* nil)

(setf *melodic-net* (get-melodic-net harmonic-seed interval-reservoir)))

#|

(defun legal-melodic-movement-p (melodic-pair)

(let* ((melodic-net *melodic-net*)

(current-inspection (loop for x in melodic-net

when (= (first x) (first melodic-pair))

return (second x))))

(if (member (second melodic-pair) current-inspection)

t

nil)))

|#

;; To allow repetitions on legal melodic-movements:

(defun legal-melodic-movement-p (melodic-pair)

(if (equal (first melodic-pair) (second melodic-pair))

t

(let* ((melodic-net *melodic-net*)

(current-inspection (loop for x in melodic-net

when (= (first x) (first melodic-pair))

return (second x))))

(if (member (second melodic-pair) current-inspection)

t

nil))))

;;////////////////////////////////////////////

;;============================================

;;////////////////////////////////////////////

(defun atonal-melodic-expectancy (melodic-cell)

(+ (* (get-proximity (second melodic-cell) (third melodic-cell))

(get-mobility (second melodic-cell) (third melodic-cell)))

(get-logic-direction melodic-cell)))

;;============================================

;;(atonal-melodic-expectancy '(48 59 60))

;;============================================

(defun get-up-down-from-interval-reservoir (note-value interval-reservoir)

(let ((negative-reservoir (reverse (loop for alpha in interval-reservoir

collect (* alpha -1)))))

(loop for x in (append negative-reservoir (list 0) interval-reservoir)

collect (+ note-value x))))

(defun build-melodic-cells-from-interval-reservoir (interval-reference interval-reservoir)

(let ((up-down-reservoir

(get-up-down-from-interval-reservoir (second interval-reference) interval-reservoir)))

(loop for x in up-down-reservoir

collect (append interval-reference (list x)))))

(defun melodic-expectancy-with-interval-reservoir (melodic-cells)

(loop for x in melodic-cells

collect (list (third x)

(note-name (third x))

(atonal-melodic-expectancy x))))

#|

(melodic-expectancy-with-interval-reservoir

(build-melodic-cells-from-interval-reservoir '(48 60) '(1 2 3 4 10 11 13 14)))

|#

(defun generate-and-order-expectancy-values-with-reservoir (interval-reference interval-reservoir)

(order-expectancy-melodic-cells

(melodic-expectancy-with-interval-reservoir

(build-melodic-cells-from-interval-reservoir interval-reference interval-reservoir))))

(defun melodic-expectancy-cells-ordered-with-reservoir (interval-reference interval-reservoir)

(let* ((ordered-expectancy-values

(generate-and-order-expectancy-values-with-reservoir interval-reference interval-reservoir))

(expectancy-values (loop for x in ordered-expectancy-values

collect (first x))))

(loop for y in expectancy-values

collect (append interval-reference (list y)))))

(defun get-ordered-expectancy-values-with-reservoir (interval-reference interval-reservoir)

(let ((expectancy-values

(melodic-expectancy-cells-ordered-with-reservoir interval-reference interval-reservoir)))

(loop for x in expectancy-values

collect (third x))))

;;////////////////////////////////////////////

;; Atonal Melodic Generation

;;////////////////////////////////////////////

(defun compare-values (reference list)

(cond ((endp list) nil)

((equal (first (first list)) reference) (first list))

(t (compare-values reference (rest list)))))

(defun check-expectancy-values-in-melodic-net (interval-reference interval-reservoir)

(loop for x in (get-ordered-expectancy-values-with-reservoir interval-reference interval-reservoir)

when (compare-values x *melodic-net*)

collect (compare-values x *melodic-net*)))

(defun get-expectancy-values-from-ordered-net (interval-reference interval-reservoir)

(loop for x in (check-expectancy-values-in-melodic-net interval-reference interval-reservoir)

collect (first x)))

(defun check-and-get-legal-movements-in-ordered-net (interval-reference interval-reservoir)

(let ((ordered-net (get-expectancy-values-from-ordered-net interval-reference interval-reservoir)))

(loop for x in ordered-net

when (legal-melodic-movement-p (list (second interval-reference) x))

collect x)))

#|

(weight-for-list

(check-and-get-legal-movements-in-ordered-net '(59 60) '(1 2 3 4 10 11 13 14)))

(uniform-random-weight

(weight-for-list

(check-and-get-legal-movements-in-ordered-net '(59 60) '(1 2 3 4 10 11 13 14))))

(weight-for-list

(check-and-get-legal-movements-in-ordered-net '(59 59) '(1 2 3 4 10 11 13 14)))

(uniform-random-weight

(weight-for-list

(check-and-get-legal-movements-in-ordered-net '(59 59) '(1 2 3 4 10 11 13 14))))

|#

(defun melodic-start (harmonic-seed)

(elt harmonic-seed (random (length harmonic-seed))))

#|

(defun starting-interval (harmonic-seed)

(let ((start (melodic-start harmonic-seed)))

(list start start)))

|#

(defun starting-interval (harmonic-seed &optional starting-note)

(if starting-note

(list starting-note starting-note)

(let ((start (melodic-start harmonic-seed)))

(list start start))))

;;////////////////////////////////////////////

;; Random Generation

;;////////////////////////////////////////////

(defun atonal-melodic-expectancy-random-generation (n harmonic-seed interval-reservoir &optional starting-note)

(define-net harmonic-seed interval-reservoir)

(let ((interval-seed (if starting-note

(starting-interval harmonic-seed starting-note)

(starting-interval harmonic-seed))))

(do* ((counter

(- n 2)

(decf counter))

(current-interval-reference

interval-seed

(list (second output) (first output)))

(output (cons

(uniform-random-weight

(weight-for-list

(check-and-get-legal-movements-in-ordered-net

current-interval-reference

interval-reservoir)))

(list (second interval-seed)))

(cons

(uniform-random-weight

(weight-for-list

(check-and-get-legal-movements-in-ordered-net

current-interval-reference

interval-reservoir)))

output)))

((= 0 counter) (reverse output)))))

;;(atonal-melodic-expectancy-random-generation 4 '(48 59 63 74) '(1 2 3 4 10 11 13 14))

;;(atonal-melodic-expectancy-random-generation 4 '(48 59 63 74) '(1 2 3 4 10 11 13 14) 74)

;;(atonal-melodic-expectancy-random-generation 4 '(48 57 59 60) '(1 2 3 4 10 11 13 14))

;;(atonal-melodic-expectancy-random-generation 4 '(48 57 59 60) '(1 2 3 4 10 11 13 14) 59)

;;(atonal-melodic-expectancy-random-generation 4 '(48 57 59 60) '(1 2 3 4 5 7 10 11 13 14) 59)

;;////////////////////////////////////////////

;; Melodic Net Printing

;;////////////////////////////////////////////

(defun print-melodic-net* (harmonic-seed interval-reservoir)

(let ((melodic-net (get-melodic-net harmonic-seed interval-reservoir)))

(loop for x in melodic-net

collect (list (first x) (sort (cons (first x) (second x)) #'<)))))

;;(print-melodic-net* '(48 59 63 74) '(1 2 3 4 10 11))

(defun print-melodic-net (harmonic-seed interval-reservoir)

(loop for x in (print-melodic-net* harmonic-seed interval-reservoir)

do (print x))

(format t "~&~a" "====================")

(loop for x in (print-melodic-net* harmonic-seed interval-reservoir)

collect (first x)))

;;(print-melodic-net '(48 59 63 74) '(1 2 3 4 10 11))

;;(print-melodic-net '(48 59 63 74) '(1 2 3 4 5 10 11))

;;(atonal-melodic-expectancy-random-generation 8 '(48 59 63 74) '(1 2 3 4 10 11))

;;(atonal-melodic-expectancy-random-generation 8 '(48 59 63 74) '(1 2 3 4 5 10 11) 74)