Browse Source

upadted radio submission

master
suroh 2 years ago
parent
commit
1fa0c662a9
5 changed files with 837 additions and 0 deletions
  1. +0
    -0
      pureData/radiopheniaSubmission.2.pd
  2. +498
    -0
      pureData/radiopheniaSubmission.pd
  3. +39
    -0
      superCollider/buffersExperiment.scd
  4. +69
    -0
      superCollider/ex_looperWithTrigger.scd
  5. +231
    -0
      superCollider/linesTutorial.scd

+ 0
- 0
pureData/radiopheniaSubmission.2.pd View File


+ 498
- 0
pureData/radiopheniaSubmission.pd View File

@ -0,0 +1,498 @@
#N canvas 814 99 824 925 10;
#X obj 43 273 osc~;
#N canvas 1307 215 517 674 asdr 0;
#X obj 219 461 vline~;
#X obj 281 399 pack f f;
#X obj 219 308 pack f f f f;
#X msg 219 332 1 \$2 \, \$4 \$3 \$2;
#X obj 96 225 sel 0;
#X obj 281 372 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 219 284 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 57 101 inlet;
#X obj 18 493 *~;
#X obj 17 525 outlet~;
#X obj -3 451 inlet~;
#X obj 145 71 inlet;
#X obj 190 71 inlet;
#X obj 234 72 inlet;
#X obj 279 72 inlet;
#X text 345 49 A : Max 300ms S : Max 500ms D : Max 100% level R : Max
1000ms, f 13;
#X msg 281 436 0 \$2;
#X floatatom 105 134 5 0 300 2 A - -;
#X floatatom 141 134 5 0 500 2 D - -;
#X floatatom 177 134 5 0 1 2 S - -;
#X floatatom 213 134 5 0 1000 2 R - -;
#X msg 106 45 50;
#X msg 136 45 200;
#X msg 199 45 200;
#X msg 170 45 0.8;
#X obj 74 498 *~;
#X obj 73 523 outlet~;
#X obj 50 449 inlet~;
#X obj 106 20 r onLoad;
#X connect 0 0 8 1;
#X connect 0 0 25 1;
#X connect 1 0 16 0;
#X connect 2 0 3 0;
#X connect 3 0 0 0;
#X connect 4 0 5 0;
#X connect 4 1 6 0;
#X connect 5 0 1 0;
#X connect 6 0 2 0;
#X connect 7 0 4 0;
#X connect 8 0 9 0;
#X connect 10 0 8 0;
#X connect 11 0 17 0;
#X connect 12 0 18 0;
#X connect 13 0 19 0;
#X connect 14 0 20 0;
#X connect 16 0 0 0;
#X connect 17 0 2 1;
#X connect 18 0 2 2;
#X connect 19 0 2 3;
#X connect 20 0 1 1;
#X connect 21 0 17 0;
#X connect 22 0 18 0;
#X connect 23 0 20 0;
#X connect 24 0 19 0;
#X connect 25 0 26 0;
#X connect 27 0 25 0;
#X connect 28 0 21 0;
#X connect 28 0 22 0;
#X connect 28 0 24 0;
#X connect 28 0 23 0;
#X coords 0 -1 1 1 150 60 1 100 100;
#X restore 43 545 pd asdr;
#X obj 43 150 mtof;
#X obj 658 365 table notes;
#X obj 659 388 table recBuffer;
#X obj 672 92 bng 30 250 50 0 butRec empty REC 32 16 0 30 -258113 -1
-1;
#X obj 673 166 bng 30 250 50 0 butPly empty PLY 32 16 0 30 -4034 -1
-1;
#X obj 43 876 dac~ 1 2 3 4;
#X obj 673 129 bng 30 250 50 0 butDub empty DUB 32 16 0 30 -260097
-1 -1;
#X floatatom 43 125 5 0 0 0 - - -;
#X floatatom 43 175 5 0 0 0 - - -;
#X obj 43 102 sigmund~ -hop 2048 pitch env;
#X obj 213 317 s noteStatus;
#X obj 112 271 osc~;
#X obj 672 33 loadbang;
#X obj 672 56 s onLoad;
#X obj 42 45 adc~ 1;
#X text 91 43 incoming pitch;
#X text 393 606 what I'm trying to do: Have a looper that pitch shifts
the looping of my recorded sound. Then cuts \, and splices my playing
back at me. A live remix of sorts.;
#X text 393 686 Record Looper not working Sound follower not very clean
not on off detection very tempremental;
#X obj 213 165 int;
#X obj 213 191 / 10;
#X floatatom 213 214 5 0 0 0 - - -;
#X obj 55 301 / 2;
#X obj 55 325 osc~;
#X obj 119 315 / 2;
#X obj 119 339 osc~;
#X obj 43 713 rev3~ 105 50 3000 0;
#N canvas 543 86 1100 790 arrayer 1;
#X obj 43 15 inlet;
#X obj 76 150 ||;
#X obj 43 245 spigot;
#X floatatom 76 216 5 0 0 0 - - -;
#X obj 131 39 t b f;
#X obj 131 92 +;
#X obj 160 714 line;
#X obj 160 738 outlet;
#X floatatom 136 296 5 0 0 0 - - -;
#X floatatom 160 600 5 0 0 0 - - -;
#X obj 136 366 f;
#X obj 163 366 + 1;
#X floatatom 136 417 5 0 0 0 - - -;
#X obj 136 344 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 160 490 + 1;
#X floatatom 160 540 5 0 0 0 - - -;
#X floatatom 43 312 5 0 0 0 - - -;
#X obj 377 714 line;
#X obj 377 738 outlet;
#X floatatom 377 600 5 0 0 0 - - -;
#X obj 136 321 sel 1;
#X obj 43 368 f;
#X obj 44 342 t b f;
#X obj 91 90 + 10;
#X msg 131 66 -10;
#X obj 76 120 > 10;
#X obj 110 120 < -10;
#X floatatom 43 391 5 0 0 0 - - -;
#X obj 136 391 % 16;
#X obj 160 513 % 16;
#X obj 132 169 sel 1;
#X obj 132 219 s noteChange;
#X msg 132 193 bang;
#X obj 43 488 tabwrite pitches;
#X obj 377 563 tabread pitches;
#X obj 160 562 tabread pitches;
#X msg 160 690 \$1 15;
#X msg 377 690 \$1 15;
#X obj 278 263 timer;
#X floatatom 278 286 6 0 0 0 - - -;
#X obj 279 240 b, f 2;
#X obj 793 199 array define -yrange 0 10000 durations 16;
#X obj 793 228 array define -yrange 0 1500 pitches 16;
#X obj 279 182 r noteStatus;
#X obj 383 287 f;
#X obj 410 287 + 1;
#X floatatom 383 338 5 0 0 0 - - -;
#X obj 279 207 sel 1;
#X obj 383 312 % 16;
#X obj 278 374 tabwrite durations;
#X obj 307 239 t b b;
#X obj 260 490 + 1;
#X floatatom 260 540 5 0 0 0 - - -;
#X obj 260 513 % 16;
#X obj 261 562 tabread durations;
#X obj 477 563 tabread durations;
#X floatatom 261 602 5 0 0 0 - - -;
#X floatatom 477 603 5 0 0 0 - - -;
#X msg 770 165 const 0;
#X obj 609 617 timer;
#X obj 609 591 t b b;
#X obj 609 542 == 0;
#X obj 609 566 sel 1;
#X floatatom 609 640 8 0 0 0 - - -;
#X obj 609 665 s melLen;
#X msg 609 452 0;
#X obj 609 476 t f f;
#X text 570 451 reset;
#X obj 609 425 r posReset;
#X connect 0 0 2 0;
#X connect 0 0 25 0;
#X connect 0 0 26 0;
#X connect 1 0 3 0;
#X connect 1 0 30 0;
#X connect 2 0 4 0;
#X connect 2 0 16 0;
#X connect 2 0 23 0;
#X connect 3 0 2 1;
#X connect 4 0 24 0;
#X connect 4 1 5 1;
#X connect 5 0 26 1;
#X connect 6 0 7 0;
#X connect 8 0 20 0;
#X connect 8 0 22 0;
#X connect 9 0 36 0;
#X connect 10 0 11 0;
#X connect 10 0 28 0;
#X connect 11 0 10 1;
#X connect 12 0 14 0;
#X connect 12 0 33 1;
#X connect 12 0 34 0;
#X connect 12 0 51 0;
#X connect 12 0 55 0;
#X connect 12 0 61 0;
#X connect 13 0 10 0;
#X connect 14 0 29 0;
#X connect 15 0 35 0;
#X connect 16 0 21 1;
#X connect 17 0 18 0;
#X connect 19 0 37 0;
#X connect 20 0 13 0;
#X connect 21 0 27 0;
#X connect 22 0 21 0;
#X connect 23 0 25 1;
#X connect 24 0 5 0;
#X connect 25 0 1 0;
#X connect 26 0 1 1;
#X connect 27 0 33 0;
#X connect 28 0 12 0;
#X connect 29 0 15 0;
#X connect 30 0 32 0;
#X connect 32 0 31 0;
#X connect 34 0 19 0;
#X connect 35 0 9 0;
#X connect 36 0 6 0;
#X connect 37 0 17 0;
#X connect 38 0 39 0;
#X connect 39 0 49 0;
#X connect 40 0 38 0;
#X connect 43 0 47 0;
#X connect 43 0 8 0;
#X connect 44 0 45 0;
#X connect 44 0 48 0;
#X connect 45 0 44 1;
#X connect 46 0 49 1;
#X connect 47 0 40 0;
#X connect 47 1 50 0;
#X connect 48 0 46 0;
#X connect 50 0 44 0;
#X connect 50 1 38 1;
#X connect 51 0 53 0;
#X connect 52 0 54 0;
#X connect 53 0 52 0;
#X connect 54 0 56 0;
#X connect 55 0 57 0;
#X connect 58 0 41 0;
#X connect 58 0 42 0;
#X connect 59 0 63 0;
#X connect 60 0 59 0;
#X connect 60 1 59 1;
#X connect 61 0 62 0;
#X connect 62 0 60 0;
#X connect 63 0 64 0;
#X connect 65 0 66 0;
#X connect 66 0 61 0;
#X connect 66 1 10 0;
#X connect 68 0 65 0;
#X restore 43 202 pd arrayer;
#X text 393 742 Right now "pd arrayer" is set to 16 steps to make nice
rhythmicy things. Maybe a change to this patch is for it to follow
my playing and then sometimes not.;
#X text 393 812 Could make a tab for each note played which would record
pitch \, duration and the recorded sound. Probably should live in a
separate max-patch to utilise different cores (remember how to do this?)
;
#X obj 44 658 *~ 0.8;
#X obj 93 660 *~ 0.8;
#X obj 669 214 r noteStatus;
#X obj 669 268 bng 30 250 50 0 empty empty NOTE_ON 35 17 0 20 -4034
-1 -1;
#X obj 669 240 sel 1 0;
#X obj 669 303 bng 30 250 50 0 empty empty NOTE_OFF 35 17 0 20 -1 -262144
-1;
#N canvas 296 246 550 610 noteOnOff 0;
#X obj 180 377 moses 1;
#X obj 180 428 f;
#X obj 207 429 + 1;
#X obj 180 404 bang;
#X msg 214 405 0;
#X obj 207 480 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 207 456 select 2;
#X obj 89 379 moses 1;
#X obj 89 430 f;
#X obj 116 431 + 1;
#X obj 89 406 bang;
#X msg 123 407 0;
#X obj 116 482 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 116 458 select 2;
#X msg 118 508 1;
#X msg 200 510 0;
#X obj 89 4 inlet;
#X obj 118 538 outlet;
#X floatatom 89 26 5 0 0 0 - - -;
#X obj 104 64 r noteOnSens;
#X obj 89 122 > 6;
#X obj 207 139 nbx 3 20 0 30 0 1 noteOnSens empty THRESH 0 -8 0 15
-262144 -1 -1 6 256;
#X obj 191 215 r noteChange;
#X obj 191 241 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 191 289 t b b;
#X obj 189 336 spigot;
#X obj 191 314 spigot;
#X obj 276 139 tgl 20 0 empty empty chg_d? 24 10 0 10 -262144 -1 -1
0 1;
#X obj 191 265 spigot;
#X obj 207 11 r onLoad;
#X msg 207 33 6;
#X connect 0 0 3 0;
#X connect 0 1 4 0;
#X connect 1 0 2 0;
#X connect 2 0 1 1;
#X connect 2 0 6 0;
#X connect 3 0 1 0;
#X connect 4 0 1 0;
#X connect 5 0 15 0;
#X connect 6 0 5 0;
#X connect 7 0 11 0;
#X connect 7 1 10 0;
#X connect 8 0 9 0;
#X connect 9 0 8 1;
#X connect 9 0 13 0;
#X connect 10 0 8 0;
#X connect 11 0 8 0;
#X connect 12 0 14 0;
#X connect 13 0 12 0;
#X connect 14 0 17 0;
#X connect 15 0 17 0;
#X connect 16 0 18 0;
#X connect 18 0 20 0;
#X connect 19 0 20 1;
#X connect 20 0 0 0;
#X connect 20 0 7 0;
#X connect 20 0 25 1;
#X connect 20 0 26 1;
#X connect 22 0 23 0;
#X connect 23 0 28 0;
#X connect 24 0 26 0;
#X connect 24 1 25 0;
#X connect 25 0 5 0;
#X connect 26 0 12 0;
#X connect 27 0 28 1;
#X connect 28 0 24 0;
#X connect 29 0 30 0;
#X connect 30 0 21 0;
#X coords 0 -1 1 1 150 65 1 200 100;
#X restore 213 241 pd noteOnOff;
#N canvas 550 114 1390 930 recordBuffers 0;
#X obj 31 40 inlet~;
#X obj 32 778 outlet~;
#X obj 154 37 r butRec;
#X obj 244 159 r butPly;
#X msg 282 208 stop;
#X obj 154 270 timer;
#X obj 172 240 tabwrite~ recBuffer;
#X obj 32 679 tabread4~ recBuffer;
#X obj 31 529 phasor~;
#X obj 32 588 *~;
#X obj 31 454 t b f;
#X obj 31 502 /;
#X msg 31 478 1;
#X obj 155 379 / 1000;
#X obj 185 158 r butDub;
#X msg 172 131 start 0;
#X msg 233 528 \; recBuffer resize \$1 \;;
#X obj 154 62 t b b;
#X msg 144 658 0;
#X text 41 705 audio playback of loop;
#X text 701 46 recording of dry signal to be processed later. challenges:
- getting the durations of the notes to match up with the recorded
notes. - repitching notes - getting full duration to match durations
sum;
#X obj 233 370 r audioRate;
#X floatatom 233 393 6 0 0 0 - - -;
#X obj 233 473 f;
#X obj 155 463 *;
#X floatatom 155 401 5 0 0 0 - - -;
#X obj 33 640 +~ 0;
#X obj 339 128 r melLen;
#X floatatom 339 249 8 0 0 0 - - -;
#X obj 233 498 * 24;
#X msg 352 188 0;
#X obj 339 215 spigot;
#X msg 384 188 1;
#X obj 352 155 r onLoad;
#X obj 339 274 t b f;
#X obj 243 183 t b b b;
#X obj 155 492 t f f;
#X connect 0 0 6 0;
#X connect 2 0 5 0;
#X connect 2 0 17 0;
#X connect 3 0 35 0;
#X connect 4 0 6 0;
#X connect 7 0 1 0;
#X connect 8 0 9 0;
#X connect 9 0 26 0;
#X connect 10 0 12 0;
#X connect 10 1 11 1;
#X connect 11 0 8 0;
#X connect 12 0 11 0;
#X connect 13 0 25 0;
#X connect 14 0 6 0;
#X connect 15 0 6 0;
#X connect 17 0 15 0;
#X connect 17 1 23 0;
#X connect 17 1 32 0;
#X connect 18 0 7 1;
#X connect 21 0 22 0;
#X connect 22 0 24 1;
#X connect 22 0 23 0;
#X connect 23 0 29 0;
#X connect 24 0 36 0;
#X connect 25 0 24 0;
#X connect 25 0 10 0;
#X connect 26 0 7 0;
#X connect 27 0 31 0;
#X connect 28 0 34 0;
#X connect 29 0 16 0;
#X connect 30 0 31 1;
#X connect 31 0 28 0;
#X connect 32 0 31 1;
#X connect 33 0 30 0;
#X connect 34 1 13 0;
#X connect 35 1 5 1;
#X connect 35 2 4 0;
#X connect 36 0 9 1;
#X connect 36 1 16 0;
#X restore 280 621 pd recordBuffers;
#N canvas 1153 446 450 300 audioRate 0;
#X msg 132 49 44100;
#X msg 147 77 48000;
#X msg 163 106 88200;
#X msg 179 132 96000;
#X obj 23 42 vradio 25 1 1 4 empty empty empty 0 -8 0 10 -262144 -1
-1 1;
#X text 53 47 44.1kHz;
#X text 53 71 48.0kHz;
#X text 53 95 88.2kHz;
#X text 53 119 96.0kHz;
#X obj 132 19 sel 0 1 2 3;
#X obj 152 177 s audioRate;
#X connect 0 0 10 0;
#X connect 1 0 10 0;
#X connect 2 0 10 0;
#X connect 3 0 10 0;
#X connect 4 0 9 0;
#X connect 9 0 0 0;
#X connect 9 1 1 0;
#X connect 9 2 2 0;
#X connect 9 3 3 0;
#X coords 0 -1 1 1 110 150 1 10 10;
#X restore 658 422 pd audioRate;
#X obj 577 98 r butRec;
#X obj 577 125 s posReset;
#X obj 281 591 lop~ 3000;
#X obj 279 667 *~ 0.8;
#X obj 334 667 *~ 0.8;
#X obj 227 665 *~ 0.8;
#X connect 0 0 1 0;
#X connect 1 0 31 0;
#X connect 1 1 32 0;
#X connect 2 0 10 0;
#X connect 9 0 2 0;
#X connect 10 0 28 0;
#X connect 11 0 9 0;
#X connect 11 1 20 0;
#X connect 13 0 1 1;
#X connect 14 0 15 0;
#X connect 16 0 11 0;
#X connect 16 0 42 0;
#X connect 16 0 45 0;
#X connect 20 0 21 0;
#X connect 21 0 22 0;
#X connect 22 0 37 0;
#X connect 23 0 24 0;
#X connect 24 0 1 1;
#X connect 25 0 26 0;
#X connect 26 0 1 0;
#X connect 27 0 7 0;
#X connect 27 0 7 2;
#X connect 27 1 7 1;
#X connect 27 1 7 3;
#X connect 28 0 0 0;
#X connect 28 0 23 0;
#X connect 28 1 13 0;
#X connect 28 1 25 0;
#X connect 28 1 26 0;
#X connect 31 0 27 0;
#X connect 32 0 27 1;
#X connect 33 0 35 0;
#X connect 35 0 34 0;
#X connect 35 1 36 0;
#X connect 37 0 1 2;
#X connect 37 0 12 0;
#X connect 38 0 43 0;
#X connect 38 0 44 0;
#X connect 40 0 41 0;
#X connect 42 0 38 0;
#X connect 43 0 7 0;
#X connect 43 0 7 2;
#X connect 44 0 7 1;
#X connect 44 0 7 3;
#X connect 45 0 7 3;
#X connect 45 0 7 2;

+ 39
- 0
superCollider/buffersExperiment.scd View File

@ -0,0 +1,39 @@
s.boot;
s.plotTree;
s.freeAll;
s.meter;
(
b.free;
b = Buffer.alloc(s, s.sampleRate * 5, 1);
t = s.sampleRate * 5
)
(
SynthDef(\rec, {
arg out=0, bufNum=0, inCh=0, recLvl=1, preLvl=0, loop=0;
var recIn, sig;
// recordIn...
recIn = SoundIn.ar(inCh, 1);
RecordBuf.ar(recIn, bufNum, recLevel: recLvl, preLevel: preLvl, doneAction: 2, loop: loop);
Out.ar(out, recIn);
}).add;
)
(
y = SynthDef(\playBack, {
arg outL=0, outR=1, bufNum=0, start=0, end=24000, rate=1;
var playBuf;
Out.ar(outL,Pan2.ar(BufRd.ar(1, b.bufnum, Phasor.ar(0, BufRateScale.kr(b.bufnum) * rate, start, end),0.0)));
Out.ar(outR,Pan2.ar(BufRd.ar(1, b.bufnum, Phasor.ar(0, BufRateScale.kr(b.bufnum) * rate, start, end),0.0)));
}).play(s,[\bufNum, b, \end, t])
)
y.set(\start, 0, \end, 250000, \rate, 1.2);
y.free;
x = Synth(\rec, [\out, 0, \bufNum, b, \loop, 1, \preLvl, 1]);
x.free;

+ 69
- 0
superCollider/ex_looperWithTrigger.scd View File

@ -0,0 +1,69 @@
// allocate buffer. Your loops should be shorter
b = Buffer.alloc(s, s.sampleRate * 16, 2);
(
l = {arg t_trig=0, t_reset=1, t_switch, plvl=1, ticknum=4, frombeat=0, grainsize=0, buf=b;
var in, gate, time, ticklength, firsttrig, ticks, beats, grainstarts, grainlengths,
grainend, startfrombeat, bufswitch, rlvl, playenv, player, grainer;
var beatnum = 4;
// audio input. Change to use other inputs
in = SoundIn.ar(0) ! 2;
gate = PulseCount.kr(t_trig, t_reset) > 1;
time = Latch.kr(Timer.kr(t_trig), gate);
ticklength = time / (beatnum * ticknum);
// initial trigger to set play- and recbuf to index 0
firsttrig = Trig.kr(SetResetFF.kr(t_trig, t_reset), 0.05);
ticks = TDuty.kr(ticklength, gate, 1) * gate;
// triggers at each loop cycle beginning + extra trigger at start of first recording
beats = Trig.kr(PulseCount.kr(ticks, t_reset) % (beatnum * ticknum), 0.1) + firsttrig;
//Poll.kr(ticks, ticks);
// values for the loopbuf and switching between it and the playbuf
grainstarts = Array.series(beatnum, 0, (SampleRate.ir * ticklength * ticknum).round(1));
grainlengths = [0.25, 0.5, 1, 2, 3, 4];
startfrombeat = Select.kr(frombeat, grainstarts);
grainend = startfrombeat + (ticklength * SampleRate.ir / Select.kr(grainsize, grainlengths)).round(1);
bufswitch = (((PulseCount.kr(t_switch, t_reset) % 2) * 2 ) -1);
// reclevel gate is read from controlbus index 3
rlvl = EnvGen.kr(Env.asr(0.05, 1.0, 0.05), PulseCount.kr(t_trig, t_reset) % 2);
playenv = EnvGen.kr(Env.asr(0.05, 1.0, 0.05), gate);
player = PlayBuf.ar(2, buf, BufRateScale.kr(buf), beats, loop:1);
grainer = LoopBuf.ar(2, buf, BufRateScale.kr(buf), bufswitch,
startfrombeat, startfrombeat, grainend, 2);
RecordBuf.ar(in <! in, buf, recLevel: rlvl, preLevel:plvl, loop:1, trigger:beats);
Out.ar(0, LinXFade2.ar(player, grainer, Lag.kr(bufswitch, 0.1), playenv) + in);
}.play;
)
// start recording first loop
l.set(\t_trig, 1);
// stop recording, start looping
l.set(\t_trig, 1);
// switch to LoopBuf
l.set(\t_switch, 1)
// beat 1-4, as 0-3
l.set(\frombeat, 1)
// size of the looped grain 0 - 5
l.set(\grainsize, 3)
// switch back to PlayBuf
l.set(\t_switch, 1)
// overdub
l.set(\t_trig, 1);
// reset and start again
l.set(\t_reset, 1);
b.zero;
//finally, clean up
l.free; b.free;

+ 231
- 0
superCollider/linesTutorial.scd View File

@ -0,0 +1,231 @@
//240A Theory Paper
//SuperCollider Composition by Michael Hetrick
//Started 12.03.12
//Finished 12.xx.12
//In this interactive paper, I will be exploring generative strategies in Supercollider. I am writing this paper simultaneously with my learning process,
//so all code you see is written as I learn it.
//Recently, I've been working a lot with my hardware modular synth. One of my favorite modules is Maths by Make Noise.
//The main concept of Maths is a looping AD envelope with many other tricks. I have found it to be invaluable in making music.
//I'm starting off with some example code for the Decay UGen:
play({ Decay.ar(Impulse.ar(XLine.kr(1,50,20), 0.25), 0.2, PinkNoise.ar, 0) });
//Similarly, the Decay2 documentation contains a much more pleasant sine implementation.
{ Decay.ar(Impulse.ar(XLine.kr(1,50,20), 0.25), 0.2, FSinOsc.ar(600), 0) }.play;
//Both of these examples use an XLine object to take the AD envelope from subsonic frequencies, through morphosis into AM synthesis.
//Annoylingly, both of these examples only use the left channel.
//While the morphosis is a very cool effect, I want to do something more rhythmic in stereo. I am starting with the following line:
{ Decay.ar(Impulse.ar([1.50, 1.25], 0.25), 0.3, FSinOsc.ar(600), 0)*0.3 }.play;
//This creates a short percussive loop in stereo. To achieve the stereo effect, I have used the [ , ] notation inside of the Impulse arguments.
//Next, I want to set up stereo notes:
{ Decay.ar(Impulse.ar([1.50, 1.25], 0.25), 0.3, FSinOsc.ar([600,300]), 0)*0.3 }.play;
//This is more interesting, but still quite boring. To offset this, I have set up three envelopes to be played simultaneously.
{ Decay.ar(Impulse.ar([1.50, 1.25], 0.25), 0.3, FSinOsc.ar(600), 0)*0.3 }.play;
{ Decay.ar(Impulse.ar([0.75, 1.75], 0.25), 0.3, FSinOsc.ar(300), 0)*0.3 }.play;
{ Decay.ar(Impulse.ar([2.50, 1.00], 0.25), 0.3, FSinOsc.ar(400), 0)*0.3 }.play;
//Triggering these simultaneously creates all sorts of rhythms as the patterns go in and out of sync.
//Okay, so now we need changing notes. It seems the best way to do this would be to create a SynthDef, and trigger each impulse manually:
SynthDef.new("blip", { |leftPitch = 440, rightPitch = 440, amp = 0.3, decay = 0.25, leftFreq=0.0, rightFreq=0.0|
var sig;
sig = Decay.ar(Impulse.ar([leftFreq, rightFreq], 0.0), decay, FSinOsc.ar([leftPitch, rightPitch]), 0)*amp;
Out.ar(0, sig ! 2); // sig ! 2 is the same as [sig, sig]
}).play;
x = Synth.new("blip");
// AC: Remember to free the synth! You can use the doneAction in envelope generators, but it can't be done here! (OK I see you've solved it below)
//That took a lot of trial and error! If Impulse's frequency is set to 0, it only releases one impulse. This now gives me the flexibility
//to sequence individual blips or full pulse streams. For example:
x = Synth.new("blip",["leftPitch", 600, "rightPitch", 400]); //blip chord
x = Synth.new("blip",["leftPitch", 600, "rightPitch", 400, "leftFreq", 200, "rightFreq", 20, "amp", 0.1]); //Stereo AM synth
// AC: I'm trying to figure out why this sounds buzzy. Do you know? I suspect there is a sudden jump in amplitude when the Decay is retriggered.
//We learned about Routines in class, which are something I haven't tried before. Let's attempt to create a simple stereo sequence.
r = Routine({
a = Synth.new("blip",["leftPitch", 600, "rightPitch", 400]).yield;
b = Synth.new("blip",["leftPitch", 300, "rightPitch", 300]).yield;
c = Synth.new("blip",["leftPitch", 900, "rightPitch", 200]).yield;
d = Synth.new("blip",["leftPitch", 800, "rightPitch", 400]).yield;
a.free; b.free; c.free; d.free;
});
r.next;
r.reset;
//Cool! We have two melodies (one on each channel). Alternatively, we can use a task:
(
t = Task({
loop {
[600, 300, 900, 800].do({ |seqFreq|
Synth("blip", [ amp: 0.2, leftPitch:seqFreq]);
0.125.wait;
});
}
}).play;
)
t.stop;
t.play;
//I like that! I'm wondering what will happen if I do a double do loop:
(
t = Task({
loop {
[400, 300, 200, 300].do({ |rightSeqFreq|
[600, 300, 900, 800].do({ |leftSeqFreq|
x = Synth("blip", [ amp: 0.2, leftPitch:leftSeqFreq, rightPitch:rightSeqFreq]);
0.125.wait;
x.free;
});
});
}
}).play;
)
t.stop;
t.play;
//I turned the Synth part into "x" so that I could free it after every loop. I did this because the RAM and CPU usage were
//growing with every repeat. This is now an efficient, looping sequence!
//The SC sequencing tutorial is now trying to convince me to use patterns. This seems like it would be a cleaner way of sequencing
//longer patterns with more variation.
(
var leftNoteSequence, rightNoteSequence;
leftNoteSequence = Pseq([600, 300, 900, 800, 400, 600],inf).asStream;
rightNoteSequence = Pseq([600, 400, 300, 200, 400],inf).asStream;
t = Task({
loop {
x = Synth("blip", [ amp: 0.2, leftPitch:leftNoteSequence.next, rightPitch:rightNoteSequence.next]);
0.125.wait;
x.free;
}
}).play;
)
//Now we're talking! Because of the uneven PSeq size, I now have a 30-event sequence. Let's see if we can do something cool
//with changing the frequency of the Impulse generator.
//First, let's redefine the SynthDef to include stereo amplitude control:
SynthDef.new("blip", { |leftPitch = 440, rightPitch = 440, ampL = 0.3, ampR = 0.3, decay = 0.25, leftFreq=0.0, rightFreq=0.0|
var sig;
sig = Decay.ar(Impulse.ar([leftFreq, rightFreq], 0.0), decay, FSinOsc.ar([leftPitch, rightPitch]), 0)*[ampL, ampR];
Out.ar(0, sig ! 2); // sig ! 2 is the same as [sig, sig]
}).play;
//Now, let's make a new sequence with pauses
(
var leftNoteSequence, rightNoteSequence;
var leftAmpSequence, rightAmpSequence;
leftNoteSequence = Pseq([600, 300, 900, 800, 400, 600],inf).asStream;
rightNoteSequence = Pseq([600, 400, 300, 200, 400],inf).asStream;
leftAmpSequence = Pseq([0.3, 0.0, 0.0, 0.3, 0.2, 0.1],inf).asStream;
rightAmpSequence = Pseq([0.3, 0.0, 0.3, 0.0, 0.0, 0.3, 0.3, 0.1, 0.3],inf).asStream;
t = Task({
loop {
x = Synth("blip", [ ampL: leftAmpSequence.next, ampR: rightAmpSequence.next, leftPitch:leftNoteSequence.next, rightPitch:rightNoteSequence.next]);
0.125.wait;
x.free;
}
}).play;
)
//Cool! Here it is with different Impulse frequencies:
(
var leftNoteSequence, rightNoteSequence;
var leftAmpSequence, rightAmpSequence;
var leftImpSequence, rightImpSequence;
leftNoteSequence = Pseq([600, 300, 900, 800, 400, 600],inf).asStream;
rightNoteSequence = Pseq([600, 400, 300, 200, 400],inf).asStream;
leftAmpSequence = Pseq([0.3, 0.0, 0.0, 0.3, 0.2, 0.1],inf).asStream;
rightAmpSequence = Pseq([0.3, 0.0, 0.3, 0.0, 0.0, 0.3, 0.3, 0.1, 0.3],inf).asStream;
leftImpSequence = Pseq([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 12.0],inf).asStream;
rightImpSequence = Pseq([0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 14.0, 0.0, 0.0, 0.0, 0.0],inf).asStream;
t = Task({
loop {
x = Synth("blip", [ ampL: leftAmpSequence.next, ampR: rightAmpSequence.next, leftPitch:leftNoteSequence.next, rightPitch:rightNoteSequence.next, leftFreq: leftImpSequence.next, rightFreq: rightImpSequence.next]);
0.125.wait;
x.free;
}
}).play;
)
//A bit clicky. Let's redefine our Synth to use Decay2, which has an attack time.
// AC: This is the solution...
(
SynthDef.new("blip", { |leftPitch = 440, rightPitch = 440, ampL = 0.3, ampR = 0.3, decay = 0.25, leftFreq=0.0, rightFreq=0.0|
var sig;
sig = Decay2.ar(Impulse.ar([leftFreq, rightFreq], 0.0), 0.01, decay, FSinOsc.ar([leftPitch, rightPitch]), 0)*[ampL, ampR];
Out.ar(0, sig ! 2); // sig ! 2 is the same as [sig, sig]
}).play;
)
//And now, let's use a shorter decay time, and let's change the length of time between loops
(
var leftNoteSequence, rightNoteSequence;
var leftAmpSequence, rightAmpSequence;
var leftImpSequence, rightImpSequence;
var loopLengthSequence;
leftNoteSequence = Pseq([600, 300, 900, 800, 400, 600],inf).asStream;
rightNoteSequence = Pseq([600, 400, 300, 200, 400],inf).asStream;
leftAmpSequence = Pseq([0.3, 0.0, 0.0, 0.3, 0.2, 0.1],inf).asStream;
rightAmpSequence = Pseq([0.3, 0.0, 0.3, 0.0, 0.0, 0.3, 0.3, 0.1, 0.3],inf).asStream;
leftImpSequence = Pseq([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 12.0],inf).asStream;
rightImpSequence = Pseq([0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 14.0, 0.0, 0.0, 0.0, 0.0],inf).asStream;
loopLengthSequence = Pseq([0.125, 0.125, 0.125, 0.25, 0.25, 0.125],inf).asStream;
t = Task({
loop {
x = Synth("blip", [ ampL: leftAmpSequence.next, ampR: rightAmpSequence.next, leftPitch:leftNoteSequence.next, rightPitch:rightNoteSequence.next, leftFreq: leftImpSequence.next, rightFreq: rightImpSequence.next, decay: 0.15]);
loopLengthSequence.next.wait;
x.free;
}
}).play;
)
//Now that I have a cool melodic sequence, I should put together a hi-hat pattern
(
SynthDef.new("hihat", { |ampL = 0.3, ampR = 0.3, decay = 0.10, leftFreq=0.0, rightFreq=0.0|
var sig;
sig = Decay2.ar(Impulse.ar([leftFreq, rightFreq], 0.0), 0.01, decay, WhiteNoise.ar, 0)*[ampL, ampR];
Out.ar(0, sig ! 2);
}).play;
)
//Adding it to the melodic sequence:
(
var hiHatSequence;
var leftNoteSequence, rightNoteSequence;
var leftAmpSequence, rightAmpSequence;
var leftImpSequence, rightImpSequence;
var loopLengthSequence;
leftNoteSequence = Pseq([600, 300, 900, 800, 400, 600],inf).asStream;
rightNoteSequence = Pseq([600, 400, 300, 200, 400],inf).asStream;
leftAmpSequence = Pseq([0.3, 0.0, 0.0, 0.3, 0.2, 0.1],inf).asStream;
rightAmpSequence = Pseq([0.3, 0.0, 0.3, 0.0, 0.0, 0.3, 0.3, 0.1, 0.3],inf).asStream;
leftImpSequence = Pseq([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 12.0],inf).asStream;
rightImpSequence = Pseq([0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 14.0, 0.0, 0.0, 0.0, 0.0],inf).asStream;
loopLengthSequence = Pseq([0.125, 0.125, 0.125, 0.25, 0.25, 0.125],inf).asStream;
hiHatSequence = Pseq([0.3, 0.1, 0.3, 0.0, 0.3, 0.0, 0.3, 0.0, 0.0, 0.1, 0.1, 0.0, 0.3],inf).asStream;
t = Task({
loop {
x = Synth("blip", [ ampL: leftAmpSequence.next, ampR: rightAmpSequence.next, leftPitch:leftNoteSequence.next, rightPitch:rightNoteSequence.next, leftFreq: leftImpSequence.next, rightFreq: rightImpSequence.next, decay: 0.15]);
y = Synth("hihat", [ ampL: hiHatSequence.next, ampR: hiHatSequence.next]);
loopLengthSequence.next.wait;
x.free; y.free;
}
}).play;
)

Loading…
Cancel
Save