cl-patterns-study/dirty-journal/2022-09-01-more-percussions...

365 lines
13 KiB
Common Lisp

;;; copy from previous day
(in-package #:cl-collider)
(defsynth bdrum ((amp 0.5) (out 0) )
(out.ar out (* amp (sin-osc.ar (line.ar 120 60 1) 0 (env-gen.ar (env (list 0 1 0) (list 0.005 0.5)) :act :free)))))
;; (synth :bdrum :amp 1)
(in-package #:cl-collider)
(defsynth snare ((amp 0.5) (out 0))
(out.ar out (* amp (white-noise.ar (env-gen.ar (env (list 0 1 0.3 0) (list 0.005 0.01 0.5)) :act :free)))))
;; (synth :snare)
(in-package #:cl-collider)
(defsynth hihat ((amp 0.5) (out 0))
(out.ar out (* amp (hpf.ar (white-noise.ar 1) 10000) (env-gen.ar (env (list 0 1 0) (list 0.005 0.5)) :act :free))))
;; hihat = HPF.ar(WhiteNoise.ar(1), 10000) * Decay2.ar(tempo, 0.005, 0.5);
;; (synth :hihat)
;;; whoa, now I can try to combine these in a pattern!
;; let's just copy another pattern with my instruments maybe?
(in-package #:cl-patterns)
(pb :foo ;; define a new pattern named :foo
:instrument :bdrum ;; 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 2 ;; give each event a duration of 1 beat
:pfin 2 ;; limit the length of the pattern to 4 events (the default is infinite events)
)
;; (play :foo)
;; (end :foo)
(pb :fee ;; define a new pattern named :foo
:instrument :hihat ;; 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 1 ;; limit the length of the pattern to 4 events (the default is infinite events)
)
;; (play :fee)
;; (end :fee)
(pb :fum ;; define a new pattern named :foo
:instrument :snare ;; 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 0.5 ;; give each event a duration of 1 beat
:pfin 8 ;; limit the length of the pattern to 4 events (the default is infinite events)
:amp 0.1
)
;; (play :fum)
;; (end :fum)
(pdef :all-parallel (ppar (list (pdef :foo) (pdef :fee) (pdef :fum))))
;; (play :all-parallel)
;; (end :all-parallel)
;;; new day.
;; let's think more about it.
;; my guess is that things don't align properly
;; another new thing, I guess here drum is every 2nd beat, hihat every beat and snare double beats
;; let's try another beat by drum?
;; tuum, tu-tu-tum, tum-tum-tum
(in-package #:cl-patterns)
;; 2 tacts of 4 beats each
(pb :more-drum ;; define a new pattern named :more-drum
:instrument :bdrum ;; 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 (pseq '(2.5 0.5 1 1 1 1 1) 1)
)
;; (play :more-drum)
;; (end :more-drum)
;; (stop :more-drum)
;;
;; what I need is seq as duration?
;;
;; ok. what kind of plates I need?
;; maybe quick 6 pause 2, repeat
(pb :hihat-aligned-with-long-notes-to-4
:instrument :hihat
:play-quant 4 ; that helps to start this rhythm not on current beat, but on some beat in future
; to sync with others, ok.
; but only works for startup? not for aligning after end of 1 cycle?
:dur (pseq '(1 0.5 0.5 2) 1)
:amp (pseq '(1 0.5 0.5 0.5) 1)
;; how to make pause for 2?
)
;; (play :hihat-aligned-with-long-notes-to-4)
;; (end :hihat-aligned-with-long-notes-to-4)
;; so, I'd like a pause in the beginning?
;; like 2 beat pause in the beginning, start with 3rd beat?
;; would aligning work for that?
;;
;; i don't think so.
;;
;; then let's try to read more articles on patterns (in SC)?
;; maybe there will something about pauses
;;
;; or, let's finish this with long hihat in beginning
;; maybe 1 drum per beat will help me understand :play-quant better?
;; i tried setting it to 16 for hihat and it still repeated itself without stop
;; while I expected it to play once every two 4 tacts
(pb :metered-beat
:instrument :bdrum
:dur 1
:play-quant 4 ; skip first two beats?
:amp (pseq '(1 0.5 0.5 0.5) 1))
;; (play :metered-beat)
;; (stop :metered-beat)
;; I could try adding accents?
(pb :single-hihat
:instrument :hihat
:dur (pseq '(1) 1)
:play-quant 4)
;; (play :single-hihat)
;; (end :single-hihat)
;; (stop :single-hihat)
;; so, it still repeats? hmmmmmm
;; ok, I have no idea how to alighn things with pauses
;;
;; let's go on and read http://doc.sccode.org/Tutorials/Streams-Patterns-Events3.html
;; so Pseq would have offset? would that be used for pauses in between?
;; and "pauses during pattern" could be simulated with "longer beats", even though how do I separate that from long-notes?
;; well, from
;; pb :hihat-aligned-with-long-notes-to-4
;; pb :single-hihat
;; it seems that :play-quant helps to start-up new pattern on particular beat, for example 4th
;; (starting from 0 that's start of a new tact in 4/4 meter)
;; but doesn't help if pattern is less than 4 beats to align each repetition with start of new tact
;; (midinote-freq) ; this is for writing melodies
;;; so, some synths from article http://doc.sccode.org/Tutorials/Streams-Patterns-Events3.html
;; (
;; SynthDef( \help_SPE3_Mridangam, { |out, t_amp|
;; var sound;
;; sound = Resonz.ar(
;; WhiteNoise.ar(70) * Decay2.kr( t_amp, 0.002, 0.1 ),
;; 60.midicps,
;; 0.02,
;; 4
;; ).distort * 0.4;
;; Out.ar(out, sound);
;; DetectSilence.ar(sound, doneAction: Done.freeSelf);
;; }).add;
;; (in-package #:cl-collider)
;; (defsynth help_spe3_mridangam ((amp 0.5) (out 0))
;; (let* ((sound '())))
;; (out.ar out (* amp (sin-osc.ar (line.ar 120 60 1) 0 (env-gen.ar (env (list 0 1 0) (list 0.005 0.5)) :act :free)))))
;; ;; (synth ::bdrum)
;; ;; (stop)
;;
;; well, it seems that these generators are not present in the cl library, that's ok
;;
;; should I try doing pauses by setting amptitude to 0?
(pb :single-hihat
:instrument :hihat
:dur (pseq '(1) )
:amp (pseq '(0.5 0 0 0) 1)
:play-quant 4)
;; (play :single-hihat)
;; (end :single-hihat)
;; (stop :single-hihat)
;;; cool, i like that.
;; so initial thing - metered beat and attempt at hiheads with pauses
(pdef :metered-and-first-hihead
(ppar (list (pdef :metered-beat) (pdef :hihat-aligned-with-long-notes-to-4))))
;; (play :metered-and-first-hihead)
;; (end :metered-and-first-hihead)
;;; trying quick 3-hihead, aligned with pauses
(pb :hihead-3-quick-with-pauses-to-tact
:instrument :hihat
:play-quant 4 ; that helps to start this rhythm not on current beat, but on some beat in future
; to sync with others, ok.
; but only works for startup? not for aligning after end of 1 cycle?
:dur (pseq '(1 0.5 0.5 0.5 1.5) 1)
:amp (pseq '(0 0.5 0.5 0.5 0) 1)
;; how to make pause for 2?
)
;; (play :hihead-3-quick-with-pauses-to-tact)
;; (end :hihead-3-quick-with-pauses-to-tact)
(pdef :metered-and-three-quick
(ppar (list (pdef :metered-beat) (pdef :hihead-3-quick-with-pauses-to-tact))))
;; (play :metered-and-three-quick)
;; (end :metered-and-three-quick)
(pb :pause-tact
:instrument :hihat ; without instrument - :amp doesn't do anything
:dur (pseq '(4) 1) ; just having 4 - repeats endlessly
:amp 0)
;; (play :pause-tact)
;; (end :pause-tact)
;; (stop :pause-tact)
;;; now let's add a pause tact
(pdef :hihead-3-quick-and-pause
(pseq (list
(pdef :hihead-3-quick-with-pauses-to-tact)
(pdef :pause-tact)) 1))
;; (play :hihead-3-quick-and-pause)
;; (end :hihead-3-quick-and-pause)
;; (stop :hihead-3-quick-and-pause)
;;; well, that works somewhat.
;; let's add this to my "more complicated drum line"
(pdef :more-complicated-drum-and-three-quick-hiheads
(ppar (list (pdef :more-drum) (pdef :hihead-3-quick-and-pause))))
;; (play :more-complicated-drum-and-three-quick-hiheads)
;; (end :more-complicated-drum-and-three-quick-hiheads)
;;
;;; yay, I guess!
;;; let's play all three in order?
(pdef :all-from-today-in-order
(pseq (list
(pseq (list (pdef :metered-and-first-hihead)) 4)
(pseq (list (pdef :all-parallel)) 3)
(pseq (list (pdef :more-complicated-drum-and-three-quick-hiheads)) 4)
(pseq (list (pdef :all-parallel)) 3)) 1))
;; (play :all-from-today-in-order)
;; (end :all-from-today-in-order)
;; (stop :all-from-today-in-order)
;;; now let's try again to write this down with a more advised function
;; (in-package #:cl-collider)
;; (in-package #:cl-patterns)
;; (render (pdef :metered-and-three-quick) "/tmp/attempt-1.wav" :dur 4)
;; let's copy the error
;; There is no applicable method for the generic function
;; #<STANDARD-GENERIC-FUNCTION CL-PATTERNS::BACKEND-INSTRUMENT-CONTROLS (1)>
;; when called with arguments
;; (:BDRUM (EVENT :INSTRUMENT :BDRUM :DUR 2.5 :DELTA 0)).
;; [Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]
;;
;; with other pattern:
;; There is no applicable method for the generic function
;; #<STANDARD-GENERIC-FUNCTION CL-PATTERNS::BACKEND-INSTRUMENT-CONTROLS (1)>
;; when called with arguments
;; (:BDRUM
;; (EVENT :INSTRUMENT :BDRUM :DUR 1 :PLAY-QUANT (4) :AMP 1 :DELTA 0)).
;; [Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]
;;; so let's write them with previous writing method?
;; and save a link to it?
;;; oh, but there's "non-real time rendering" in cl-collider
;; let's try that? I don't see how to connect it with the patterns
;;
;; so https://github.com/byulparan/cl-collider#record-audio-output it is
;;; write a single channel to disk
;; we can write to buffer number out_buf_num by reading in from the 0 bus
(in-package #:cl-collider)
(defsynth disk_writer ((out_buf_num 99))
(disk-out.ar out_buf_num (in.ar 0)))
(setf mybuffer (buffer-alloc (expt 2 17)))
mybuffer
;; start a disk_writer synth
(setf writer_0 (synth 'disk_writer))
;; make it output to buffer you allocated
(ctrl writer_0 :out_buf_num (bufnum mybuffer))
;; continuously write the buffer contents to a file
(buffer-write mybuffer "/tmp/all-from-today-in-order.aiff" :leave-open-p t)
(in-package #:cl-patterns)
;; now play whatever sounds you like
(play :all-parallel)
(end :all-parallel)
(play :metered-and-first-hihead)
(end :metered-and-first-hihead)
(play :more-complicated-drum-and-three-quick-hiheads)
(end :more-complicated-drum-and-three-quick-hiheads)
(play :all-from-today-in-order)
(end :all-from-today-in-order)
;; e.g.
(proxy :blah (sin-osc.ar 440))
(free :blah)
;; then when you are done
(in-package #:cl-collider)
;; stop the disk_writer synth
(free writer_0)
;; close and free the buffer
(buffer-close mybuffer)
(buffer-free mybuffer)
;; then you can play what you recorded with a utility like mpv:
;; mpv /tmp/foo.aiff
(in-package #:cl-collider)
;; https://github.com/SCLOrkHub/SCLOrkSynths
;; https://github.com/SCLOrkHub/SCLOrkSynths/blob/master/SynthDefs/bass/acidOto3091.scd
(defsynth bdrum ((amp 0.5) (out 0) )
(out.ar out (* amp (sin-osc.ar (line.ar 120 60 1) 0 (env-gen.ar (env (list 0 1 0) (list 0.005 0.5)) :act :free)))))
;; out = 0, gate = 1, freq = 440, amp = 0.1, pan = 0, att = 0.001, dec = 0.5, sus = 0.1, rel = 0.5, curve = -4,
;; // Other Controls
;; // width is 0 - 1
;; // filterRange is in octaves
;; lagTime = 0.12, filterRange = 6, width = 0.51, rq = 0.3;
(defsynth acid0to3091 ((amp 0.5) (out 0) (gate 1) (freq 440) (pan 0) (att 0.001) (dec 0.5) (sus 0.1) (rel 0.5) (curve -4) (lagTime 0.12) (filterRange 6) (width 0.51) (rq 0.3))
(let* ((freq (lag.kr freq lagTime))
(ampEnv (env-gen.kr (adsr att dec sus rel amp 0) :gate gate))
;; (filterEnv (env-gen.kr (adsr att (* 2 dec) (/ sus 2) (* 2 rel) (expt 2 filterRange) (list (* -1 curve) curve curve curve ) 1) gate :act :free))
;; this is likely not correct way to set up cure of the form curve: [-1 * curve, curve, curve, curve],
;; does that mean multichannel things?
;; let's just set as single curve and check how it looks?
(filterEnv (env-gen.kr (adsr att (* 2 dec) (/ sus 2) (* 2 rel) (expt 2 filterRange) (* -1 curve) 1) :gate gate :act :free))
;; is LFPulse.ar(...).range(-1, 1) gets from _range ?
(sndStep1 (_range nil (lf-pulse.ar freq 0.0 width) -1 1))
(sndStep2 (rlpf.ar sndStep1 (* freq filterEnv) rq))
(sndStep3 (* sndStep2 ampEnv)))
(out.ar out (pan2.ar sndStep3 pan))))
(synth :acid0to3091)
(stop)
;; that a nice acid base, just not freeing the thing, so can't be used as is, sad.
;; let's try something else?
;;; (and that one seems interesting for later : https://github.com/SCLOrkHub/SCLOrkSynths/blob/master/SynthDefs/bass/fmBass.scd )
;;
;;; https://github.com/SCLOrkHub/SCLOrkSynths/blob/master/SynthDefs/bass/bassWarsaw.scd
(defsynth fmBass ((out 0) (freq 440) (gate 1) (amp 0.5) (pan 0) (att 0.01) (dec 0.3) (sus 0.4) (rel 0.1) (slideTime 0.17) (cutoff 1100) (width 0.15) (detune 1.005) (preamp 4))
(let* ((env (env-gen.kr (adsr att dec sus rel) :gate gate :act :free))
(freq (lag.kr freq slideTime))
(sndStep1 (var-saw.ar freq 0 width preamp))
(sndStep2 (distort sndStep1))
(sndStep3 (* sndStep2 env))
(sndStep4 (lpf.ar sndStep3 cutoff amp)))
(out.ar out (pan2.ar sndStep4 pan))))
(synth :fmBass :freq 80)
(stop)
;; overall this is not quite success, not quite a failure
;; I've practiced searching for tihngs I don't konw between the libraries