Posts posted by AM
-
-
Why limit a hoquetus to just four voices? Imagine it instead for fifty guitars dispersed throughout the space—not as a mere progression, but as a finely shaped structure articulated by a vector envelope. A concept piece, perhaps best experienced on a quiet Sunday evening 😅
Have a look at the (list-plot...)...
(This essentially creates spatial and sonic structures similar to those in Ligeti’s Atmosphères or XENAKIS... and on this point stochastic method would be interesting ;-))
;; 50 GUITARISTS should play a hocket in an "specific enevelope-order" (setf 50guits (list-plot (vector-map (gen-integer 1 50) (vector-to-envelope2 '(4.2456284 7.2268248 6.4440737) '(3.682579 8.78879 10.000002) (gen-noise 356) :segment (primes 12) :type 3)))) (progn (setf mat (make-omn :pitch '(e4) :length (gen-repeat 50 's))) ;; allvoices for 50 players (gen-hocket mat :density (gen-binary-for-hocket 50guits)))i like to be guitarist number one - just 2 notes to play!

-
everything okay with this code.... use binary... like janusz coded it...
(progn (setf mat '(q c4 d4 e4 f4 g4 a4 b4 c5)) (gen-hocket mat :density '((1 0 0 0 1 0 0 0 0 0 1) (0 1 0 1 0 1 0 0 0 1 0) (0 0 1 0 0 0 1 0 1 0 0) (0 0 0 0 0 0 0 1 0 0 0))) (setf mv (merge-voices v1 v2 v3 v4)))and when you generate the binary seq with.... it's that simple.
(defun gen-binary-for-hocket (alist) (let ((vlist (sort-asc (remove-duplicates alist)))) (loop for v in vlist collect (loop for i in alist when (= i v) collect 1 else collect 0)))) ;;; now with OPMO-function... (progn (setf mat '(q c4 d4 e4 f4 g4 a4 b4 c5)) (gen-hocket mat :density (gen-binary-for-hocket '(1 2 3 2 1 2 3 4 3 2 1))) (setf mv (merge-voices v1 v2 v3 v4))) -
the great thing about Opusmodus is that you can code your own solutions for ideas, problems, or historical models – it gives you a lot of freedom. MAX/MSP, PWGL, or CLM are/were like that too…
thx @janusz for your personal support!
here is another solution for the traditional hocket... take it or leave it or code it in your own personal way ;-)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; generates hocket-voice (defun gen-hocket-voice (elist omnlist) (let ((omnevents (single-events omnlist)) (elist (gen-repeat 5 elist))) (loop repeat (length (single-events omnlist)) for cnt = 0 then (incf cnt) when (= (nth cnt elist) 1) collect (nth cnt omnevents) else collect (if (length-restp (car (nth cnt omnevents))) (nth cnt omnevents) (* -1 (car (flatten (omn :length (nth cnt omnevents))))))))) ;; splits isntruments for binary.. (defun gen-binary-for-hocket (alist) (let ((vlist (sort-asc (remove-duplicates alist)))) (loop for v in vlist collect (loop for i in alist when (= i v) collect 1 else collect 0)))) ;; each number is an instrumnet -> for voices (gen-binary-for-hocket '(1 2 3 2 1 2 3 4 3 2 1))) => ((1 0 0 0 1 0 0 0 0 0 1) (0 1 0 1 0 1 0 0 0 1 0) (0 0 1 0 0 0 1 0 1 0 0) (0 0 0 0 0 0 0 1 0 0 0)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; EXAMPLE ;; rnd-omn-seq (setf omn-seq (make-omn :pitch (make-scale 'c4 23) :length '(s) :span :pitch)) ;; voices 1-4 (setf v1 (gen-hocket-voice (first (gen-binary-for-hocket '(1 2 3 2 1 2 3 4 3 2 1))) omn-seq)) (setf v2 (gen-hocket-voice (second (gen-binary-for-hocket '(1 2 3 2 1 2 3 4 3 2 1))) omn-seq)) (setf v3 (gen-hocket-voice (third (gen-binary-for-hocket '(1 2 3 2 1 2 3 4 3 2 1))) omn-seq)) (setf v4 (gen-hocket-voice (fourth (gen-binary-for-hocket '(1 2 3 2 1 2 3 4 3 2 1))) omn-seq)) ;; check -> when chromatic scale then everything is okayx (merge-voices v1 v2 v3 v4) -
If it weren’t exclusively stochastic, but if it were also possible to ‘filter’ the events through binary lists, then one could build interesting instrumentation matrices/trajectories (for example, using vector-envelopes that would then be mapped voice by voice into binary lists). Would that be an option?
-
a simple hocket-function - starting with an OMN-sequence
(defun gen-hocket-voice (elist omnlist) (let ((omnevents (single-events omnlist))) (loop repeat (length (single-events omnlist)) for cnt = 0 then (incf cnt) when (= (nth cnt elist) 1) collect (nth cnt omnevents) else collect (if (length-restp (car (nth cnt omnevents))) (nth cnt omnevents) (* -1 (car (flatten (omn :length (nth cnt omnevents))))))))) ;; eveluate this (progn ;(setf omnseq '(s c4 mf cs4 d4 ds4 -q s e4 f4 -1 s fs4 g4 gs4 a4)) ; simple ;(setf omnseq (flatten (gen-rnd-omn 3 8 1 3 '(c4 cs4 d4 ds4 e4 f4 fs4 g4 gs4 a4) 's nil) )) ; more complex (setf omnseq (flatten (filter-first 5 (gen-rnd-omn 8 '(8 8 12 4) 2 4 '(c4 cs4 d4 ds4 e4 f4 fs4 g4 gs4 a4) 's '(p mp f) :rotate '(-1 2 0 1) :type 2)))) (setf events1 '(0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1)) ; an eventlist (setf events2 '(1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0)) ; another eventlist (setf events3 '(1 1 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1)) ; another eventlist (setf instr1 (gen-hocket-voice events1 omnseq)) (setf instr2 (gen-hocket-voice events2 omnseq)) (setf instr3 (gen-hocket-voice events3 omnseq)) ;; check it -> if one voice then everything okay (merge-voices instr1 instr2 instr3)) -
-
packed in a function ... as many voices you want...
;; packed in a function (defun gen-omn-by-events (elist plist rlist &key (vel 'p)) (loop repeat (length elist) for cnt = 0 then (incf cnt) when (= (nth cnt elist) 1) collect (list (nth cnt rlist) (nth cnt plist) vel) else collect (* -1 (nth cnt rlist )))) (setf events1 '(1 0 1 1 0 0 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1 0 1)) ; an eventlist (setf events2 '(0 1 0 0 0 1 0 0 1 1 0 1 0 0 1 0 1 0 0 0 1 1 1 0)) ; another eventlist (setf events3 '(1 1 1 0 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 0 1 0 0 0)) ; another eventlist (setf instr1 (gen-omn-by-events events1 plist rlist :vel 'p)) (setf instr2 (gen-omn-by-events events2 plist rlist :vel 'f)) (setf instr3 (gen-omn-by-events events3 plist rlist :vel 'ppp)) ;; ........ ;; check it (merge-voices instr1 instr2 instr3) -
a (very simple) more lispian version
(setf l1 '(1 0 1 1 0 0 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1 0 1)) ; an eventlist (setf l2 '(0 1 0 0 0 1 0 0 1 1 0 1 0 0 1 0 1 0 0 0 1 1 1 0)) ; another eventlist (setf plist (gen-repeat 2 (rnd-air :type :pitch))) ;; a rnd-pitch-seq (setf rlist (rnd-sample 50 '(1/16 2/16 3/16 5/16))) ;; a rnd-length-seq ;; voice 1 (setf instr1 (loop repeat (length l1) for cnt = 0 then (incf cnt) when (= (nth cnt l1) 1) collect (list (nth cnt rlist) (nth cnt plist) 'f) else collect (* -1 (nth cnt rlist)))) ;; voice 2 (setf instr2 (loop repeat (length l2) for cnt = 0 then (incf cnt) when (= (nth cnt l2) 1) collect (list (nth cnt rlist) (nth cnt plist) 'p) else collect (* -1 (nth cnt rlist )))) ;; check by MERGE (merge-voices instr1 instr2) -
-
-
Here’s a small function I needed because I’m working with "binary counting patterns". All patterns must always have the same length (a fixed bit length determined by the largest value).
(defun dec-to-bin-rhythm (ilist) (let ((span (find-max (mapcar 'length (decimal-to-binary ilist))))) (loop for i in (binary-rhythm span ilist 1 :type 1) collect (loop for x in i when (< x 0) append (gen-repeat (abs x) 0) else collect x)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; to ensure the pattern is always the same length, the bit length for all decimal-to-binary conversions is adjusted to match the largest decimal number ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (dec-to-bin-rhythm '(234234 1 23 110 )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; binary-counting-rhythm -> counting from x to y ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setf bitseq (dec-to-bin-rhythm (gen-integer 1 145))) ;; 8-bit (omn-to-measure (make-omn :pitch '(c5) :length (gen-length bitseq '1/32) :velocity '(mf)) '(2/8)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; examples with list-plot ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (progn (setf bitseq (dec-to-bin-rhythm (gen-integer 1 79))) (length-list-plot (flatten bitseq) :join-points t :style :fill)) (progn (setf bitseq (dec-to-bin-rhythm (gen-integer 1 230 3))) ;; count with step 3 (length-list-plot (flatten bitseq) :join-points t :style :fill)) (progn (setf bitseq (dec-to-bin-rhythm (primes 50))) (length-list-plot (flatten bitseq) :join-points t :style :fill))A "Binary Counting Filter": You can also think of it (a liitle bit) like Tom Johnson’s work — the filter/binary approach generates all possible combinations etc...
(defun binary-count-filter (&key (type 'pos) (n 50) minp maxp minl maxl field (rhy '1/16)) (progn (setf n-chords n) (setf pseq (dec-to-bin-rhythm (gen-integer minp maxp))) (setf lseq (dec-to-bin-rhythm (gen-integer minl maxl)));(cellular-automaton lrule n-chords linit)) (setf positions (loop for i in pseq collect (position-item 1 i))) (setf chords (if (equal type 'neg) (loop for i in positions collect (chordize (remove-duplicates (melodize (position-remove i field))))) (loop for i in positions collect (chordize (position-filter i field))))) (setf lengths (loop for i in (flatten lseq) when (= i 1) collect rhy else collect (* -1 rhy))) (make-omn :pitch chords :length lengths :velocity '(ppp)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; examples counting 1 to 123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; type: pos -> play/chordize the 1-values (binary-count-filter :type 'pos :minp 1 :maxp 123 :field (make-scale 'c4 11 :alt '(1 2 3 7)) :minl 1 :maxl 123 :rhy '1/16) ;; type: neg -> play/chordize the 0-values (binary-count-filter :type 'neg :minp 1 :maxp 123 :field (make-scale 'c4 11 :alt '(1 2 3 7)) :minl 1 :maxl 123 :rhy '1/16) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 2 more examples with counting 23 to 255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; type: pos -> play/chordize the 1-values (binary-count-filter :type 'pos :minp 23 :maxp 255 :field (make-scale 'c4 11 :alt '(1 2 3 7)) :minl 23 :maxl 255 :rhy '1/32) ;; type: pos -> play/chordize the 0-values (binary-count-filter :type 'neg :minp 23 :maxp 255 :field (make-scale 'c4 11 :alt '(1 2 3 7)) :minl 23 :maxl 255 :rhy '1/32) -
Here's a little function that generates OMN-Seqs with CA-filter (pos/neg) with a CA-Rhy - both parameters independently.
Have fun - André
(defun cellular-automaton-filter (&key (type 'pos) (n 200) prule pinit lrule linit field (rhy '1/16)) (progn (setf n-chords n) (setf pseq (cellular-automaton prule n-chords pinit)) ;'(0 0 0 0 0 0 1 0 0 0 0 0 0))) (setf lseq (cellular-automaton lrule n-chords linit)) (setf positions (loop for i in pseq collect (position-item 1 i))) (setf chords (if (equal type 'neg) (loop for i in positions collect (chordize (position-remove i field))) (loop for i in positions collect (chordize (position-filter i field))) )) (setf lengths (loop for i in (flatten lseq) when (= i 1) collect rhy else collect (* -1 rhy))) (make-omn :pitch chords :length lengths :velocity '(ppp)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; type: pos -> play/chordize the 1-values (cellular-automaton-filter :type 'pos :prule 110 :pinit '(0 0 0 0 0 1 0 0 1 0 0 0 0 0 0) :field (gen-sieve '(f0 f7) '(6 3 4 6 3 4) :type :pitch) :lrule 26 :linit '(0 0 0 0 0 1 0 0 1 0 0 0 0 0 0) :rhy '1/20) ;; type: neg -> play/chordize the 0-values (cellular-automaton-filter :type 'neg :prule 110 :pinit '(0 0 0 0 0 1 0 0 1 0 0 0 0 0 0) :field (gen-sieve '(f0 f7) '(6 3 4 6 3 4) :type :pitch) :lrule 26 :linit '(0 0 0 0 0 1 0 0 1 0 0 0 0 0 0) :rhy '1/32) -
Fixed intervals: each generation extracts a predefined interval-sequence. Within the simulation loop—which runs and visualizes multiple generations—users can choose whether to display intervals or absolute pitches.
With every generation (or evaluation), the initial binary sequence is modified. This dynamic updating makes the specific behavior of each rule more apparent, allowing for clearer comparisons between different cellular automaton rules.
(progn ;; set rule number ;(setf rule 12) (setf rule (random 257)) ;; set n simulations (setf sims 5) (loop repeat sims do (progn (setf intervals (pitch-to-interval (rnd-air :group :symmetric :type :pitch :seed 1234))) (setf seq (cellular-automaton rule 200 (gen-binary-rnd 1 11 1 3))) (setf positions (loop for i in seq collect (position-item 1 i))) (setf ilist (loop for i in positions collect (position-filter i intervals))) (setf plist (loop for i in ilist collect (interval-to-pitch i))) (setf plist2 (interval-to-pitch (flatten ilist)))) ;; intervals ; do (list-plot (flatten ilist) :join-points nil :style :fill) ;; pitches every gen starting on c4 ;do (pitch-list-plot (flatten plist) :join-points t :style :fill)) ;; pitches all (without gen restart) do (pitch-list-plot (flatten plist2) :join-points t :style :fill) do (sleep 1))) -
Here’s a small technical idea... just with a "random-chord"
(progn (setf chord (rnd-sample-seq 10 (gen-sieve '(c3 g7) '(1 2 4 7 4 2) :type :pitch))) (setf rule30 (cellular-automaton 30 200 '(0 0 0 1 0 1 0 0 0 0))) (setf positions (loop for i in rule30 collect (position-item 1 i))) (setf chords (loop for i in positions collect (chordize (position-filter i chord)))) (pitch-list-plot (flatten chords) :join-chords t))https://plato.stanford.edu/entries/cellular-automata/supplement.html
-
Weird notation shows up when I merge the following voices—on their own, there’s no problem.
;; two versions (setf v1 '((-3he d4 pppp - d4 - d4) (-3he d4 pppp - d4 - -))) (setf v2 '((-7wq - eb5 pppp ten - eb5 ten - eb5 ten) (-7wq eb5 pppp ten - eb5 ten - - -))) (merge-voices v1 v2) (setf v1 '(-3he d4 pppp - d4 - d4 -3he d4 pppp - d4 - -)) (setf v2 '(-7wq - eb5 pppp ten - eb5 ten - eb5 ten -7wq eb5 pppp ten - eb5 ten - - -)) (merge-voices v1 v2) -
-
-
-
-
(defun reset-integer-sequence (alist &key (offset 0) (flatten nil)) (let ((min (find-min (flatten alist)))) (progn (setf alist (cond ((listp (car alist)) (loop for j in alist collect (loop for i in j collect (+ (- i min) offset)))) (t (loop for i in alist collect (+ (- i min) offset))))) (if (equal flatten t) (flatten alist) alist)))) -
I’m trying to merge two voices, but the grace notes get lost in the process. What do I need to do differently? Thanks for any advice!
Greetings
André
(setf v1 '(-1/4 1/28 eb5 p ten a4 bb2 ff ten+marc (-acc 1/8 gs4 mf leg) 1/28 b4 ppppp ten -3/28)) (setf v2 '(-6/28 (-acc 1/8 f6 ff) 3/28 d4e9 pppp ten -5/28)) (merge-voices v1 v2) => (-7w. 7q^7h. d4e9 pppp ten eb5 p ten a4 bb2 ff ten+marc b4 ppppp ten -7h.) -
Here is a function (with subfunctions) that operates based on the principle of the Brownian bridge. You define the start and end, and with each generation, an extended embellishment emerges. The principle is simple and allows for the creation of ornaments. Attached are some examples — I’ve structured them this way to make the principle easier to understand.
Here is a small graphical model showing four generations. The start and end points remain the same, while new random points are added in between with each generation.

The Code & Examples
(defun pick (a b &key (span 5)) (let ((rnd1 (car (rnd-number 1 (+ a span) (- a span)))) (rnd2 (car (rnd-number 1 (+ b span) (- b span)))) (n)) (progn (setf n (car (rnd-number 1 rnd1 rnd2))) (if (or (= n a) (= n b)) (+ (rnd-pick '(1 -1)) n) n)))) (defun gen-brownian-bridge (n startend &key (all-gen nil) (output 'integer) (span 5)) (let ((seq) (liste startend)) (progn (setf seq (append (list startend) (loop repeat n do (setf liste (filter-repeat 1 (loop repeat (1- (length liste)) for cnt = 0 then (incf cnt) append (append (list (nth cnt liste) (pick (nth cnt liste) (nth (1+ cnt) liste) :span span) (nth (1+ cnt) liste)))))) collect liste))) (setf seq (if (equal all-gen t) seq (car (last seq)))) (if (equal output 'pitch) (integer-to-pitch seq) seq)))) (defun remove-duplicates-keep-edges (lst) "Entfernt innere Duplikate aus LST, behält aber den ersten und letzten Wert unabhängig von Wiederholungen." (let* ((first (first lst)) (last (car (last lst))) (len (length lst)) (result '()) (seen '()) (index 0)) (dolist (el lst (reverse result)) (cond ;; Ersten Wert immer behalten ((= index 0) (push el result) (push el seen)) ;; Letzten Wert immer behalten ((= index (1- len)) (push el result)) ;; Innere Duplikate von first oder last überspringen ((or (and (eq el first) (/= index 0)) (and (eq el last) (/= index (1- len)))) ;; überspringen nil) ;; Andere Duplikate vermeiden ((not (member el seen)) (push el result) (push el seen))) (setf index (1+ index))))) ;(remove-duplicates-keep-edges '(a b c a d e b c)) (defun reset-pitch-sequence (pitch-sequence pitch &key (type 'low)) (let ((pitch1 (cond ((equal type 'low) (car (get-ambitus pitch-sequence :type :pitch))) ((equal type 'high) (cadr (get-ambitus pitch-sequence :type :pitch))) ((equal type 'center) (center-position-in-list (sort-asc pitch-sequence) :get-value t))))) (if (not (omn-formp pitch-sequence)) (pitch-transpose (car (pitch-to-interval (list (if (chordp pitch1) (car (pitch-melodize pitch1)) (append pitch1)) pitch))) pitch-sequence) (omn-component-replace pitch-sequence (pitch-transpose (car (pitch-to-interval (list (if (chordp pitch1) (car (pitch-melodize pitch1)) (append pitch1)) pitch))) (omn :pitch pitch-sequence)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; only the main function, to see how it works ;;; 6 generations, start with 3 end with 2, span = max inteval/seps ;;; (list-plot (flatten (gen-brownian-bridge 6 '(3 2) :span 4 :all-gen t)) :join-points nil :style :fill) (gen-brownian-bridge 4 '(3 2) :span 3 :all-gen t) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; example with 6 generations ;;; every generation in an new bar to show how ith works (omn-list-plot (progn (setf seq (reset-integer-sequence (gen-brownian-bridge 6 '(3 2) :span 4 :all-gen t))) (setf pitchfield (make-scale 'c4 (find-max (flatten seq)) :alt '(1 1 2 4 7 4 2))) (setf pitch (position-filter seq pitchfield)) (setf rhy 1/16) (setf lengths (loop for i in pitch collect (length-rational-quantize (gen-length (gen-repeat (length i) 1) rhy) :round '10/4))) (make-omn :pitch pitch :length lengths)) :join-points nil :style :fill) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ALL DUPLCIATIONS INSIDE one PHRASE are removed!!! ;;; example with 6 generations ;;; every generation in an new bar to show how ith works ;;; (omn-list-plot (progn (setf seq (reset-integer-sequence (loop for i in (gen-brownian-bridge 6 '(3 2) :span 4 :all-gen t) collect (remove-duplicates-keep-edges i)))) (setf pitchfield (make-scale 'c4 (find-max (flatten seq)) :alt '(1 1 2 4 7 4 2))) (setf pitch (position-filter seq pitchfield)) (setf rhy 1/16) (setf lengths (loop for i in pitch collect (length-rational-quantize (gen-length (gen-repeat (length i) 1) rhy) :round '6/4))) (make-omn :pitch pitch :length lengths)) :join-points nil :style :fill) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -
Well, I don’t need this specifically, but here’s a quick sketched example: you have a pattern, and if you set it a bit cleverly (the initial and end values), then it mutates into pulses and then into another pattern. Very simple.
(length-list-plot (make-omn :length (length-staccato (gen-length (flatten (list (gen-repeat 3 '(11 2 17 9 13)) (gen-acc/rit '(11 2 17 9 13) 2) (reverse (gen-acc/rit '(8 5 10 10 5) 2)) (gen-repeat 5 '(8 5 10 10 5) ))) '1/64)) :pitch '(c4)) :point-radius 0 :join-points nil :style :fill)
or...
(length-list-plot (make-omn :length (gen-length (flatten (list (gen-repeat 3 '(11 7 5 3)) (gen-acc/rit '(11 7 5 3) 2) (reverse (gen-acc/rit '(5 7 11 17 23) 2)) (gen-repeat 5 '(5 7 11 17 23) ))) '1/64) :pitch '(c4)) :point-radius 0 :join-points nil :style :fill)
as a starting TOCCATA 😂 .. and if you like... map it on/to your favorite scale
(pitch-list-plot (make-omn :pitch (integer-to-pitch (reverse (flatten (gen-acc/rit '(1 2 3 1 5 7 11 3 13 3 17 23 7 11 7 5) 9)))) :length '(t) :span :pitch) :join-points t :style :fill)
-
A small further development – separate sequences for note values and rests (positive and negative integers).
;; subfunction to test the end of the loop (defun pos-neg (lst +val -val) (let ((pos 0) (neg 0)) (dolist (x lst (list (* +val pos) (* -val neg))) (cond ((> x 0) (incf pos)) ((< x 0) (incf neg)))))) ;; main function (defun gen-acc/rit* (alist length rest) (loop while (not (equal (sum (abs! alist)) (sum (abs! (pos-neg alist length rest))))) collect (setf alist (loop for i in alist when (or (= i length) (= i rest)) collect i else collect (if (> i 0) (if (> i length) (- i 1) (+ i 1)) (if (< i rest) (+ i 1) (- i 1))))))) ;; example (length-list-plot (gen-length (gen-acc/rit* '(3 -11 2 -13 23 5 -5 17 -2) 7 -3) ;; list with pos and neg integers + endval pos + endval neg '1/12) :join-points t :point-radius 0 :style :fill)
Pointillism from a vector
in Support & Troubleshooting
very nice!!