diff --git a/2022-08-19-patterns-guide.lisp b/2022-08-19-patterns-guide.lisp index 5ccea21..5bddff5 100644 --- a/2022-08-19-patterns-guide.lisp +++ b/2022-08-19-patterns-guide.lisp @@ -114,3 +114,195 @@ (play :foo) (end :foo) + +;; ok, I'm starting to try something of my own +(pb :my-foo + :note (pseq '(1 (1 2) (1 3) (1 4) 2 4)) + :play-quant 3 + :dur 1 + ) + +(play :my-foo) +(stop :my-foo) + +;; what's this :note? are they steps of an ocave? +(pb :my-notes + :note (pseq '(0 1 2 3 4 5 6 7 8 9)) + :play-quant 3 + :dur 1 + ) + +(play :my-notes) +(stop :my-notes) + +;; maybe! let's do octave + +(pb :my-octave + :note (pseq '(0 1 2 3 4 5 6 7 (0 7))) + :dur (pseq (concatenate 'list (make-list 7 :initial-element 0.5) '(4 8))) + :play-quant 4 + :dur 1 + ) + + +(play :my-octave) +(stop :my-octave) + +;; why :dur doesn't influence things? + +(pb :my-lengths + :note (pseq '(0 1)) + :dur (pseq '(1 1 2 2 4 4 8 8 16 16)) + :play-quant 4 + ) +(play :my-lengths) +(stop :my-lengths) + +;; well that's because there was another :dur with single value, cool + +;; maybe! let's do octave fixed + +(pb :my-octave2 + :note (pseq '(0 1 2 3 4 5 6 7 (0 7)) 1) + :dur (pseq (concatenate 'list (make-list 7 :initial-element 1) '(2 4))) + :play-quant 4 + ) + + +(play :my-octave2) +(end :my-octave2) + +;; by adding 1 as pseq REPEATS thing, I can stop the pattern by END, which ends after the pattern completion +;; and pattern completes after single repetition, +;; but without END pattern repeats, that's cool + +;;; now, what about other ways to set up pitch? apart from note there were other? + + +(pb :what-note + :note (pseq '(0 1 2 3 4 5 6 7 (0 7)) 1) + :octave 3 + :dur (pseq (concatenate 'list (make-list 7 :initial-element 1) '(2 4))) + :play-quant 4 + ) +;; looks like octave 5 is default, and quite high. +;; 1 - 2 are barely audible +;; 3 is bass + + +(play :what-note) +(end :what-note) + + +(pb :what-degree + :octave 3 + :note (pseq '(0 1 2 3 4 5 6 7 (0 7)) 1) + :dur (pseq (concatenate 'list (make-list 7 :initial-element 1) '(2 4))) + :play-quant 4 + ) + + +(play :what-degree) +(end :what-degree) + +;; so, is that same thing? + +;;; now. let's look at :root + +(pb :what-root + :note (pseq '(0 7 (0 7)) 1) + :octave 4 + :root 2 + :dur (pseq '(1 1 3)) + :play-quant 4 + ) + +(play :what-root) +(end :what-root) +;; yup, root changes root of the key + +;;; now let's try to write some chords? +(setq *M1* '(0 2 4)) +(setq *Min1* '(0 1.5 4)) +(setq *M3* '(2 4 6)) + +(setq *chord* *Min1*) + +(pb :what-chord + :note (pseq `(,*m1* ,*min1*)) + :octave 4 + :root 2 + :dur (pseq '(2 2) 1) + ;; :play-quant 4 + ) + +(play :what-chord) +(end :what-chord) + +;; those are major and minor chord, but very ugly cheap sound. +;; is there are way to make it clear? +;; is that about "instrument"? + +;; https://github.com/defaultxr/cl-patterns/blob/master/doc/supercollider-example.lisp +(in-package #:cl-collider) +(defsynth default ((gate 1) (freq 440) (out 0)) + (let* ((env (env-gen.kr (asr 0.01 1 0.1) :gate gate :act :free)) + (sig (sin-osc.ar freq 0 0.2))) + (out.ar out (pan2.ar sig 0 env)))) +(defsynth kik ((freq 440) (out 0)) + (let* ((env (env-gen.kr (env (list 0 1 0) (list 0.001 1)) :act :free)) + (fenv (env-gen.kr (env (list 1 0) (list 0.25)) :level-scale freq)) + (sig (sin-osc.ar fenv 0 0.2))) + (out.ar out (pan2.ar sig 0 env)))) +(defsynth sine-wave ((note 60) (freq 400)) + (let* ((freq (midicps note)) + (sig (sin-osc.ar freq 0 .2))) + (out.ar 0 sig))) + +(in-package #:cl-patterns) + +(pb :what-instrument + :note (pseq `(0 1)) + :instrument :default + :octave 5 + :root 2 + :dur (pseq '(2 2) 1) + ;; :play-quant 4 + ) + +(play :what-instrument) +(end :what-instrument) + + +;; changing instrument on the fly leaves something running +;; how do I disable it all? +(cl-patterns:stop t) + +;;; and some aux functions discovered: +(all-chords) +(all-scales) +(all-tunings) + +;;; can I just use chord as :note ? + +(pb :what-predef-chord + :note (pseq `((chord "Major Triad") (chord "Minor Triad"))) + :octave 4 + :root 2 + :dur (pseq '(2 2) 1) + ;; :play-quant 4 + ) + +(play :what-predef-chord) +(end :what-predef-chord) + +(in-package #:cl-collider) +(proxy :foo (sin-osc.ar 440 0 0.2)) + +;; so, attempt to call #'PLAY for those predef chords, leads to nothing playing +;; and previous things not starting. +;; more or less stable setup is +;; - restart emacs +;; - whole "setting-up-cl-collider" +;; - whole "supercollider-examples" +;; let's put that into single file maybe? as cargo cult diff --git a/attempt-at-setup.lisp b/attempt-at-setup.lisp new file mode 100644 index 0000000..207bf70 --- /dev/null +++ b/attempt-at-setup.lisp @@ -0,0 +1,79 @@ + +;; https://defaultxr.github.io/cl-collider-tutorial/02-getting-started.html + +(ql:quickload :cl-collider) +(in-package :sc-user) + +(setf *s* (make-external-server "localhost" :port 4444)) +(server-boot *s*) ; already in use + + +(ql:quickload :cl-patterns/supercollider) + +;; ...this will take care of loading cl-collider for you if it's not already loaded. + +;; once that is done, start the SuperCollider server if you haven't already: + +(cl-patterns:backend-start 'supercollider) + +;; (Note: if you get an error, make sure that sc:*sc-synth-program* is the same as the output of "which scsynth" from your command line. You may also need to set sc:*sc-plugin-paths* if you get errors about UGens not being installed.) + +;; then define a few synths... + +(in-package #:cl-collider) + +(defsynth kik ((freq 440) (out 0)) + (let* ((env (env-gen.kr (env (list 0 1 0) (list 0.001 1)) :act :free)) + (fenv (env-gen.kr (env (list 1 0) (list 0.25)) :level-scale freq)) + (sig (sin-osc.ar fenv 0 0.2))) + (out.ar out (pan2.ar sig 0 env)))) + +(defsynth default ((gate 1) (freq 440) (out 0)) + (let* ((env (env-gen.kr (asr 0.01 1 0.1) :gate gate :act :free)) + (sig (sin-osc.ar freq 0 0.2))) + (out.ar out (pan2.ar sig 0 env)))) + +;; then, enable cl-patterns's supercollider backend: + +(in-package #:cl-patterns) + +;; start the clock that patterns will be played on: + +;; the clock keeps tempo in beats per second; thus 110/60 = 110 beats per minute +(start-clock-loop :tempo 110/60) + +*clock* + +;; ...and then go ahead and write some patterns! + +(pb :foo ;; define a new pattern named :foo + :instrument :kik ;; use the :kik synth we defined above + :play-quant 4 ;; make sure the pattern will only start on a beat that is divisible by 4, to stay in sync + :dur 1 ;; give each event a duration of 1 beat + :pfin 4 ;; limit the length of the pattern to 4 events (the default is infinite events) + ) + +(pb :bar + :instrument :default + :play-quant 4 + :dur 1/2 + :scale :major ;; select the major scale + :degree (pwhite 0 7) ;; pick a random note from the first 7 notes in the selected scale + :pfindur 4 ;; limit the length of the pattern to 4 beats. pfindur causes the pattern to be limited based on its duration in beats, rather than the number of events. + ) + +;; start playing the defined patterns: + +;;; testing +;; (in-package #:cl-collider) +;; (proxy :foo (sin-osc.ar 440 0 0.2)) +;; (proxy :foo ()) + +;; (in-package #:cl-patterns) +;; (play :foo) + +;; (play :bar) + +;; (end :foo) + +;; (end :bar) diff --git a/programming-music-journal.org b/programming-music-journal.org index e64ab97..83c662d 100644 --- a/programming-music-journal.org +++ b/programming-music-journal.org @@ -45,3 +45,27 @@ wtf am I to do. ** maybe let's try to do stuff inside of org file? ** how do I clear things, it seems that cl-patterns seems to send things to server? ** should I try a different backend? +** so, when SC returned lots of errors on pb what helped - starting syn wave from "setting-up" file +;;; https://defaultxr.github.io/cl-collider-tutorial/03-make-a-sound.html +(setf *s* (make-external-server "localhost" :port 4444)) +(server-boot *s*) ; already in use + + +;;; https://defaultxr.github.io/cl-collider-tutorial/03-make-a-sound.html +(proxy :foo (sin-osc.ar 440 0 0.2)) ; no error, but hear no sound +;; opened QjackCtl, connected Graph SuperCollider to Air by Aftershokz left +(proxy :foo (sin-osc.ar 300 0 0.2)) +(proxy :foo (saw.ar 300 0.2)) + +** how do I make sounds better? +do I go to cl-collider package for explanation of synths and such? +** to stopp things that run amok: +(cl-patterns:stop t) +** ugh. why doesn't it produce sounds? +** ok, what did I learn today? +- some interaction with pseq + having scales, root / ocave +- intersecting with durations, also seq and not totally alighning +- some combined sounds, which don't sound nice +- maybe reliant startup procedure +- and attempting to run chords hangs it all