;;; ;;; 01/27/2004 ;;; Common Music Patterns ;;; ;;; 2/13/2004 version references sound files stored in ;;;/usr/ccrma/web/html/courses/220b/sounds ;;; 01/26/2006: changed to use cm's process instead of with-sound ;;; we will use the mixsound instrument, you can find it in: ;;; /usr/ccrma/web/html/courses/220b/topics/patterns/examples/mixsound.ins ;;; copy it to your work area, compile and load it before proceeding with ;;; the examples below. ;; create a pattern of type "cycle", use note duration names (q -> quarter note) (defparameter r (new cycle :of '(q q e s s e))) ;;; use the pattern ;;; (next r) --> returns the next element of the pattern ;;; (rhythm (next r)) --> translates the name to a time value in seconds ;;; in the current tempo ;;; for more details on rhythm see: ;;; http://ccrma.stanford.edu/software/cm/doc/dict/rhythm-fn.html (with-sound(:srate 44100) (loop repeat 25 for time = 0 then (+ time (rhythm (next r))) do (format t "~s " time) ;; the "mixsound" clm instrument mixes in a soundfile at a point in time (mixsound "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" time))) ;;; using process (defun pattern1 () (process repeat 25 do (format t "~s " (now)) ;; the "mixsound" clm instrument mixes in a soundfile at a point in time (output (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg (now))) wait (rhythm (next r)))) (events (pattern1) "pat1.snd" :srate 44100) ;;; the second argument to rhythm is an optional tempo factor ;;; (the default is 60 bpm, 60 beats per minute) ;;; here we set up a counter that increments tempo by 5bpm on each iteration of the loop (with-sound(:srate 44100) (loop repeat 50 for tempo from 60 by 5 for time = 0 then (+ time (rhythm (next r) tempo)) do (format t "~s " time) (mixsound "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" time))) (defun pattern2 () (process repeat 25 for tempo from 60 by 5 do (format t "~s " (now)) (output (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg (now))) wait (rhythm (next r) tempo))) (events (pattern2) "pat1.snd" :srate 44100) ;;; here we define a tempo envelope (the local variable tempo) ;;; and interpolate over it with time, so that we get a smootly ;;; changing tempo (that can change in arbitrary ways) ;;; see this for more details on the CM interpl function: ;;; http://ccrma.stanford.edu/courses/220b/cm/doc/dict/interpl-fn.html (with-sound(:srate 44100) (loop repeat 50 ;; the tempo "envelope", x values are in seconds, y values are in bpm with tempo = '(0 60 3 60 6 120 10 120) ;; on each iteration we add to time for time = 0 then (+ time ;; the rhythmic value of the next element (rhythm (next r) ;; interpreted with respect to the current ;; tempo as interpolated in the envelope (interpl time tempo))) do (format t "~s " time) (mixsound "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" time))) (defun pattern3 () (process repeat 25 ;; the tempo "envelope", x values are in seconds, y values are in bpm with tempo = '(0 60 3 60 6 120 10 120) do (format t "~s " (now)) (output (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg (now))) ;; we wait for the right amount of time wait ;; and that is the rhythmic value of the element (rhythm (next r) ;; interpreted with respect to the current ;; tempo as interpolated in the envelope (interpl (now) tempo)))) (events (pattern3) "pat1.snd" :srate 44100) ;;; more complex rhythmic patterns (with an embedded subpattern) ;;; note the use of backquote "`" and comma "," to add a pattern ;;; element to the list of elements (defparameter r (new cycle :of `(q q e s s ,(new random :of '(e s. s.. e e) :for 2)) :for 8)) (defparameter r (new heap :of `(q q e s s ,(new random :of '(e s. s.. e e) :for 2)) :for 8)) ;;; so let's use the new pattern (the last one is a "heap", random selection ;;; with replacement). We use a fixed tempo of 120 bpm. (defun pattern1 () (process repeat 25 do (format t "~s " (now)) ;; the "mixsound" clm instrument mixes in a soundfile at a point in time (output (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg (now))) wait (rhythm (next r) 120))) (events (pattern1) "pat1.snd" :srate 44100) ;;; having to use include the filename all the time is a pain, we can encapsulate it ;;; inside a function and define a explicit "pirexlid" instrument, which is ;;; easier to read (defun pirexlid (time) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg time)) ;;; so the same call as before looks cleaner (defun pattern1 () (process repeat 25 do (format t "~s " (now)) ;; the "mixsound" clm instrument mixes in a soundfile at a point in time (output (pirexlid (now))) wait (rhythm (next r) 120))) (events (pattern1) "pat1.snd" :srate 44100) ;;; we define another "instrument" (defun potlid (time) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/small-lid-1.snd" :beg time)) ;;; and redefine our rhythm pattern (defparameter r (new heap :of `(q q e s s ,(new random :of '(e s. s. e e) :for 2)) :for 8)) ;;; and we get two performers to use the same rhythmic pattern, but ;;; not at the same time. (defun pirexpattern () (process repeat 25 do (format t "~s " (now)) (output (pirexlid (now))) wait (rhythm (next r) 120))) (defun potpattern () (process repeat 25 do (format t "~s " (now)) (output (potlid (now))) wait (rhythm (next r) 120))) (events (list (pirexpattern) (potpattern)) "pat1.snd" :srate 44100) ;;; each "period" of the pattern is nine notes long, we now create ;;; a performance that aligns with that period (ie: is 10 periods long) (defun pirexpattern () (process repeat (* 10 9) do (format t "~s " (now)) (output (pirexlid (now))) wait (rhythm (next r) 120))) (defun potpattern () (process repeat (* 10 9) do (format t "~s " (now)) (output (potlid (now))) wait (rhythm (next r) 120))) (events (list (pirexpattern) (potpattern)) "pat1.snd" :srate 44100) ;;; one of the performers is now playing at a different tempo (80 bpm instead of ;;; 120 bpm), so both are out of sinc and one of them finishes first... (defun pirexpattern () (process repeat 25 do (format t "~s " (now)) (output (pirexlid (now))) wait (rhythm (next r) 80))) (defun potpattern () (process repeat 25 do (format t "~s " (now)) (output (potlid (now))) wait (rhythm (next r) 120))) (events (list (pirexpattern) (potpattern)) "pat1.snd" :srate 44100) ;;; of course we can limit our loop by time instead of by number of notes, ;;; let's use the "while" feature of the loop macro. This will mercifully ;;; only last for 10 seconds. One of the performers is using the same ;;; rhythmic pattern but is playing it at half speed... (60 bpm instead ;;; of 120 bpm) (defun pirexpattern () (process while (< (now) 10) do (format t "~s " (now)) (output (pirexlid (now))) wait (rhythm (next r) 60))) (defun potpattern () (process while (< (now) 10) do (format t "~s " (now)) (output (potlid (now))) wait (rhythm (next r) 120))) (events (list (pirexpattern) (potpattern)) "pat1.snd" :srate 44100) ;;; ok, let's redefine the instruments adding one more parameter. Our percussionists ;;; can do better than before and produce different amplitudes... (defun potlid (time amp) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/small-lid-1.snd" :beg time :amp amp)) (defun pirexlid (time amp) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg time :amp amp)) (defparameter r (new heap :of `(q q h h e s s t s ,(new random :of '(s s s) :for 2)) :for 8)) ;;; create a pattern for amplitudes (defparameter a (new heap :of `(ppp ppp ppp f mp p fff))) ;;; we use the "amplitude" function to translate between amplitude names ;;; and numbers (that mix can understand). (defun pirexpattern () (process while (< (now) 10) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (pirexlid (now) amp)) wait (rhythm (next r) 120))) (defun potpattern () (process while (< (now) 10) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (potlid (now) amp)) wait (rhythm (next r) 120))) (events (list (pirexpattern) (potpattern)) "pat1.snd" :srate 44100) ;;; if you look at the mixsound instrument you will see that it uses locsig ;;; and has parameters that let you control "degree" and "distance" ;;; so, one more instrument added to the mix and expose the "degree" and ;;; "distance" parameters in the function definition... ;;; by default potlid sends to the left channel (defun potlid (time amp &key (degree 0)(distance 1)) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/small-lid-1.snd" :beg time :amp amp :degree degree :distance distance)) ;;; but pirexlid sends (by default) to the right channel (defun pirexlid (time amp &key (degree 90)(distance 1)) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" :beg time :amp amp :degree degree :distance distance)) ;;; the trivet is in the middle (defun trivet (time amp &key (degree 45)(distance 1)) (new mixsound :file "/usr/ccrma/web/html/courses/220b/sounds/1.snd" :beg time :amp amp :degree degree :distance distance)) ;;; let's add a whole note there so that the texture is not so thick... (setf r (new heap :of `(q w h h e s s t s ,(new random :of '(s s s) :for 2)) :for 8)) ;;; and now we have three players banging on three different "percussion ;;; instruments", all of them using the same basic rhythm pattern, but not ;;; synchronized at all. ;;; we could also include everything in the events call instead of using functions... (events (list ;; pirex lid (process while (< (now) 10) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (pirexlid (now) amp)) wait (rhythm (next r) 120)) ;; pot lid (process while (< (now) 10) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (potlid (now) amp)) wait (rhythm (next r) 120)) ;; trivet (process while (< (now) 10) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (trivet (now) amp)) wait (rhythm (next r) 120))) "pat1.snd" :srate 44100 :channels 2) ;;; a pattern for position of sound between speakers (defparameter pospat (new line :of (list 0 10 20 30 40 50 60 70 80 90 (new heap :of '(0 45 30 70))))) (defparameter pospat (new palindrome :of (list 0 10 20 30 40 50 60 70 80 90))) (events (list (process while (< (now) 10) for amp = (amplitude (next a)) for pos = (next pospat) do (format t "~s " (now)) (output (pirexlid (now) amp :degree pos)) wait (rhythm (next r) 120))) "pat1.snd" :srate 44100 :channels 2) ;;; let's redefine the trivet instrument, instead of using the "mixsound" ;;; instrument we now use the "one-cut" instrument. This can add vibrato, ;;; sampling rate control and amplitude envelope control to a soundfile. ;;; (and a lot of other things as well). More interesting than just plain ;;; sample playback. ;;; the "one-cut" instrument is part of the "cut.ins" file at: ;;; http://ccrma.stanford.edu/courses/220b/topics/patterns/examples/cut.ins ;;; you need to download it to your working directory, and compile and load ;;; it before you can use the following definition. (defun trivet (time amp rate &key (degree 45)(distance 1)) (new one-cut :start-time time :amp amp :soundfile "/usr/ccrma/web/html/courses/220b/sounds/1.snd" ;; we do not add an amplitude envelope, just leave amp as it is :amp-func '(0 1 1 1) ;; we do pass a sampling rate multiplier :sample-rate-mult rate ;; and pass the rest of the parameters :degree degree :distance distance)) ;;; and add a pattern for controlling sampling rate conversion ;;; "1.0" is no rate conversion at all, ie: play at the original pitch (defparameter rt (new random :of '(1 1.1 0.9 1.2 0.1))) ;;; so now the trivet player has a "tunable" trivet, that is, a trivet that ;;; he can change in size between notes! Or better, a set of tuned trivets ;;; that have frequency ratios (to the original master trivet) of 1.1, 0.9, 1.2 ;;; and 0.1 - the last one is the "bass trivet" :-) (events (list ;; pirex lid (process while (< (now) 15) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (pirexlid (now) amp)) wait (rhythm (next r) 120)) ;; pot lid (process while (< (now) 15) for amp = (amplitude (next a)) do (format t "~s " (now)) (output (potlid (now) amp)) wait (rhythm (next r) 120)) ;; trivet (process while (< (now) 15) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " (now)) (output (trivet (now) amp rate)) wait (rhythm (next r) 120))) "pat1.snd" :srate 44100 :channels 2) ;;; obviously the potlid and pirexlid instruments could be changed to use one-cut as well..... ;;; 01/29/2004 ;;; ;;; Using with-mix ;;; (setf r (new heap :of `(q q h h e s s t s ,(new random :of '(s s s) :for 2)) :for 8)) (setf a (new heap :of `(ppp ppp ppp f mp p fff))) (setf rt (new random :of '(1 1.1 0.9 1.2 0.1))) (defun potlid (time amp &key (degree 0)(distance 1)) (mixsound "/usr/ccrma/web/html/courses/220b/sounds/small-lid-1.snd" time :amp amp :degree degree :distance distance)) (defun pirexlid (time amp &key (degree 90)(distance 1)) (mixsound "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" time :amp amp :degree degree :distance distance)) (defun trivet (time amp &key (degree 45)(distance 1)) (mixsound "/usr/ccrma/web/html/courses/220b/sounds/1.snd" time :amp amp :degree degree :distance distance)) ;;; render the whole "piece" (with-sound(:srate 44100 :channels 2 :statistics t) (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp)) (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (potlid time amp)) (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " time) (trivet time amp)) ) ;;; Duration: 88.7651, Last begin time: 17.6875 ;;; Compute time: 42.870, Compute ratio: 0.48 ;;; OutA max amp: 0.642 (near 15.563 secs) ;;; OutB max amp: 0.423 (near 11.251 secs) ;;; now we use with-mix to isolate all three percussionists ;;; we can change the score for one of them and the others ;;; are just mixed in... ;;; http://ccrma.stanford.edu/software/snd/snd/clm.html#with-mix (with-sound(:srate 44100 :channels 2 :statistics t) (with-mix() "perc1" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp))) (with-mix() "perc2" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (potlid time amp))) (with-mix() "perc3" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " time) (trivet time amp))) ) (with-sound(:srate 44100 :channels 2 :statistics t) (with-mix() "perc1" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp))) (with-mix() "perc2" 0 (loop repeat 52 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (potlid time amp))) (with-mix() "perc3" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " time) (trivet time amp))) ) (with-sound(:srate 44100 :channels 2 :statistics t) (with-mix() "perc1" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp))) (mixsound "perc1.snd" 5)) ;;; first time through... ;; Duration: 89.2651, Last begin time: 18.1875 ;; Compute time: 57.130, Compute ratio: 0.64 ;; OutA max amp: 0.676 (near 10.813 secs) ;; OutB max amp: 0.477 (near 3.939 secs) ;;; second time... nothing changed in the "score" so the files ;;; are not recalculated, they are just mixed in again ;; Duration: 89.2651, Last begin time: 0.0000 ;; Compute time: 0.670, Compute ratio: 0.01 ;; OutA max amp: 0.676 (near 10.813 secs) ;; OutB max amp: 0.477 (near 3.939 secs) ;;; Random states, a way to "repeat randomness" ;;; ;;; "make-random-state" creates a new state for the random number generator ;;; we can use this "state" to initialize our random number generator and ;;; get back from it the same sequence of pseudo-random numbers ;;; (make-random-state) will copy the current state ;;; (make-random-state t) will create a new random state (setf our-state #S(RANDOM-STATE :STATE #(0 2567483615 624 2399190014 1137182317 2253280414 141745551 818671727 3408544464 2637449285 3997139722 1567458197 2158697837 4165731285 115673465 2562555337 3215016996 3441572108 577931770 551369138 117835083 3343006121 1503836709 3117200456 4504391 4131906073 3373407833 3537511322 1917578358 1690368525 3964080855 887742912 911593693 1319939151 276281573 997293945 3108899806 52914670 2747214089 2863600763 2757154018 2689457286 2706809915 2392869797 2471180300 3457063856 3808114890 1476393081 524107653 4073405607 1713287395 3841112922 3849685838 3121031827 2425513064 3630454790 2530502446 2402762898 2521401607 2155461681 2133035864 2315754327 2725496260 4243455322 2682819930 3289842678 635809000 2004705224 2805488526 3004041854 3247079215 2212935840 3879963183 3117092770 3856255591 4109917628 3026269092 2693215944 1764800509 3935466168 4064958228 1972415329 4251581743 797011628 2566829613 2068187101 601478687 2808156559 4069220854 1377616639 1185209485 820375444 1425652157 2400183174 3668076399 2405407224 1744079359 3477430164 933725682 1566857946 1832127432 240531375 630824814 3488597194 2271687858 1471805910 2884935994 3394409344 1343901208 1557868871 3502434057 869237086 2930464899 1937634387 1051674313 1132953277 4000029853 2543278280 1925194277 923712680 2757646013 1222471889 376230535 3410644667 3212412689 1237349881 4057482067 3179831052 1124990723 3272322632 2616125206 544661348 3090065141 1719865077 3982588615 3716436952 3843180780 4224167377 2324362849 2271424663 2939480146 2321709082 3016112643 71724017 4280520610 2320225299 484361284 2831668068 1455553999 3825098968 523135482 2178718262 1912253209 3944569102 1654069176 1935498645 2046173181 85752582 658292729 1233321689 855122901 3185975463 2479238840 457701890 4131304811 2343189162 2921663723 786811281 679354330 1338260392 1777859412 1068082737 523619070 3469542624 884304186 964202126 4273749171 630071838 2015855749 3709725892 2918574644 1809206784 3377614872 253038171 8019356 195259202 3534595009 1567780418 1660705832 3959508455 544128943 571426759 2279723328 98689480 3228179623 2880246132 2614757967 4037297699 1161218915 2300817518 2540857185 2435565013 3490061722 3010432805 3702544940 3172973653 1940971038 1920940551 1617500971 3207017056 488330105 1875030157 740201485 1302748915 1544616013 1101439696 3013023306 2977977150 1255142275 1307157794 243458728 3615970594 3034202080 1031350022 2950208571 2644452443 3836475644 2735912059 1413805470 4060086173 522020921 3908018273 3725375887 2368020770 4131402375 2482541308 2494426399 1951273563 588605549 592414957 958585710 2586866004 589151709 845295137 2589121782 899399990 2438144321 4285397859 25857493 2120479487 661310765 1294665913 1454172561 3727046346 1675898696 2639509961 2567106836 3502761132 1829232906 114797911 2419848020 3963226096 4241174242 2892425417 414940188 1277621266 2491512710 3567635484 1216290884 2689575235 3989344432 2658525867 426630842 1671457392 3159849124 1922920590 3779260540 3650476589 1763947321 478588460 2810987633 2384301429 4104028170 2706134437 1216686844 3379977195 909732771 3568743275 2045735205 2264918098 1350138031 1984150470 4272395684 2999282437 257620454 2615848674 1665982341 495834170 3575498249 2785049882 1288385441 4096524106 2818099704 1729395406 1349925848 865844939 2434394694 896782852 2150760645 1335217845 681894455 2845683687 3113939854 3746300786 2330711500 3306723710 3678631050 2528726087 3536782708 1339742255 4031375715 1018000414 2556747541 3905967187 1702892753 3898312530 2260581688 1471525670 832605864 1195913614 1894389170 3990641639 2019116605 2104677110 3925109694 3376523229 3369011683 3407333038 1148123280 1522838405 1878872165 565329094 3745640817 290997582 3792443163 1758000590 4017996546 2332064189 9453748 544595038 2415935601 968620475 401316644 4093016722 2915890580 1080306574 2277357516 64537512 3201440427 3217553169 1923262180 1908369087 1169242205 2962782644 1631874103 3143735480 3444755661 3538357426 3754540098 3525120019 2743068607 111514625 3012488918 1291824918 3006555270 756174216 309223453 868643303 831557786 3617683514 3516526838 107097891 501962058 1266893230 2830668424 2432936944 4178926073 2691255074 815711521 1980330119 983243873 3557366985 2307290935 3595265647 1115895331 1219137266 1584362088 1393645047 781291929 3448263657 253187807 3855326857 787703809 213357301 2730826042 46787754 1509382821 2291435592 1368350919 365241780 266417563 2764511935 117945130 2198940460 2082711745 2896188764 3867344307 994134030 817032485 260267577 198160158 1064904312 2376754939 4062503649 3525736143 3461614626 2727179180 1719190350 3109246676 1597229592 1497702024 3613089465 3956534031 4038666602 2115340572 1084923681 2891508049 4181097073 3944960685 1458617946 3143028380 2888045580 2908318013 2991734419 1071991278 1468566176 1366678592 2821042273 418943948 4223565114 3149523516 510040630 3866869519 1902366078 1473383390 1968310207 2377366971 1417731267 776531025 3950220989 125315263 4050603045 3987956425 3005879678 461232057 589766347 1232521958 2395254259 38116070 1772434576 3007731720 2365382 2371901683 1899172331 857885993 4025639941 2790436407 4249622979 1561193115 2336225950 3617545577 2697172656 1336784921 2411101016 2994198115 1403551527 2945417697 1633008499 2151741407 1632768279 270501269 3187634865 1359941000 871213559 2256158558 94846264 122036485 1769584103 3232160685 3072773014 105678677 4293976955 3154966603 3086747585 4041960676 2021300249 1818942319 1570271838 3069376628 3356307080 3840459218 1480872561 3827464237 623643172 2999535155 3612339285 1985758703 1700132584 141303024 951311540 2566809865 98784861 2490620344 4249842282 3782301302 1378794291 2767953605 179250575 1293703800 501839051 2452142374 3038859588 193824943 3720713757 4280044009 2266850662 4288120457 3549294728 2760330222 4101390900 3214446796 441540960 416795899 3367187491 41464509 812690351 3994903850 3168459853 4234687564 457436237 224162180 2295623480 770436615 3601312233 3346679161 2160178506 3412594577 4116793540 3502585774 1783991917 837615305 1247352955 647361617 1394589477 852275045 4234232331 3438106459 1623822316 4177960886 2231886239 455346728 633302016 1230085689 2389141074 280768459 1113555027 1704428695 315987820 1883343835 682219842 3105164107 1666615055 416008393 542689937 4251354746 2428031235 600506540 1462194724 1216100322 1579125209 3894279299 2272600268 3982897555 1959239710 1548469642 23680295 3039918516 312569120 955658227 208599091 2550151540 1896928228 72100016 3500294088 2259931248 714883412 2816982143 632767661 3519655838 3168292943 4067157440 4007396175 564460381 2888233747 2498298136 1899649958 3701705288 4254381309 3145291933 1738936355 2350158291 1860002527 2471678465 1948612763 612958511 2549653753 1310382198))) ;;; create a variable to hold the state (setf rstate (make-random-state)) ;;; "reset" the random number generator: (setf *random-state* rstate) ;;; see what we get (loop repeat 10 collect (random 1.0)) ;;; let's change something in the second percussionist: ;;; 60 notes instead of 50 (with-sound(:srate 44100 :statistics t) (with-mix() "perc1" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp))) (with-mix() "perc2" 0 (loop repeat 60 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (potlid time amp))) (with-mix() "perc3" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " time) (trivet time amp rate)))) ;;; Duration: 89.2651, Last begin time: 20.6875 ;;; Compute time: 3.850, Compute ratio: 0.04 ;;; OutA max amp: 0.670 (near 14.188 secs) ;;; first: save the state of the random number generator (format t "~s~%" *random-state*) ;;; second: save the state somewhere #S(RANDOM-STATE :SEED 53394439818049 :FIXSEED #(322232860 96107050 250634044 75027447 224158754 510482997 248826895 178541235 39577401 527928579 470234764 290257996 51428656 131576166 207674176 390823226 215523727 199814170 122060315 381945238 243794854 443469863 133521199 257170632 256805179 265642477 198974496 80963503 189170188 206604054 237227377 353393716 229783914 96047189 434678376 86306459 149632373 248212571 196444087 518495937 39236071 137429568 347029803 2965016 17398680 104637269 228281457 351767297 76097493 84177204 486165845 198508384 338649829 116924086 41942180 1 32)) ;;; use the saved state: ;;; --> somehow set *random-state* to the saved state ;;; --> avoid global (special) variables that hold common music patterns (with-sound(:srate 44100 :statistics t) (let* ((*random-state* #S(RANDOM-STATE :SEED 214464539643913 :FIXSEED #(65427681 367335485 250634044 75027447 224158754 510482997 248826895 178541235 39577401 527928579 470234764 290257996 51428656 131576166 207674176 390823226 215523727 199814170 122060315 381945238 243794854 443469863 133521199 257170632 256805179 265642477 198974496 80963503 189170188 206604054 237227377 353393716 229783914 382284057 359650929 399018617 176020288 536256588 17902852 478918536 48178404 204065716 56771807 488407272 422693426 433834005 374329143 136243570 413154235 498987801 104220607 491584442 432050878 520273799 321642460 25 1))) (r (new heap :of `(q q h h e s s t s ,(new random :of '(s s s) :for 2)) :for 8)) (a (new heap :of `(ppp ppp ppp f mp p fff)))) (loop repeat 10 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp)))) ;;; Duration: 87.3276, Last begin time: 0.0000 ;;; Compute time: 1.867, Compute ratio: 0.02 ;;; OutA max amp: 0.794 (near 15.627 secs) ;;;"/zap/test.snd" ;;; Let's change all instruments to use one-cut (defun potlid (time amp rate &key (degree 0)(distance 1)) (one-cut time amp :soundfile "/usr/ccrma/web/html/courses/220b/sounds/small-lid-1.snd" ;; we do not add an amplitude envelope, just leave amp as it is :amp-func '(0 1 1 1) ;; we do pass a sampling rate multiplier :sample-rate-mult rate :degree degree :distance distance)) (defun pirexlid (time amp rate &key (degree 90)(distance 1)) (one-cut time amp :soundfile "/usr/ccrma/web/html/courses/220b/sounds/lid-1.snd" ;; we do not add an amplitude envelope, just leave amp as it is :amp-func '(0 1 1 1) ;; we do pass a sampling rate multiplier :sample-rate-mult rate :degree degree :distance distance)) (defun trivet (time amp rate &key (degree 45)(distance 1)) (one-cut time amp :soundfile "/usr/ccrma/web/html/courses/220b/sounds/1.snd" ;; we do not add an amplitude envelope, just leave amp as it is :amp-func '(0 1 1 1) ;; we do pass a sampling rate multiplier :sample-rate-mult rate :degree degree :distance distance)) (with-sound(:srate 44100 :channels 2 :statistics t) (let* ((r (new heap :of `(q q h h e s s t s ,(new random :of '(s s s) :for 2)) :for 8)) (a (new heap :of `(ppp ppp ppp f mp p fff))) (rt (new random :of '(1 1.1 0.9 1.2 0.1)))) (with-mix() "perc1" 0 (let* ((rates (new heap :of '(1 1.001 0.99 1.003 0.98)))) (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp (next rates))))) (with-mix() "perc2" 0 (let* ((flex (new random :of '(((0 1 1 1))((0 1 0.2 0.5 1 0.7))((0 1 0.3 0.9 1 1.3)))))) (loop repeat 50 for cut-sample-rate = (next flex) for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (potlid time amp 1.0)))) (with-mix() "perc3" 0 (loop repeat 50 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " time) (trivet time amp rate))) )) ;;; change rhythms... (with-sound(:srate 44100 :channels 2 :statistics t) (let* ((r (new heap :of `(q h. h h s s t t ,(new random :of '(s s s) :for 2)) :for 8)) (a (new heap :of `(pppp pppp ppp f mp p fff))) (rt (new random :of '(1 1.1 0.9 1.2 0.1)))) (with-mix() "perc1" 0 (let* ((rates (new heap :of '(1 1.001 0.99 1.003 0.98)))) (loop repeat 51 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (pirexlid time amp (next rates))))) (with-mix() "perc2" 0 (let* ((flex (new random :of '(((0 1 1 1))((0 1 0.2 0.5 1 0.7))((0 1 0.3 0.9 1 1.3)))))) (loop repeat 51 for cut-sample-rate = (next flex) for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) do (format t "~s " time) (potlid time amp 1.0)))) (with-mix() "perc3" 0 (loop repeat 51 for time = 0 then (+ time (rhythm (next r) 120)) for amp = (amplitude (next a)) for rate = (next rt) do (format t "~s " time) (trivet time amp rate))) ))