yay percussion rhythms, the beginning is here

This commit is contained in:
efim 2022-09-01 13:31:03 +00:00
parent e4a109e45e
commit babaf1156a
2 changed files with 335 additions and 0 deletions

View File

@ -0,0 +1,317 @@
;;; 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

View File

@ -207,3 +207,21 @@ I'm not sure if that's what you were using for that recording, but it may be mor
** ok, got new responses ** ok, got new responses
more about :act :free and nuances of creating with pulse-driver more about :act :free and nuances of creating with pulse-driver
** and I think I understand Env(elope) better now, yay? ** and I think I understand Env(elope) better now, yay?
* [2022-09-01 Thu]
** DONE so, I do have some percussion rhythm, let's try something more interesting?
** DONE and try to write with the adviced better function
** and maybe try to get other instruments
** new thing! if I keep pattern playing and reeval it's definition - new definition would start playing, cool
** message
Over the weekends I've learned quite a bit!
Previous questions were definitely more pointed to me figuring out how to do synthdefs that could be used as :instrument in patterns
Now I kind of understand part of EnvGen (Envelope) - it takes two lists, and emits values of first list by timeperiods from the second list
and that can be fed into any part of other generator - as frequency for SIN-OSC, or amptitue
past sunday with your help I've figured out how to make percussion instruments from SuperCollider example and done simplest regular beat
Today I tried to figure out more complicated beats, and how to join different lines with pauses
Still lots to do, but will share what I've accomplished in hopes that it returns you a little bit of excitement your project brings