1/* 2 Live Coding Functions 3 Author: Steven Yi 4*/ 5 6instr S1 7 ifreq = p4 8 iamp = p5 9endin 10 11instr P1 12 ibeat = p4 13endin 14 15;; TIME 16 17gk_tempo init 120 18 19 20/** Set tempo of global clock to itempo value in beats per minute. */ 21opcode set_tempo,0,i 22 itempo xin 23 gk_tempo init itempo 24endop 25 26/** Returns tempo of global clock in beats per minute. */ 27opcode get_tempo,i,0 28 xout i(gk_tempo) 29endop 30 31/** Adjust tempo of global clock towards by inewtempo by incr amount. */ 32opcode go_tempo, 0, ii 33 inewtempo, incr xin 34 35 icurtempo = i(gk_tempo) 36 itemp init icurtempo 37 38 if(inewtempo > icurtempo) ithen 39 itemp = min:i(inewtempo, icurtempo + abs(incr)) 40 gk_tempo init itemp 41 elseif (inewtempo < icurtempo) ithen 42 itemp = max:i(inewtempo, icurtempo - abs(incr)) 43 gk_tempo init itemp 44 endif 45endop 46 47instr Perform 48 ibeat = p4 49 50 schedule("P1", 0, p3, ibeat) 51endin 52 53 54gk_clock_internal init 0 55gk_clock_tick init 0 56gk_now init 0 57 58/** Returns value of now beat time 59 (Code used from Thorin Kerr's LivecodeLib.csd) */ 60opcode now, i, 0 61 xout i(gk_now) 62endop 63 64/** Returns current clock tick at init time */ 65opcode now_tick, i, 0 66 xout i(gk_clock_tick) 67endop 68 69/** Returns duration of time in given number of beats (quarter notes) */ 70opcode beats, i, i 71 inumbeats xin 72 ibeatdur = divz(60, i(gk_tempo), -1) 73 xout ibeatdur * inumbeats 74endop 75 76/** Returns duration of time in given number of measures (4 quarter notes) */ 77opcode measures, i, i 78 inummeasures xin 79 xout beats(inummeasures * 4) 80endop 81 82/** Returns duration of time in given number of ticks (16th notes) */ 83opcode ticks, i, i 84 inumbeats xin 85 ibeatdur = divz(60, i(gk_tempo), -1) 86 ibeatdur = ibeatdur / 4 87 xout ibeatdur * inumbeats 88endop 89 90/** Returns time from now for next beat, rounding to align 91 on beat boundary. 92 (Code used from Thorin Kerr's LivecodeLib.csd) */ 93opcode next_beat, i, p 94 ibeatcount xin 95 inow = now() 96 ibc = frac(ibeatcount) 97 inudge = int(ibeatcount) 98 iresult = inudge + ibc + (round(divz(inow, ibc, inow)) * (ibc == 0 ? 1 : ibc)) - inow 99 xout beats(iresult) 100endop 101 102/** Returns time from now for next measure, rounding to align to measure 103 boundary. */ 104opcode next_measure, i,0 105 inow = now() % 4 106 ival = 4 - inow 107 if(ival < 0.25) then 108 ival += 4 109 endif 110 inext = beats(ival) 111 xout inext 112endop 113 114/** Reset clock so that next tick starts at 0 */ 115opcode reset_clock, 0, 0 116 gk_clock_internal init 0 117 gk_clock_tick init -1 118 gk_now init -(ksmps / sr) 119endop 120 121/** Adjust clock by iadjust number of beats. 122 Value may be positive or negative. */ 123opcode adjust_clock, 0, i 124 iadjust xin 125 gk_now init i(gk_now) + iadjust 126endop 127 128 129instr Clock ;; our clock 130 ;; tick at 1/16th note 131 kfreq = (4 * gk_tempo) / 60 ;; frequency of 16th note 132 kdur = 1 / kfreq ;; duration of 16th note in seconds 133 kstep = (gk_tempo / 60) / kr ;; step size in quarter notes per buffer 134 kstep16th = kfreq / kr ;; step size in 16th notes per buffer 135 gk_now += kstep ;; advance beat clock 136 gk_clock_internal += kstep16th ;; advance 16th note clock 137 138 // checks if next buffer will be one where clock will 139 // trigger. If so, then schedule event for time 0 140 // which will get processed next buffer. 141 if(gk_clock_internal + kstep16th >= 1.0 ) then 142 gk_clock_internal -= 1.0 143 gk_clock_tick += 1 144 event("i", "Perform", 0, kdur, gk_clock_tick) 145 endif 146endin 147 148;; Randomization 149 150/** Given a random chance value between 0 and 1, calculates a random value and 151returns 1 if value is less than chance value. For example, giving a value of 0.7, 152it can read as "70 percent of time, return 1; else 0" */ 153opcode choose, i, i 154 iamount xin 155 ival = 0 156 157 if(random(0,1) < limit:i(iamount, 0, 1)) then 158 ival = 1 159 endif 160 xout ival 161endop 162 163;; Array Functions 164 165/** Cycles through karray using index. */ 166opcode cycle, i, ik[] 167 indx, kvals[] xin 168 ival = i(kvals, indx % lenarray(kvals)) 169 xout ival 170endop 171 172 173/** Checks to see if item exists within array. Returns 1 if 174 true and 0 if false. */ 175opcode contains, i, ii[] 176 ival, iarr[] xin 177 indx = 0 178 iret = 0 179 while (indx < lenarray:i(iarr)) do 180 if (iarr[indx] == ival) then 181 iret = 1 182 igoto end 183 endif 184 indx += 1 185 od 186end: 187 xout iret 188endop 189 190/** Checks to see if item exists within array. Returns 1 if 191 true and 0 if false. */ 192opcode contains, i, ik[] 193 ival, karr[] xin 194 indx = 0 195 iret = 0 196 while (indx < lenarray:i(karr)) do 197 if (i(karr,indx) == ival) then 198 iret = 1 199 igoto end 200 endif 201 indx += 1 202 od 203end: 204 xout iret 205endop 206 207/** Create a new array by removing all instances of a 208given number from an existing array. */ 209opcode remove, k[], ik[] 210 ival, karr[] xin 211 212 ifound = 0 213 indx = 0 214 while (indx < lenarray:i(karr)) do 215 if(i(karr, indx) == ival) then 216 ifound += 1 217 endif 218 indx += 1 219 od 220 221 kout[] init (lenarray:i(karr) - ifound) 222 223 indx = 0 224 iwriteIndx = 0 225 226 while (indx < lenarray:i(karr)) do 227 iv = i(karr, indx) 228 if(iv != ival) then 229 kout[iwriteIndx] init iv 230 iwriteIndx += 1 231 endif 232 indx += 1 233 od 234 235 xout kout 236endop 237 238/** Returns random item from karray. */ 239opcode rand, i, k[] 240 kvals[] xin 241 indx = int(random(0, lenarray(kvals))) 242 ival = i(kvals, indx) 243 xout ival 244endop 245 246/** Returns random item from String array. */ 247opcode rand, S, S[] 248 Svals[] xin 249 indx = int(random(0, lenarray(Svals))) 250 Sval = Svals[indx] 251 xout Sval 252endop 253 254/** Returns random item from karray. */ 255opcode randk, k, k[] 256 kvals[] xin 257 kndx = int(random:k(0, lenarray:k(kvals))) 258 kval = kvals[kndx] 259 xout kval 260endop 261 262/** Returns random item from karray. */ 263opcode randk, S, S[] 264 Svals[] xin 265 kndx = int(random:k(0, lenarray:k(Svals))) 266 Sval = Svals[kndx] 267 xout Sval 268endop 269 270 271;; Event 272 273/** Wrapper opcode that calls schedule only if iamp > 0 and ifreq > 0. */ 274opcode cause, 0, Siiii 275 Sinstr, istart, idur, ifreq, iamp xin 276 if(ifreq > 0 && iamp > 0) then 277 schedule(Sinstr, istart, idur, ifreq, iamp) 278 endif 279endop 280 281;; Beats 282 283/** Given a hexadecimal beat string pattern and optional 284itick (defaults to current now_tick()), returns value 1 if 285the given tick matches a hit in the hexadecimal beat, or 286returns 0 otherwise. */ 287opcode hexbeat, i, So 288 Spat, itick xin 289 290 if(itick <= 0) then 291 itick = now_tick() 292 endif 293 294 istrlen = strlen(Spat) 295 296 iout = 0 297 298 if (istrlen > 0) then 299 ;; 4 bits/beats per hex value 300 ipatlen = strlen(Spat) * 4 301 ;; get beat within pattern length 302 itick = itick % ipatlen 303 ;; figure which hex value to use from string 304 ipatidx = int(itick / 4) 305 ;; figure out which bit from hex to use 306 ibitidx = itick % 4 307 308 ;; convert individual hex from string to decimal/binary 309 ibeatPat = strtol(strcat("0x", strsub(Spat, ipatidx, ipatidx + 1))) 310 311 ;; bit shift/mask to check onset from hex's bits 312 iout = (ibeatPat >> (3 - ibitidx)) & 1 313 endif 314 315 xout iout 316 317endop 318 319 320/** Given hex beat pattern, use given itick to fire 321 events for given instrument, duration, frequency, and 322 amplitude */ 323opcode hexplay, 0, SiSiip 324 Spat, itick, Sinstr, idur, ifreq, iamp xin 325 326 if(ifreq > 0 && iamp > 0 && strlen(Sinstr) > 0 && hexbeat(Spat, itick) == 1) then 327 schedule(Sinstr, 0, idur, ifreq, iamp ) 328 endif 329endop 330 331/** Given hex beat pattern, use global clock to fire 332 events for given instrument, duration, frequency, and 333 amplitude */ 334opcode hexplay, 0, SSiip 335 Spat, Sinstr, idur, ifreq, iamp xin 336 337 itick = i(gk_clock_tick) 338 339 if(ifreq > 0 && iamp > 0 && strlen(Sinstr) > 0 && hexbeat(Spat, itick) == 1) then 340 schedule(Sinstr, 0, idur, ifreq, iamp ) 341 endif 342endop 343 344 345/** Given an octal beat string pattern and optional 346itick (defaults to current now_tick()), returns value 1 if 347the given tick matches a hit in the octal beat, or 348returns 0 otherwise. */ 349opcode octalbeat, i, Si 350 Spat, itick xin 351 352 ;; 3 bits/beats per octal value 353 ipatlen = strlen(Spat) * 4 354 ;; get beat within pattern length 355 itick = itick % ipatlen 356 ;; figure which octal value to use from string 357 ipatidx = int(itick / 3) 358 ;; figure out which bit from octal to use 359 ibitidx = itick % 3 360 361 ;; convert individual octal from string to decimal/binary 362 ibeatPat = strtol(strcat("0", strsub(Spat, ipatidx, ipatidx + 1))) 363 364 ;; bit shift/mask to check onset from hex's bits 365 xout (ibeatPat >> (2 - ibitidx)) & 1 366 367endop 368 369opcode octalplay, 0, SiSiip 370 Spat, ibeat, Sinstr, idur, ifreq, iamp xin 371 372 if(octalbeat(Spat, ibeat) == 1) then 373 schedule(Sinstr, 0, idur, ifreq, iamp ) 374 endif 375endop 376 377opcode octalplay, 0, SSiip 378 Spat, Sinstr, idur, ifreq, iamp xin 379 380 itick = i(gk_clock_tick) 381 382 if(octalbeat(Spat, itick) == 1) then 383 schedule(Sinstr, 0, idur, ifreq, iamp ) 384 endif 385endop 386 387;; Phase Functions 388 389/** Given count and period, return phase value in range [0-1) */ 390opcode phs, i, ii 391 icount, iperiod xin 392 xout (icount % iperiod) / iperiod 393endop 394 395/** Given period in ticks, return current phase of global 396 clock in range [0-1) */ 397opcode phs, i, i 398 iticks xin 399 xout (i(gk_clock_tick) % iticks) / iticks 400endop 401 402/** Given period in beats, return current phase of global 403 clock in range [0-1) */ 404opcode phsb, i, i 405 ibeats xin 406 iticks = ibeats * 4 407 xout (i(gk_clock_tick) % iticks) / iticks 408endop 409 410/** Given period in measures, return current phase of global 411 clock in range [0-1) */ 412opcode phsm, i, i 413 imeasures xin 414 iticks = imeasures * 4 * 4 415 xout (i(gk_clock_tick) % iticks) / iticks 416endop 417 418 419;; Iterative Euclidean Beat Generator 420;; Returns string of 1 and 0's 421opcode euclid_str, S, ii 422 ihits, isteps xin 423 424 Sleft = "1" 425 Sright = "0" 426 427 ileft = ihits 428 iright = isteps - ileft 429 430 while iright > 1 do 431 if (iright > ileft) then 432 iright = iright - ileft 433 Sleft = strcat(Sleft, Sright) 434 else 435 itemp = iright 436 iright = ileft - iright 437 ileft = itemp 438 Stemp = Sleft 439 Sleft = strcat(Sleft, Sright) 440 Sright = Stemp 441 endif 442 od 443 444 Sout = "" 445 indx = 0 446 while (indx < ileft) do 447 Sout = strcat(Sout, Sleft) 448 indx += 1 449 od 450 indx = 0 451 while (indx < iright) do 452 Sout = strcat(Sout, Sright) 453 indx += 1 454 od 455 456 xout Sout 457endop 458 459 460/** Given number of ihits for a period of isteps and an optional 461itick (defaults to current now_tick()), returns value 1 if 462the given tick matches a hit in the euclidean rhythm, or 463returns 0 otherwise. */ 464opcode euclid, i, iio 465 ihits, isteps, itick xin 466 467 if(itick <= 0) then 468 itick = now_tick() 469 endif 470 471 Sval = euclid_str(ihits, isteps) 472 indx = itick % strlen(Sval) 473 xout strtol(strsub(Sval, indx, indx + 1)) 474endop 475 476opcode euclidplay, 0, iiiSiip 477 ihits, isteps, itick, Sinstr, idur, ifreq, iamp xin 478 479 if(euclid(ihits, isteps, itick) == 1) then 480 schedule(Sinstr, 0, idur, ifreq, iamp) 481 endif 482endop 483 484 485opcode euclidplay, 0, iiSiip 486 ihits, isteps, Sinstr, idur, ifreq, iamp xin 487 488 itick = i(gk_clock_tick) 489 490 if(euclid(ihits, isteps, itick) == 1) then 491 schedule(Sinstr, 0, idur, ifreq, iamp) 492 endif 493endop 494 495;; Phase-based Oscillators 496 497/** Returns cosine of given phase (0-1.0) */ 498opcode xcos, i,i 499 iphase xin 500 xout cos(2 * $M_PI * iphase) 501endop 502 503/** Range version of xcos, similar to Impromptu's cosr */ 504opcode xcos, i,iii 505 iphase, ioffset, irange xin 506 xout ioffset + (cos(2 * $M_PI * iphase) * irange) 507endop 508 509/** Returns sine of given phase (0-1.0) */ 510opcode xsin, i,i 511 iphase xin 512 xout sin(2 * $M_PI * iphase) 513endop 514 515/** Range version of xsin, similar to Impromptu's sinr */ 516opcode xsin, i,iii 517 iphase, ioffset, irange xin 518 xout ioffset + (sin(2 * $M_PI * iphase) * irange) 519endop 520 521/** Non-interpolating oscillator. Given phase in range 0-1, 522returns value within the give k-array table. */ 523opcode xosc, i, ik[] 524 iphase, kvals[] xin 525 indx = int(lenarray:i(kvals) * (iphase % 1)) 526 xout i(kvals, indx) 527endop 528 529 530/** Non-interpolating oscillator. Given phase duration in beats, 531returns value within the give k-array table. (shorthand for xosc(phsb(ibeats), karr) )*/ 532opcode xoscb, i,ik[] 533 ibeats, kvals[] xin 534 xout xosc(phsb(ibeats), kvals) 535endop 536 537/** Non-interpolating oscillator. Given phase duration in measures, 538returns value within the give k-array table. (shorthand for xosc(phsm(ibeats), karr) )*/ 539opcode xoscm, i, ik[] 540 ibeats, kvals[] xin 541 xout xosc(phsm(ibeats), kvals) 542endop 543 544 545/** Linearly-interpolating oscillator. Given phase in range 0-1, 546returns value intepolated within the two closest points of phase within k-array 547table. */ 548opcode xosci, i, ik[] 549 iphase, kvals[] xin 550 ilen = lenarray:i(kvals) 551 indx = ilen * (iphase % 1) 552 ibase = int(indx) 553 ifrac = indx - ibase 554 555 iv0 = i(kvals, ibase) 556 iv1 = i(kvals, (ibase + 1) % ilen) 557 xout iv0 + (iv1 - iv0) * ifrac 558endop 559 560 561/** Linearly-interpolating oscillator. Given phase duration in beats, 562returns value intepolated within the two closest points of phase within k-array 563table. (shorthand for xosci(phsb(ibeats), karr) )*/ 564opcode xoscib, i,ik[] 565 ibeats, kvals[] xin 566 xout xosci(phsb(ibeats), kvals) 567endop 568 569/** Linearly-interpolating oscillator. Given phase duration in measures, 570returns value intepolated within the two closest points of phase within k-array 571table. (shorthand for xosci(phsm(ibeats), karr) )*/ 572opcode xoscim, i,ik[] 573 ibeats, kvals[] xin 574 xout xosci(phsm(ibeats), kvals) 575endop 576 577/** Line (Ramp) oscillator. Given phase in range 0-1, return interpolated value between given istart and iend. */ 578opcode xlin, i, iii 579 iphase, istart, iend xin 580 xout istart + (iend - istart) * iphase 581endop 582 583;; Duration Sequences 584 585/** Given a tick value and array of durations, returns new duration value for tick. */ 586opcode xoscd, i, ik[] 587 itick, kdurs[] xin 588 indx = 0 589 isum = 0 590 ilen = lenarray:i(kdurs) 591 ival = 0 592 593 while (indx < ilen) do 594 isum += i(kdurs, indx) 595 indx += 1 596 od 597 598 itick = itick % isum 599 indx = 0 600 ival = 0 601 icur = 0 602 603 while (indx < ilen) do 604 itemp = i(kdurs, indx) 605 606 if(itick < icur + itemp) then 607 ival = itemp 608 indx += ilen 609 else 610 icur += abs(itemp) 611 endif 612 613 indx += 1 614 od 615 616 xout ival 617 618 endop 619 620 621/** Given an array of durations, returns new duration value for current clock tick. Useful with mod division and cycle for additive/subtractive rhythms. */ 622opcode xoscd, i, k[] 623 kdurs[] xin 624 xout xoscd(now_tick(), kdurs) 625endop 626 627 628/** Given a tick value and array of durations, returns new duration or 0 depending upon whether tick hits a new duration value. Values 629may be positive or negative, but not zero. Negative values can be interpreted as rest durations. */ 630opcode dur_seq, i, ik[] 631 itick, kdurs[] xin 632 ival = 0 633 icur = 0 634 ilen = lenarray:i(kdurs) 635 itotal = 0 636 637 indx = 0 638 while (indx < ilen) do 639 itotal += abs:i(i(kdurs, indx)) 640 indx += 1 641 od 642 643 ;print itotal 644 645 indx = 0 646 itick = itick % itotal 647 648 while (indx < ilen) do 649 itemp = i(kdurs, indx) 650 if(icur == itick) then 651 ival = itemp 652 indx += ilen 653 elseif (icur > itick) then 654 indx += ilen 655 else 656 icur += abs(itemp) 657 endif 658 659 indx += 1 660 od 661 xout ival 662endop 663 664 665/** Given an array of durations, returns new duration or 0 depending upon 666 * whether current clock tick hits a new duration value. Values 667may be positive or negative, but not zero. Negative values can be interpreted 668as rest durations. */ 669opcode dur_seq, i, k[] 670 kdurs[] xin 671 xout dur_seq(now_tick(), kdurs) 672endop 673 674/** Experimental opcode for generating melodic lines given array of durations, pitches, and amplitudes. Durations follow dur_seq practice that negative values are rests. Pitch and amp array indexing wraps according to their array lengths given index of non-rest duration value currently fired. */ 675opcode melodic, iii, ik[]k[]k[] 676 itick, kdurs[], kpchs[], kamps[] xin 677 678 idur = dur_seq(itick, kdurs) 679 ipch = 0 680 iamp = 0 681 682 indx = 0 683 itotal = 0 684 ilen = lenarray:i(kdurs) 685 686 while (indx < ilen) do 687 itotal += abs:i(i(kdurs, indx)) 688 indx += 1 689 od 690 691 itick = itick % itotal 692 693 if(idur > 0) then 694 indx = 0 695 icur = 0 696 ivalindx = 0 697 698 while (indx < ilen) do 699 itemp = i(kdurs, indx) 700 701 if(icur == itick) then 702 indx += ilen 703 elseif (icur > itick) then 704 indx += ilen 705 else 706 if (itemp > 0) then 707 ivalindx += 1 708 endif 709 710 icur += abs(itemp) 711 endif 712 713 indx += 1 714 od 715 716 ipch = i(kpchs, ivalindx % lenarray:i(kpchs)) 717 iamp = i(kamps, ivalindx % lenarray:i(kamps)) 718 endif 719 720 xout idur, ipch, iamp 721endop 722 723/** Experimental opcode for generating melodic lines given array of durations, pitches, and amplitudes. Durations follow dur_seq practice that negative values are rests. Pitch and amp array indexing wraps according to their array lengths given index of non-rest duration value currently fired. */ 724opcode melodic, iii, k[]k[]k[] 725 kdurs[], kpchs[], kamps[] xin 726 idur, ipch, iamp = melodic(now_tick(), kdurs, kpchs, kamps) 727 xout idur, ipch, iamp 728endop 729 730;; String functions 731 732/** 733 rotate - Rotates string by irot number of values. 734 (Inspired by rotate from Charlie Roberts' Gibber.) 735*/ 736opcode rotate, S, Si 737 Sval, irot xin 738 739 ilen = strlen(Sval) 740 irot = irot % ilen 741 Sout = strcat(strsub(Sval, irot, ilen), strsub(Sval, 0, irot)) 742 xout Sout 743endop 744 745 746/** Repeats a given String x number of times. For example, `Sval = strrep("ab6a", 2)` will produce the value of "ab6aab6a". Useful in working with Hex beat strings. */ 747opcode strrep, S, Si 748 Sval, inum xin 749 750 Sout = Sval 751 indx = 1 752 while (indx < inum) do 753 Sout = strcat(Sout, Sval) 754 indx += 1 755 od 756 757 xout Sout 758endop 759 760 761;; Channel Helper 762 763/** Sets i-rate value into channel and sets initialization to true. Works together 764 with xchan */ 765opcode xchnset, 0, Si 766 SchanName, ival xin 767 Sinit = sprintf("%s_initialized", SchanName) 768 chnset(1, Sinit) 769 chnset(ival, SchanName) 770endop 771 772/** xchan 773 Initializes a channel with initial value if channel has default value of 0 and 774 then returns the current value from the channel. Useful in live coding to define 775 a dynamic point that will be automated or set outside of the instrument that is 776 using the channel. 777 778 Opcode is overloaded to return i- or k- value. Be sure to use xchan:i or xchan:k 779 to specify which value to use. 780*/ 781opcode xchan, i,Si 782 SchanName, initVal xin 783 784 Sinit = sprintf("%s_initialized", SchanName) 785 if(chnget:i(Sinit) == 0) then 786 chnset(1, Sinit) 787 chnset(initVal, SchanName) 788 endif 789 xout chnget:i(SchanName) 790endop 791 792/** xchan 793 Initializes a channel with initial value if channel has default value of 0 and 794 then returns the current value from the channel. Useful in live coding to define 795 a dynamic point that will be automated or set outside of the instrument that is 796 using the channel. 797 798 Opcode is overloaded to return i- or k- value. Be sure to use xchan:i or xchan:k 799 to specify which value to use. 800*/ 801opcode xchan, k,Si 802 SchanName, initVal xin 803 804 Sinit = sprintf("%s_initialized", SchanName) 805 if(chnget:i(SchanName) == 0) then 806 chnset(1, Sinit) 807 chnset(initVal, SchanName) 808 endif 809 xout chnget:k(SchanName) 810endop 811 812;; SCALE/HARMONY (experimental) 813 814gi_scale_major[] = array(0, 2, 4, 5, 7, 9, 11) 815gi_scale_minor[] = array(0, 2, 3, 5, 7, 8, 10) 816 817gi_cur_scale[] = gi_scale_minor 818gi_scale_base = 60 819gi_chord_offset = 0 820 821/** Set root note of scale in MIDI note number. */ 822opcode set_root, 0,i 823 iscale_root xin 824 gi_scale_base = iscale_root 825endop 826 827/** Calculate frequency from root note of scale, using 828octave and pitch class. */ 829opcode from_root, i, ii 830 ioct, ipc xin 831 ival = gi_scale_base + (ioct * 12) + ipc 832 xout cpsmidinn(ival) 833endop 834 835/** Set the global scale. Currently supports "maj" for major and "min" for minor scales. */ 836opcode set_scale, 0,S 837 Scale xin 838 if(strcmp("maj", Scale) == 0) then 839 gi_cur_scale = gi_scale_major 840 else 841 gi_cur_scale = gi_scale_minor 842 endif 843endop 844 845/** Calculate frequency from root note of scale, using 846octave and scale degree. */ 847opcode in_scale, i, ii 848 ioct, idegree xin 849 850 ibase = gi_scale_base + (ioct * 12) 851 852 idegrees = lenarray(gi_cur_scale) 853 854 ioct = int(idegree / idegrees) 855 indx = idegree % idegrees 856 857 if(indx < 0) then 858 ioct -= 1 859 indx += idegrees 860 endif 861 862 xout cpsmidinn(ibase + (ioct * 12) + gi_cur_scale[int(indx)]) 863endop 864 865/** Calculate frequency from root note of scale, using 866octave and scale degree. (k-rate version of opcode) */ 867opcode in_scale, k, kk 868 koct, kdegree xin 869 870 kbase = gi_scale_base + (koct * 12) 871 872 idegrees = lenarray(gi_cur_scale) 873 874 koct = int(kdegree / idegrees) 875 kndx = kdegree % idegrees 876 877 if(kndx < 0) then 878 koct -= 1 879 kndx += idegrees 880 endif 881 882 xout cpsmidinn(kbase + (koct * 12) + gi_cur_scale[int(kndx)]) 883endop 884 885/** Quantizes given MIDI note number to the given scale 886 (Base on pc:quantize from Extempore) */ 887opcode pc_quantize, i, ii[] 888 ipitch_in, iscale[] xin 889 inotenum = round:i(ipitch_in) 890 ipc = inotenum % 12 891 iout = inotenum 892 893 894 indx = 0 895 while (indx < 7) do 896 if(contains(ipc + indx, iscale) == 1) then 897 iout = inotenum + indx 898 goto end 899 elseif (contains(ipc - indx, iscale) == 1) then 900 iout = inotenum - indx 901 goto end 902 endif 903 indx += 1 904 od 905 end: 906 xout iout 907endop 908 909/** Quantizes given MIDI note number to the current active scale 910 (Base on pc:quantize from Extempore) */ 911opcode pc_quantize, i, i 912 ipitch_in xin 913 ival = pc_quantize(ipitch_in, gi_cur_scale) 914 xout ival 915endop 916 917/* BELOW CHORD SYSTEM IS EXPERIMENTAL */ 918 919gi_chord_base = 0 920gi_chord_maj[] = array(0,4,7) 921gi_chord_maj7[] = array(0,4,7,11) 922gi_chord_min[] = array(0,3,7) 923gi_chord_min7[] = array(0,3,7,10) 924gi_chord_dim[] = array(0,3,6) 925gi_chord_dim7[] = array(0,3,6,9) 926gi_chord_aug[] = array(0,4,8) 927gi_chord_current[] = gi_chord_maj 928 929opcode set_chord, 0, ii[] 930 ichord_root, ichord_intervals[] xin 931 gi_chord_base = ichord_root 932 gi_chord_current = ichord_intervals 933endop 934 935opcode set_chord, 0, S 936 Schord xin 937endop 938 939opcode in_chord, i, ii 940 ioct, idegree xin 941 942 ibase = gi_scale_base + (ioct * 12) + gi_chord_base 943 944 idegrees = lenarray(gi_chord_current) 945 946 ioct = int(idegree / idegrees) 947 indx = idegree % idegrees 948 949 if(indx < 0) then 950 ioct -= 1 951 indx += idegrees 952 endif 953 954 xout cpsmidinn(ibase + (ioct * 12) + gi_chord_current[indx]) 955endop 956 957;; AUDIO 958 959/** Utility opcode for declicking an audio signal. Should only be used in instruments that have positive p3 duration. */ 960opcode declick, a, a 961 ain xin 962 aenv = linseg:a(0, 0.01, 1, p3 - 0.02, 1, 0.01, 0, 0.01, 0) 963 xout ain * aenv 964endop 965 966/** Custom non-interpolating oscil that takes in kfrequency and array to use as oscillator table 967data. Outputs k-rate signal. */ 968opcode oscil, k, kk[] 969 kfreq, kin[] xin 970 ilen = lenarray(kin) 971 kphs = phasor:k(kfreq) 972 kout = kin[int(kphs * ilen) % ilen] 973 xout kout 974endop 975 976 977;; KILLING INSTANCES 978 979instr KillImpl 980 Sinstr = p4 981 if (nstrnum(Sinstr) > 0) then 982 turnoff2(Sinstr, 0, 0) 983 endif 984 turnoff 985endin 986 987/** Turns off running instances of named instruments. Useful when livecoding 988 audio and control signal process instruments. May not be effective if for 989 temporal recursion instruments as they may be non-running but scheduled in the 990 event system. In those situations, try using clear_instr to overwrite the 991 instrument definition. */ 992opcode kill, 0,S 993 Sinstr xin 994 schedule("KillImpl", 0, 0.01, Sinstr) 995endop 996 997/** Redefines instr to empty body. Useful for killing 998 temporal recursion or clock callback functions */ 999opcode clear_instr, 0,S 1000 Sinstr xin 1001 Sinstr_body = sprintf("instr %s\nendin\n", Sinstr) 1002 ires = compilestr(Sinstr_body) 1003 prints(sprintf("Cleared instrument definition: %s\n", 1004 Sinstr)) 1005endop 1006 1007/** Starts running a named instrument for indefinite time using p2=0 and p3=-1. 1008 Will first turnoff any instances of existing named instrument first. Useful 1009 when livecoding always-on audio and control signal process instruments. */ 1010opcode start, 0,S 1011 Sinstr xin 1012 1013 if (nstrnum(Sinstr) > 0) then 1014 kill(Sinstr) 1015 schedule(Sinstr, ksmps / sr,-1) 1016 endif 1017endop 1018 1019/** Stops a running named instrument, allowing for release segments to operate. */ 1020opcode stop, 0,S 1021 Sinstr xin 1022 1023 if (nstrnum(Sinstr) > 0) then 1024 schedule(-nstrnum(Sinstr), 0, 0) 1025 endif 1026endop 1027 1028instr CodeEval 1029 Scode = p4 1030 ires = compilestr(Scode) 1031endin 1032 1033/** Evaluate code at a given time */ 1034opcode eval_at_time, 0, Si 1035 Scode, istart xin 1036 iblock init ksmps / sr 1037 ;; adjust one block of time difference since this is 1038 ;; will need to be added as an event back on to the scheduler 1039 schedule("CodeEval", max:i(0, istart - iblock), 0, Scode) 1040endop 1041 1042 1043;; Fades 1044 1045gi_fade_range init -30 1046 1047 1048/** Sets the range in db to fade over. By default, range is -30 (i.e., fades from -30dbfs to 0dbfs) */ 1049opcode set_fade_range, 0, i 1050 irange xin 1051 gi_fade_range init irange 1052endop 1053 1054/** Given a fade channel identifier (number) and number of ticks to fade over time, advances from current fade channel value towards 0dbfs (1.0) using the globally set fade range. (By default starts fading in from -30dBfs and stops at 0dbfs.) */ 1055opcode fade_in, i, ii 1056 ident, inumticks xin 1057 Schan = sprintf("fade_chan_%d", ident) 1058 ival = chnget:i(Schan) 1059 if(ival < 1.0) then 1060 ival = limit:i(ival + (1 / inumticks), 0, 1.0) 1061 chnset(ival, Schan) 1062 iret = ampdbfs((1- ival) * gi_fade_range) 1063 else 1064 iret = ival 1065 endif 1066 1067 xout iret 1068endop 1069 1070/** Given a fade channel identifier (number) and number of ticks to fade over time, advances from current fade channel value towards 0 using the globally set fade range. (By default starts fading out from 0dBfs and stops at -30dbfs.) */ 1071opcode fade_out, i, ii 1072 ident, inumticks xin 1073 Schan = sprintf("fade_chan_%d", ident) 1074 1075 ival = chnget:i(Schan) 1076 iret init 0 1077 1078 if(ival > 0.0) then 1079 ival = limit:i(ival - (1 / inumticks), 0, 1.0) 1080 chnset(ival, Schan) 1081 iret = ampdbfs((1- ival) * gi_fade_range) 1082 else 1083 iret = ival 1084 endif 1085 1086 xout iret 1087endop 1088 1089/** Read value from fade channel. Useful if copy/pasting then wanting to just read from fade and control in the original code. */ 1090opcode fade_read, i, i 1091 ident xin 1092 Schan = sprintf("fade_chan_%d", ident) 1093 iret = chnget:i(Schan) 1094 xout iret 1095endop 1096 1097/** Set value for fade channel to given value. Should be in range 0-1.0. (Typically one sets to either 0 or 1.) */ 1098opcode set_fade, 0,ii 1099 ident, ival xin 1100 Schan = sprintf("fade_chan_%d", ident) 1101 ival = limit:i(ival, 0, 1.0) 1102 chnset(ival, Schan) 1103endop 1104 1105;; Stereo Audio Bus 1106 1107ga_sbus[] init 16, 2 1108 1109/** Write two audio signals into stereo bus at given index */ 1110opcode sbus_write, 0,iaa 1111 ibus, al, ar xin 1112 ga_sbus[ibus][0] = al 1113 ga_sbus[ibus][1] = ar 1114endop 1115 1116/** Mix two audio signals into stereo bus at given index */ 1117opcode sbus_mix, 0,iaa 1118 ibus, al, ar xin 1119 ga_sbus[ibus][0] = ga_sbus[ibus][0] + al 1120 ga_sbus[ibus][1] = ga_sbus[ibus][1] + ar 1121endop 1122 1123/** Clear audio signals from bus channel */ 1124opcode sbus_clear, 0, i 1125 ibus xin 1126 aclear init 0 1127 ga_sbus[ibus][0] = aclear 1128 ga_sbus[ibus][1] = aclear 1129endop 1130 1131/** Read audio signals from bus channel */ 1132opcode sbus_read, aa, i 1133 ibus xin 1134 aclear init 0 1135 al = ga_sbus[ibus][0] 1136 ar = ga_sbus[ibus][1] 1137 xout al, ar 1138endop 1139 1140;; MIXER 1141 1142gi_reverb_mixer_on init 0 1143 1144/** Always-on Mixer instrument with Reverb send channel. Use start("ReverbMixer") to run. Designed 1145 for use with pan_verb_mix to simplify signal-based live coding. */ 1146instr ReverbMixer 1147 1148 gi_reverb_mixer_on init 1 1149 1150 ;; dry and reverb send signals 1151 a1, a2 sbus_read 0 1152 a3, a4 sbus_read 1 1153 1154 al, ar reverbsc a3, a4, xchan:k("Reverb.fb", 0.7), xchan:k("Reverb.cut", 12000) 1155 1156 kamp = xchan:k("Mix.amp", 1.0) 1157 1158 a1 = tanh(a1 + al) * kamp 1159 a2 = tanh(a2 + ar) * kamp 1160 1161 out(a1, a2) 1162 1163 sbus_clear(0) 1164 sbus_clear(1) 1165endin 1166 1167 1168/** Always-on Mixer instrument with Reverb send channel and feedback delay. Use start("FBReverbMixer") to run. Designed 1169 for use with pan_verb_mix to simplify signal-based live coding. */ 1170instr FBReverbMixer 1171 al, ar sbus_read 0 1172 1173 afb0 init 0 1174 afb1 init 0 1175 1176 gi_reverb_mixer_on init 1 1177 1178 ;; dry and reverb send signals 1179 a1, a2 sbus_read 0 1180 a3, a4 sbus_read 1 1181 1182 al, ar reverbsc a3, a4, xchan:k("Reverb.fb", 0.7), xchan:k("Reverb.cut", 12000) 1183 1184 a1 = tanh(a1 + al + afb0) 1185 a2 = tanh(a2 + ar + afb1) 1186 1187 kfb_amt = xchan:k("FB.amt", 0.9) 1188 kfb_dur = xchan:k("FB.dur", 4.2) * 1000 ;; time in ms 1189 1190 afb0 = vdelay(a1 * kfb_amt, kfb_dur, 10000) 1191 afb1 = vdelay(a2 * kfb_amt, kfb_dur, 10000) 1192 1193 kamp = xchan:k("Mix.amp", 1.0) 1194 a1 *= kamp 1195 a2 *= kamp 1196 1197 out(a1, a2) 1198 1199 sbus_clear(0) 1200 sbus_clear(1) 1201 1202endin 1203 1204/** Utility opcode to pan signal, send dry to mixer, and send amount 1205 of signal to reverb. If ReverbMixer is not on, will output just 1206 panned signal using out opcode. */ 1207opcode pan_verb_mix, 0,akk 1208 asig, kpan, krvb xin 1209 ;; Panning and send to mixer 1210 al, ar pan2 asig, kpan 1211 1212 if(gi_reverb_mixer_on == 1) then 1213 sbus_mix(0, al, ar) 1214 sbus_mix(1, al * krvb, ar * krvb) 1215 else 1216 out(al, ar) 1217 endif 1218endop 1219 1220/** Utility opcode to send dry stereo to mixer and send amount 1221 of stereo signal to reverb. If ReverbMixer is not on, will output just 1222 panned signal using out opcode. */ 1223opcode reverb_mix, 0, aak 1224 al, ar, krvb xin 1225 1226 if(gi_reverb_mixer_on == 1) then 1227 sbus_mix(0, al, ar) 1228 sbus_mix(1, al * krvb, ar * krvb) 1229 else 1230 out(al, ar) 1231 endif 1232endop 1233 1234;; Automation 1235 1236/** Set a channel value at a given time. p4=ChannelName, p5=value*/ 1237instr ChnSet 1238 Schan = p4 1239 ival = p5 1240 chnset(ival, Schan) 1241endin 1242 1243/** Automation instrument for channels. Takes in "ChannelName", start value, end value, and automation type (0=linear, else exponential). */ 1244instr Auto 1245 Schan = p4 1246 istart = p5 1247 iend = p6 1248 itype = p7 1249 kauto init 0 1250 1251 if(itype == 0) then 1252 kauto = line:k(istart, p3, iend) 1253 else 1254 kauto = expon:k(istart, p3, iend) 1255 endif 1256 1257 chnset(kauto, Schan) 1258endin 1259 1260/** Automate channel value over time. Takes in "ChannelName", duration, start value, end value, and automation type (0=linear, else exponential). For exponential, signs of istart and end must match and neither can be zero. */ 1261opcode automate, 0, Siiii 1262 Schan, idur, istart, iend, itype xin 1263 schedule("Auto", 0, idur, Schan, istart, iend, itype) 1264endop 1265 1266instr FadeOutMix 1267 kauto = ampdbfs:k(line:k(0, p3, -60)) 1268 chnset(kauto, "Mix.amp") 1269endin 1270 1271/** Utility opcode for end of performances to fade out Mixer over given idur time. idur defaults to 30 seconds. **/ 1272opcode fade_out_mix, 0, o 1273 idur xin 1274 idur = (idur <= 0 ? 30 : idur) 1275 schedule("FadeOutMix", 0, idur) 1276 schedule("ChnSet", idur + 0.1, 0, "Mix.amp", 0) 1277endop 1278 1279;; DSP 1280 1281/** Saturation using tanh */ 1282opcode saturate, a, ak 1283 asig, ksat xin 1284 xout tanh(asig * ksat) / tanh(ksat) 1285endop 1286 1287;; SYNTHS 1288 1289xchnset("rvb.default", 0.1) 1290xchnset("drums.rvb.default", 0.1) 1291 1292/** Substractive Synth, 3osc */ 1293instr Sub1 1294 asig = vco2(ampdbfs(-12), p4) 1295 asig += vco2(ampdbfs(-12), p4 * 1.01, 10) 1296 asig += vco2(ampdbfs(-12), p4 * 2, 10) 1297 asig = zdf_ladder(asig, expon(10000, p3, 400), 5) 1298 asig = declick(asig) * p5 1299 pan_verb_mix(asig, xchan:i("Sub1.pan", 0.5), xchan:i("Sub1.rvb", chnget:i("rvb.default"))) 1300endin 1301 1302 1303/** Subtractive Synth, two saws, fifth freq apart */ 1304instr Sub2 1305 icut = xchan:i("Sub2.cut", sr / 3) 1306 asig = vco2(ampdbfs(-12), p4) 1307 asig += vco2(ampdbfs(-12), p4 * 1.5) 1308 asig = zdf_ladder(asig, expon(icut, p3, 400), 5) 1309 asig = declick(asig) * p5 1310 pan_verb_mix(asig, xchan:i("Sub2.pan", 0.5), xchan:i("Sub2.rvb", chnget:i("rvb.default"))) 1311endin 1312 1313 1314/** Subtractive Synth, three detuned saws, swells in */ 1315instr Sub3 1316 asig = vco2(p5, p4) 1317 asig += vco2(p5, p4 * 1.01) 1318 asig += vco2(p5, p4 * 0.995) 1319 asig *= 0.33 1320 asig = zdf_ladder(asig, expon(100, p3, 22000), 12) 1321 asig = declick(asig) 1322 pan_verb_mix(asig, xchan:i("Sub3.pan", 0.5), xchan:i("Sub3.rvb", chnget:i("rvb.default"))) 1323endin 1324 1325/** Subtractive Synth, detuned square/saw, stabby. 1326 Nice as a lead in octave 2, nicely grungy in octave -2, -1 1327*/ 1328instr Sub4 1329 asig = vco2(0.5, p4 * 2) 1330 asig += vco2(0.5, p4 * 2.01, 10) 1331 asig += vco2(1, p4, 10) 1332 asig += vco2(1, p4 * 0.99) 1333 itarget = p4 * 2 1334 asig = zdf_ladder(asig, expseg(20000, 0.15, itarget, 0.1, itarget), 5) 1335 asig = declick(asig) * p5 * 0.15 1336 pan_verb_mix(asig, xchan:i("Sub4.pan", 0.5), xchan:i("Sub4.rvb", chnget:i("rvb.default"))) 1337endin 1338 1339 1340/** Subtractive Synth, detuned square/triangle */ 1341instr Sub5 1342 asig = vco2(0.5, p4, 10) 1343 asig += vco2(0.25, p4 * 2.0001, 12) 1344 asig = zdf_ladder(asig, expseg(10000, 0.1, 500, 0.1, 500), 2) 1345 asig = declick(asig) * p5 * 0.75 1346 pan_verb_mix(asig, xchan:i("Sub5.pan", 0.5), xchan:i("Sub5.rvb", chnget:i("rvb.default"))) 1347endin 1348 1349/** Subtractive Synth, saw, K35 filters */ 1350instr Sub6 1351 asig = vco2(p5, p4) 1352 1353 asig = K35_hpf(asig, limit:i(p4, 30, 16000), 1) 1354 asig = K35_lpf(asig, expseg:k(12000, p3, limit:i(p4 * 8, 30, 12000)), 2.5) 1355 1356 asig = saturate(asig, 4.5) 1357 asig *= p5 * 0.5 1358 1359 asig = declick(asig) 1360 1361 pan_verb_mix(asig, xchan:i("Sub6.pan", 0.5), xchan:i("Sub6.rvb", chnget:i("rvb.default"))) 1362endin 1363 1364/** Subtractive Synth, saw + tri, K35 filters */ 1365instr Sub7 1366 asig = vco2(p5, p4) 1367 asig += vco2(p5, p4 * 2, 4, 0.5) 1368 1369 asig = K35_hpf(asig, limit:i(p4, 30, 16000), 1) 1370 asig = K35_lpf(asig, expseg:k(12000, p3, limit:i(p4 * 8, 30, 12000)), 2.5) 1371 1372 asig = saturate(asig, 4.5) 1373 asig *= p5 * 0.3 1374 1375 asig = declick(asig) 1376 1377 pan_verb_mix(asig, xchan:i("Sub7.pan", 0.5), xchan:i("Sub7.rvb", chnget:i("rvb.default"))) 1378endin 1379 1380/** Subtractive Synth, square + saw + tri, diode ladder filter */ 1381instr Sub8 1382 asig = vco2(p5, p4, 10) 1383 asig += vco2(p5 * 0.5, p4 * 2) 1384 asig += vco2(p5 * 0.15, p4 * 3.5, 12) 1385 1386 aenv = expon:a(1, 0.15, 0.001) 1387 asig = saturate(asig, 10) 1388 asig = diode_ladder(asig, 4000 + aenv * 4000, 12) 1389 asig = zdf_2pole(asig, p5, 0.25, 1) 1390 asig *= linen:a(1, 0, p3, .001) * 0.5 1391 pan_verb_mix(asig, xchan:i("Sub8.pan", 0.5), xchan:i("Sub8.rvb", chnget:i("rvb.default"))) 1392endin 1393 1394/** SynthBrass subtractive synth */ 1395instr SynBrass 1396 ipch = p4 1397 1398 asig = vco2(0.25, ipch) 1399 asig += vco2(0.25, ipch * 2.00) 1400 asig = zdf_ladder(asig, expseg(12000, 0.25, 500, 0.05, 500), 4) 1401 asig = declick(asig * p5) 1402 1403 pan_verb_mix(asig, xchan:i("SynBrass.pan", 0.5), xchan:i("SynBrass.rvb", chnget:i("rvb.default"))) 1404endin 1405 1406/** Synth Harp subtracitve Synth */ 1407instr SynHarp 1408 1409 asig = vco2(p5, p4) 1410 asig += vco2(p5, p4 * 0.9993423423) 1411 asig += vco2(p5, p4 * 1.00093029423048) 1412 1413 ioct = octcps(p4) 1414 1415 asig = zdf_ladder(asig, cpsoct(limit(linseg:a(ioct + 4, 0.015, ioct + 2, 0.2, ioct), 4.25, 14)), 0.5) 1416 asig = zdf_2pole(asig, p4 * 0.5, 0.5, 1) 1417 1418 asig *= linen:a(1, 0.012, p3, 0.01) 1419 1420 pan_verb_mix(asig, xchan:i("SynHarp.pan", 0.5), xchan:i("SynHarp.rvb", chnget:i("rvb.default"))) 1421endin 1422 1423/** SuperSaw sound using 9 bandlimited saws (3 sets of detuned saws at octaves)*/ 1424instr SSaw 1425 asig = vco2(1, p4) 1426 asig += vco2(1, p4 * cent(9.04234)) 1427 asig += vco2(1, p4 * cent(-7.214342)) 1428 1429 asig += vco2(1, p4 * cent(1206.294143)) 1430 asig += vco2(1, p4 * cent(1193.732)) 1431 asig += vco2(1, p4 * cent(1200)) 1432 1433 asig += vco2(1, p4 * cent(2406.294143)) 1434 asig += vco2(1, p4 * cent(2393.732)) 1435 asig += vco2(1, p4 * cent(2400)) 1436 1437 asig *= 0.1 1438 icut = xchan:i("SSaw.cut", 16000) 1439 asig = zdf_ladder(asig, expseg(icut, p3 - 0.05, icut, 0.05, 200), 0.5) 1440 asig *= p5 1441 asig = declick(asig) 1442 1443 pan_verb_mix(asig, xchan:i("SSaw.pan", 0.5), xchan:i("SSaw.rvb", chnget:i("rvb.default"))) 1444endin 1445 1446/** Modal Synthesis Instrument: Percussive/organ-y sound */ 1447instr Mode1 1448 asig = mpulse(p5, 0) 1449 1450 asig1 = mode(asig, p4, p4 * 0.5) 1451 asig1 += mode(asig, p4 * 2, p4 * 0.25) 1452 asig1 += mode(asig, p4 * 4, p4 * 0.125) 1453 1454 asig = declick(asig1) 1455 1456 pan_verb_mix(asig, xchan:i("Mode1.pan", 0.5), xchan:i("Mode1.rvb", chnget:i("rvb.default"))) 1457endin 1458 1459/** Pluck sound using impulses, noise, and waveguides*/ 1460instr Plk 1461 asig = mpulse(p5, 1 / p4) 1462 asig += random:a(-0.1, 0.1) * expseg(p5, 0.02, 0.001, p3, 0.001) 1463 1464 aout wguide1 asig, 1/ p4, 10000, 0.8 1465 aout += wguide1(asig, 1/ (2 * p4), 12000, 0.6) 1466 1467 aout = K35_hpf(aout, p4, 0.5) 1468 aout = zdf_ladder(aout, expon(10000, p3, 100), 3) 1469 aout = dcblock2(aout) 1470 1471 asig = declick(aout) 1472 1473 pan_verb_mix(asig, xchan:i("Plk.pan", 0.5), xchan:i("Plk.rvb", chnget:i("rvb.default"))) 1474endin 1475 1476gi_organ1 = ftgen(0, 0, 65536, 10, 1, 0.5, 0.3, 0.2, 0.05, 0.015) 1477/** Wavetable Organ sound using additive synthesis */ 1478instr Organ1 1479 asig = oscili(p5, p4, gi_organ1) 1480 asig *= 0.5 1481 asig = declick(asig) 1482 1483 pan_verb_mix(asig, xchan:i("Organ1.pan", 0.5), xchan:i("Organ1.rvb", chnget:i("rvb.default"))) 1484endin 1485 1486/** Organ sound based on M1 Organ 2 patch */ 1487instr Organ2 1488 asig = vco2(1, p4, 4, 0.25) 1489 asig += vco2(0.8, p4 * 2, 12) 1490 asig += vco2(0.3, p4 * 3, 10) 1491 1492 icutStart = limit:i(xchan:i("Organ2.cut", 2000), 40, sr * 1/2) 1493 icutEnd = limit:i(xchan:i("Organ2.cutEnd", 500), 40, sr * 1/2) 1494 asig = zdf_ladder(asig, expseg(icutStart, 0.08, icutEnd, p3, icutEnd), 2) 1495 1496 asig *= p5 * 0.67 1497 asig = declick(asig) 1498 1499 pan_verb_mix(asig, xchan:i("Organ2.pan", 0.5), xchan:i("Organ2.rvb", chnget:i("rvb.default"))) 1500endin 1501 1502giorgan_claribel_flute = ftgen(0, 0, 65536, 10, 1, ampdbfs(-30), ampdbfs(-35), ampdbfs(-40), ampdbfs(-32), ampdbfs(-40), ampdbfs(-42)) 1503 1504/** Wavetable Organ using Flute 8' and Flute 4', wavetable based on Claribel Flute 1505 http://www.pykett.org.uk/the_tonal_structure_of_organ_flutes.htm */ 1506instr Organ3 1507 asig = oscili(p5, p4, giorgan_claribel_flute) 1508 asig += oscili(p5, p4 * 2, giorgan_claribel_flute) 1509 ;asig += oscili(p5, p4 * 0.5) 1510 1511 asig *= linen:a(1, .02, p3, .01) 1512 1513 pan_verb_mix(asig, xchan:i("Organ3.pan", 0.5), xchan:i("Organ3.rvb", chnget:i("rvb.default"))) 1514endin 1515 1516/** Subtractive Bass sound */ 1517 1518instr Bass 1519 1520 asig = vco2(p5, p4, 10) 1521 asig += vco2(p5 * 0.25, p4 * 0.9992342342, 10) 1522 asig += vco2(p5 * 0.5, p4 * 2.000234234) 1523 aenv = linseg:a(1, 0.2, 0.1, p3 - 0.2, 0) * 6 1524 asig = zdf_ladder(asig, cpsoct(5 + aenv), 4 ) 1525 1526 asig *= linen:a(0.7, 0, p3, 0.01) 1527 1528 pan_verb_mix(asig, xchan:i("Bass.pan", 0.5), xchan:i("Bass.rvb", chnget:i("rvb.default"))) 1529 1530endin 1531 1532/** MS20-style Bass Sound */ 1533 1534instr ms20_bass 1535 ipch = p4 1536 iamp = p5 1537 aenv = expseg(1000, 0.1, ipch * 2, p3 - .05, ipch * 2) 1538 1539 asig = vco2(1.0, ipch) 1540 asig = K35_hpf(asig, ipch, 5, 0, 1) 1541 asig = K35_lpf(asig, aenv, 8, 0, 1) 1542 1543 asig *= expon:a(iamp, p3, 0.0001) 1544 1545 pan_verb_mix(asig, xchan:i("ms20_bass.pan", 0.5), xchan:i("ms20_bass.rvb", chnget:i("rvb.default"))) 1546endin 1547 1548 1549/** VoxHumana Patch */ 1550 1551instr VoxHumana 1552 ipch = p4 1553 iamp = p5 1554 aenv = transegr:a(0, 0.453, 1, 1.0, 2.242, -1, 0) 1555 1556 klfo_pulse_width = lfo(0.125, 5.72, 1) 1557 klfo_saw = lfo(0.021, 5.04, 1) 1558 klfo_pulse = lfo(0.013, 3.5, 1) 1559 1560 asaw = vco2(iamp, ipch * (1 + klfo_saw)) 1561 apulse = vco2(iamp, ipch * (1.00004 + klfo_pulse), 2, 0.625 + klfo_pulse_width) 1562 1563 aout = sum(asaw, apulse) * 0.0625 * aenv 1564 1565 ikeyfollow = 1 + exp( (ipch - 50) / 10000) 1566 1567 aout = butterlp(aout, 1986 * ikeyfollow) 1568 1569 pan_verb_mix(aout, xchan:i("VoxHumana.pan", 0.5), xchan:i("VoxHumana.rvb", chnget:i("rvb.default"))) 1570endin 1571 1572/** FM 3:1 C:M ratio, 2->0.025 index, nice for bass */ 1573instr FM1 1574 icar = xchan("FM1.car", 1) 1575 imod = xchan("FM1.mod", 3) 1576 asig = foscili(p5, p4, icar, imod, expon(2, 0.2, 0.025)) 1577 asig = declick(asig) * 0.5 1578 pan_verb_mix(asig, xchan:i("FM1.pan", 0.5), xchan:i("FM1.rvb", chnget:i("rvb.default"))) 1579endin 1580 1581/** Filtered noise, exponential envelope */ 1582instr Noi 1583 p3 = max:i(p3, 0.4) 1584 asig = pinker() * p5 * expon(1, p3, 0.001) * 0.1 1585 1586 a1 = mode(asig, p4, 80) 1587 a2 = mode(asig, p4 * 2, 40) 1588 a3 = mode(asig, p4 * 3, 30) 1589 a4 = mode(asig, p4 * 4, 20) 1590 1591 asig sum a1, a2, a3, a4 1592 1593 asig = declick(asig) * 0.25 1594 1595 pan_verb_mix(asig, xchan:i("Noi.pan", 0.5), xchan:i("Noi.rvb", chnget:i("rvb.default"))) 1596endin 1597 1598 1599/** Wobble patched based on Jacob Joaquin's "Tempo-Synced Wobble Bass" */ 1600instr Wobble 1601 /*p3 = max:i(p3, 0.4) */ 1602 1603 itri = chnget:i("Wobble.triangle") 1604 if(itri == 0) then 1605 ;; unipolar triangle 1606 itri = ftgen(0, 0, 8192, -7, 0, 4096, 1, 4096, 0) 1607 chnset(itri, "Wobble.triangle") 1608 endif 1609 1610 ;; dur in ticks (16ths) for wobble lfo 1611 iticks = xchan("Wobble.ticks", 2) 1612 ;; modulation max 1613 imod = p4 * 8 1614 1615 klfo = oscili:k(1, 1 / ticks(iticks), itri) 1616 1617 asig = vco2(p5, p4 * 2.018) 1618 asig += vco2(p5, p4, 10) 1619 asig = zdf_ladder(asig, min:k(p4 + (imod * klfo), 22000), 12) 1620 asig *= expon(1, beats(16), 0.001) 1621 asig = declick(asig) 1622 pan_verb_mix(asig, xchan:i("Wobble.pan", 0.5), xchan:i("Wobble.rvb", chnget:i("rvb.default"))) 1623 1624endin 1625 1626/** Simple Sine-wave instrument with exponential envelope */ 1627instr Sine 1628 asig = oscili(p5, p4) 1629 asig *= expseg:a(0.1, 0.001, 1, 0.1, 0.001, p3, 0.001) 1630 pan_verb_mix(asig, xchan:i("Sine.pan", 0.5), xchan:i("Sine.rvb", chnget:i("rvb.default"))) 1631endin 1632 1633/** Simple Square-wave instrument with exponential envelope */ 1634instr Square 1635 asig = vco2(p5, p4, 10) 1636 asig *= expseg:a(0.1, 0.005, 1, 0.1, 0.001, p3, 0.001) 1637 pan_verb_mix(asig, xchan:i("Square.pan", 0.5), xchan:i("Square.rvb", chnget:i("rvb.default"))) 1638endin 1639 1640/** Simple Sawtooth-wave instrument with exponential envelope */ 1641instr Saw 1642 asig = vco2(p5, p4) 1643 asig *= expseg:a(0.1, 0.005, 1, 0.1, 0.001, p3, 0.001) 1644 pan_verb_mix(asig, xchan:i("Saw.pan", 0.5), xchan:i("Saw.rvb", chnget:i("rvb.default"))) 1645endin 1646 1647 1648;; SQUINE WAVE SYNTHS 1649 1650/** Squinewave Synth, 2 osc */ 1651instr Squine1 1652 asig squinewave a(p4), expon:a(.8, p3, .1), expon:a(.9, p3, .5), 0, 4 1653 a2 squinewave a(p4 * 1.0019234234), expseg:a(.8, p3, .6), a(0), 0, 4 1654 1655 asig = (asig + a2 * 0.05) * p5 * 0.5 1656 asig = butterhp(asig, p4) 1657 asig *= linen:a(1, .015, p3, .02) 1658 asig = dcblock2(asig) 1659 1660 pan_verb_mix(asig, xchan:i("Squine1.pan", 0.5), xchan:i("Squine1.rvb", chnget:i("rvb.default"))) 1661 1662endin 1663 1664gi_lc_sine = ftgen(0, 0, 65536, 10, 1) 1665 1666/** Formant Synth, buzz source, soprano ah formants */ 1667instr Form1 1668 iamp = p5 1669 ifreq = p4 1670 asig = buzz(1, ifreq * (1 + lfo(.003, 4)), (sr / 2) / ifreq, gi_lc_sine) 1671 1672 a1 = butterbp(asig, 800, 80) 1673 a2 = butterbp(asig * ampdbfs(-6), 1150, 90) 1674 a3 = butterbp(asig * ampdbfs(-32), 2900 , 120) 1675 a4 = butterbp(asig * ampdbfs(-20), 3900, 130) 1676 a5 = butterbp(asig * ampdbfs(-50), 4950, 140) 1677 1678 asig = a1 + a2 + a3 + a4 + a5 1679 asig *= 35 * iamp * adsr(0.05, 0, 1, 0.01) 1680 1681 pan_verb_mix(asig, xchan:i("Form1.pan", 0.5), xchan:i("Form1.rvb", chnget:i("rvb.default"))) 1682endin 1683 1684;; MONOPHONIC SYNTHS 1685 1686/** Monophone synth using sawtooth wave and 4pole lpf. Use "start("Mono") to run the monosynth, then use MonoNote instrument to play the instrument. */ 1687instr Mono 1688 asig = vco2(xchan:k("Mono.amp", 0.0), portk(xchan:k("Mono.freq", 60), xchan:k("Mono.glide", 0.02))) 1689 asig = zdf_ladder(asig, xchan:k("Mono.cut", 4000), xchan:k("Mono.Q", 10)) 1690 1691 kpan = xchan:k("Mono.pan", 0.5) 1692 aL,aR pan2 asig,kpan 1693 1694 pan_verb_mix(asig, xchan:k("Mono.pan", 0.5), xchan:k("Mono.rvb", chnget:i("rvb.default"))) 1695endin 1696maxalloc("Mono", 1) 1697 1698/** Note playing instrument for Mono synth. Be careful to use this 1699and not try to create multiple Mono instruments! */ 1700instr MonoNote 1701 chnset(expon(p5, p3, 0.001), "Mono.amp") 1702 chnset(p4, "Mono.freq") 1703endin 1704 1705 1706;; DRUMS 1707 1708/** Bandpass-filtered impulse glitchy click sound. p4 = center frequency (e.g., 3000, 6000) */ 1709instr Click 1710 asig = mpulse(1, 0) 1711 asig = zdf_2pole(asig, p4, 3, 3) 1712 1713 asig *= p5 * 4 ;; adjust amp 1714 asig *= linen:a(1, 0, p3, 0.01) 1715 1716 pan_verb_mix(asig, xchan:i("Click.pan", 0.5), xchan:i("Click.rvb", chnget:i("rvb.default"))) 1717endin 1718 1719/** Highpass-filtered noise+saw sound. Use NoiSaw.cut channel to adjust cutoff. */ 1720instr NoiSaw 1721 asig = random:a(-1, 1) 1722 asig += vco2(1, 100) 1723 asig = zdf_2pole(asig, xchan:i("NoiSaw.cut", 3000), 1, 3) 1724 1725 asig *= p5 * 0.5 1726 asig *= expseg:a(1, 0.1, 0.001, p3, 0.0001) 1727 1728 asig *= linen:a(1, 0, p3, 0.01) 1729 1730 pan_verb_mix(asig, xchan:i("NoiSaw.pan", 0.5), xchan:i("NoiSaw.rvb", chnget:i("rvb.default"))) 1731endin 1732 1733/** Modified clap instrument by Istvan Varga (clap1.orc) */ 1734instr Clap 1735 ifreq = p4 ;; ignore 1736 iamp = p5 1737 1738 ibpfrq = 1046.5 /* bandpass filter frequency */ 1739 kbpbwd = port:k(ibpfrq*0.25, 0.03, ibpfrq*4.0) /* bandpass filter bandwidth */ 1740 idec = 0.5 /* decay time */ 1741 1742 a1 = 1.0 1743 a1_ delay1 a1 1744 a1 = a1 - a1_ 1745 a2 delay a1, 0.011 1746 a3 delay a1, 0.023 1747 a4 delay a1, 0.031 1748 1749 a1 tone a1, 60.0 1750 a2 tone a2, 60.0 1751 a3 tone a3, 60.0 1752 a4 tone a4, 1.0 / idec 1753 1754 aenv1 = a1 + a2 + a3 + a4*60.0*idec 1755 1756 a_ unirand 2.0 1757 a_ = aenv1 * (a_ - 1.0) 1758 a_ butterbp a_, ibpfrq, kbpbwd 1759 1760 aout = a_ * 80 * iamp ;; 1761 pan_verb_mix(aout, xchan:k("Clap.pan", 0.7), xchan:k("Clap.rvb", chnget:i("drums.rvb.default"))) 1762endin 1763 1764 1765 1766gi_808_sine ftgen 0,0,1024,10,1 ;A SINE WAVE 1767gi_808_cos ftgen 0,0,65536,9,1,1,90 ;A COSINE WAVE 1768 1769/** Bass Drum - From Iain McCurdy's TR-808.csd */ 1770instr BD ;BASS DRUM 1771 p3 = 2 * xchan("BD.decay", 0.5) ;NOTE DURATION. SCALED USING GUI 'Decay' KNOB 1772 1773 ilevel = xchan("BD.level", 1) * 2 1774 itune = xchan("BD.tune", 0) 1775 1776 ;SUSTAIN AND BODY OF THE SOUND 1777 kmul = transeg(0.2,p3*0.5,-15,0.01, p3*0.5,0,0) ;PARTIAL STRENGTHS MULTIPLIER USED BY GBUZZ. DECAYS FROM A SOUND WITH OVERTONES TO A SINE TONE. 1778 kbend = transeg(0.5,1.2,-4, 0,1,0,0) ;SLIGHT PITCH BEND AT THE START OF THE NOTE 1779 asig = gbuzz(0.5,50*octave(itune)*semitone(kbend),20,1,kmul,gi_808_cos) ;GBUZZ TONE 1780 aenv = transeg:a(1,p3-0.004,-6,0) ;AMPLITUDE ENVELOPE FOR SUSTAIN OF THE SOUND 1781 aatt = linseg:a(0,0.004,1, .01, 1) ;SOFT ATTACK 1782 asig= asig*aenv*aatt 1783 1784 ;HARD, SHORT ATTACK OF THE SOUND 1785 aenv = linseg:a(1,0.07,0, .01, 0) ;AMPLITUDE ENVELOPE (FAST DECAY) 1786 acps = expsega(400,0.07,0.001,1,0.001) ;FREQUENCY OF THE ATTACK SOUND. QUICKLY GLISSES FROM 400 Hz TO SUB-AUDIO 1787 aimp = oscili(aenv,acps*octave(itune*0.25),gi_808_sine) ;CREATE ATTACK SOUND 1788 1789 amix = ((asig*0.5)+(aimp*0.35))*ilevel*p5 ;MIX SUSTAIN AND ATTACK SOUND ELEMENTS AND SCALE USING GUI 'Level' KNOB 1790 1791 pan_verb_mix(amix, xchan:k("BD.pan", 0.5), xchan:k("BD.rvb", chnget:i("drums.rvb.default"))) 1792endin 1793 1794 1795/** Snare Drum - From Iain McCurdy's TR-808.csd */ 1796instr SD ;SNARE DRUM 1797 1798 ;SOUND CONSISTS OF TWO SINE TONES, AN OCTAVE APART AND A NOISE SIGNAL 1799 idur = xchan("SD.decay", 1.0) 1800 ilevel = xchan("SD.level", 1) 1801 itune = xchan("SD.tune", 0) 1802 1803 ifrq = 342 ;FREQUENCY OF THE TONES 1804 iNseDur = 0.3 * idur ;DURATION OF THE NOISE COMPONENT 1805 iPchDur = 0.1 * idur ;DURATION OF THE SINE TONES COMPONENT 1806 p3 = iNseDur ;p3 DURATION TAKEN FROM NOISE COMPONENT DURATION (ALWATS THE LONGEST COMPONENT) 1807 1808 ;SINE TONES COMPONENT 1809 aenv1 = expseg(1, iPchDur, 0.0001, p3-iPchDur, 0.0001) ;AMPLITUDE ENVELOPE 1810 apitch1 = oscili(1, ifrq * octave(itune), gi_808_sine) ;SINE TONE 1 1811 apitch2 = oscili(0.25, ifrq * 0.5 * octave(itune), gi_808_sine) ;SINE TONE 2 (AN OCTAVE LOWER) 1812 apitch = (apitch1+apitch2)*0.75 ;MIX THE TWO SINE TONES 1813 1814 ;NOISE COMPONENT 1815 aenv2 = expon(1,p3,0.0005) ;AMPLITUDE ENVELOPE 1816 anoise = noise(0.75, 0) ;CREATE SOME NOISE 1817 anoise = butbp(anoise, 10000*octave(itune), 10000) ;BANDPASS FILTER THE NOISE SIGNAL 1818 anoise = buthp(anoise, 1000) ;HIGHPASS FILTER THE NOISE SIGNAL 1819 kcf = expseg(5000, 0.1, 3000, p3-0.2, 3000) ;CUTOFF FREQUENCY FOR A LOWPASS FILTER 1820 anoise = butlp(anoise,kcf) ;LOWPASS FILTER THE NOISE SIGNAL 1821 amix = ((apitch*aenv1)+(anoise*aenv2))*ilevel*p5 ;MIX AUDIO SIGNALS AND SCALE ACCORDING TO GUI 'Level' CONTROL 1822 1823 pan_verb_mix(amix, xchan:k("SD.pan", 0.5), xchan:k("SD.rvb", chnget:i("drums.rvb.default"))) 1824endin 1825 1826 1827/** Open High Hat - From Iain McCurdy's TR-808.csd */ 1828instr OHH ;OPEN HIGH HAT 1829 1830 idur = xchan("OHH.decay", 1.0) 1831 ilevel = xchan("OHH.level", 1) 1832 itune = xchan("OHH.tune", 0) 1833 ioct = octave:i(itune) 1834 1835 1836 kFrq1 = 296*ioct ;FREQUENCIES OF THE 6 OSCILLATORS 1837 kFrq2 = 285*ioct 1838 kFrq3 = 365*ioct 1839 kFrq4 = 348*ioct 1840 kFrq5 = 420*ioct 1841 kFrq6 = 835*ioct 1842 p3 = 0.5*idur ;DURATION OF THE NOTE 1843 1844 ;SOUND CONSISTS OF 6 PULSE OSCILLATORS MIXED WITH A NOISE COMPONENT 1845 ;PITCHED ELEMENT 1846 aenv linseg 1,p3-0.05,0.1,0.05,0 ;AMPLITUDE ENVELOPE FOR THE PULSE OSCILLATORS 1847 ipw = 0.25 ;PULSE WIDTH 1848 a1 vco2 0.5,kFrq1,2,ipw ;PULSE OSCILLATORS... 1849 a2 vco2 0.5,kFrq2,2,ipw 1850 a3 vco2 0.5,kFrq3,2,ipw 1851 a4 vco2 0.5,kFrq4,2,ipw 1852 a5 vco2 0.5,kFrq5,2,ipw 1853 a6 vco2 0.5,kFrq6,2,ipw 1854 amix sum a1,a2,a3,a4,a5,a6 ;MIX THE PULSE OSCILLATORS 1855 amix reson amix,5000*ioct,5000,1 ;BANDPASS FILTER THE MIXTURE 1856 amix buthp amix,5000 ;HIGHPASS FILTER THE SOUND... 1857 amix buthp amix,5000 ;...AND AGAIN 1858 amix = amix*aenv ;APPLY THE AMPLITUDE ENVELOPE 1859 1860 ;NOISE ELEMENT 1861 anoise noise 0.8,0 ;GENERATE SOME WHITE NOISE 1862 aenv linseg 1,p3-0.05,0.1,0.05,0 ;CREATE AN AMPLITUDE ENVELOPE 1863 kcf expseg 20000,0.7,9000,p3-0.1,9000 ;CREATE A CUTOFF FREQ. ENVELOPE 1864 anoise butlp anoise,kcf ;LOWPASS FILTER THE NOISE SIGNAL 1865 anoise buthp anoise,8000 ;HIGHPASS FILTER THE NOISE SIGNAL 1866 anoise = anoise*aenv ;APPLY THE AMPLITUDE ENVELOPE 1867 1868 ;MIX PULSE OSCILLATOR AND NOISE COMPONENTS 1869 amix = (amix+anoise)*ilevel*p5*0.55 1870 1871 pan_verb_mix(amix, xchan:k("OHH.pan", 0.5), xchan:k("OHH.rvb", chnget:i("drums.rvb.default"))) 1872endin 1873 1874 1875/** Closed High Hat - From Iain McCurdy's TR-808.csd */ 1876instr CHH ;CLOSED HIGH HAT 1877 idur = xchan("CHH.decay", 1.0) 1878 ilevel = xchan("CHH.level", 1) 1879 itune = xchan("CHH.tune", 0) 1880 ioct = octave:i(itune) 1881 1882 kFrq1 = 296*ioct ;FREQUENCIES OF THE 6 OSCILLATORS 1883 kFrq2 = 285*ioct 1884 kFrq3 = 365*ioct 1885 kFrq4 = 348*ioct 1886 kFrq5 = 420*ioct 1887 kFrq6 = 835*ioct 1888 idur = 0.088*idur ;DURATION OF THE NOTE 1889 p3 limit idur,0.1,10 ;LIMIT THE MINIMUM DURATION OF THE NOTE (VERY SHORT NOTES CAN RESULT IN THE INDICATOR LIGHT ON-OFF NOTE BEING TO0 SHORT) 1890 1891 iohh = nstrnum("OHH") 1892 iactive = active(iohh) ;SENSE ACTIVITY OF PREVIOUS INSTRUMENT (OPEN HIGH HAT) 1893 if iactive>0 then ;IF 'OPEN HIGH HAT' IS ACTIVE... 1894 turnoff2 iohh,0,0 ;TURN IT OFF (CLOSED HIGH HAT TAKES PRESIDENCE) 1895 endif 1896 1897 ;PITCHED ELEMENT 1898 aenv expsega 1,idur,0.001,1,0.001 ;AMPLITUDE ENVELOPE FOR THE PULSE OSCILLATORS 1899 ipw = 0.25 ;PULSE WIDTH 1900 a1 vco2 0.5,kFrq1,2,ipw ;PULSE OSCILLATORS... 1901 a2 vco2 0.5,kFrq2,2,ipw 1902 a3 vco2 0.5,kFrq3,2,ipw 1903 a4 vco2 0.5,kFrq4,2,ipw 1904 a5 vco2 0.5,kFrq5,2,ipw 1905 a6 vco2 0.5,kFrq6,2,ipw 1906 amix sum a1,a2,a3,a4,a5,a6 ;MIX THE PULSE OSCILLATORS 1907 amix reson amix,5000*ioct,5000,1 ;BANDPASS FILTER THE MIXTURE 1908 amix buthp amix,5000 ;HIGHPASS FILTER THE SOUND... 1909 amix buthp amix,5000 ;...AND AGAIN 1910 amix = amix*aenv ;APPLY THE AMPLITUDE ENVELOPE 1911 1912 ;NOISE ELEMENT 1913 anoise noise 0.8,0 ;GENERATE SOME WHITE NOISE 1914 aenv expsega 1,idur,0.001,1,0.001 ;CREATE AN AMPLITUDE ENVELOPE 1915 kcf expseg 20000,0.7,9000,idur-0.1,9000 ;CREATE A CUTOFF FREQ. ENVELOPE 1916 anoise butlp anoise,kcf ;LOWPASS FILTER THE NOISE SIGNAL 1917 anoise buthp anoise,8000 ;HIGHPASS FILTER THE NOISE SIGNAL 1918 anoise = anoise*aenv ;APPLY THE AMPLITUDE ENVELOPE 1919 1920 ;MIX PULSE OSCILLATOR AND NOISE COMPONENTS 1921 amix = (amix+anoise)*ilevel*p5*0.55 1922 1923 pan_verb_mix(amix, xchan:k("CHH.pan", 0.5), xchan:k("CHH.rvb", chnget:i("drums.rvb.default"))) 1924endin 1925 1926/** High Tom - From Iain McCurdy's TR-808.csd */ 1927instr HiTom ;HIGH TOM 1928 idur = xchan("HiTom.decay", 1.0) 1929 ilevel = xchan("HiTom.level", 1) 1930 itune = xchan("HiTom.tune", 0) 1931 ioct = octave:i(itune) 1932 1933 ifrq = 200 * ioct ;FREQUENCY 1934 p3 = 0.5 * idur ;DURATION OF THIS NOTE 1935 1936 ;SINE TONE SIGNAL 1937 aAmpEnv transeg 1,p3,-10,0.001 ;AMPLITUDE ENVELOPE FOR SINE TONE SIGNAL 1938 afmod expsega 5,0.125/ifrq,1,1,1 ;FREQUENCY MODULATION ENVELOPE. GIVES THE TONE MORE OF AN ATTACK. 1939 asig oscili -aAmpEnv*0.6,ifrq*afmod,gi_808_sine ;SINE TONE SIGNAL 1940 1941 ;NOISE SIGNAL 1942 aEnvNse transeg 1,p3,-6,0.001 ;AMPLITUDE ENVELOPE FOR NOISE SIGNAL 1943 anoise dust2 0.4, 8000 ;GENERATE NOISE SIGNAL 1944 anoise reson anoise,400*ioct,800,1 ;BANDPASS FILTER THE NOISE SIGNAL 1945 anoise buthp anoise,100*ioct ;HIGHPASS FILTER THE NOSIE SIGNAL 1946 anoise butlp anoise,1000*ioct ;LOWPASS FILTER THE NOISE SIGNAL 1947 anoise = anoise * aEnvNse ;SCALE NOISE SIGNAL WITH AMPLITUDE ENVELOPE 1948 1949 ;MIX THE TWO SOUND COMPONENTS 1950 amix = (asig + anoise)*ilevel*p5 1951 1952 pan_verb_mix(amix, xchan:k("HiTom.pan", 0.5), xchan:k("HiTom.rvb", chnget:i("drums.rvb.default"))) 1953endin 1954 1955/** Mid Tom - From Iain McCurdy's TR-808.csd */ 1956instr MidTom ;MID TOM 1957 idur = xchan("MidTom.decay", 1.0) 1958 ilevel = xchan("MidTom.level", 1) 1959 itune = xchan("MidTom.tune", 0) 1960 ioct = octave:i(itune) 1961 1962 ifrq = 133*ioct ;FREQUENCY 1963 p3 = 0.6 * idur ;DURATION OF THIS NOTE 1964 1965 ;SINE TONE SIGNAL 1966 aAmpEnv transeg 1,p3,-10,0.001 ;AMPLITUDE ENVELOPE FOR SINE TONE SIGNAL 1967 afmod expsega 5,0.125/ifrq,1,1,1 ;FREQUENCY MODULATION ENVELOPE. GIVES THE TONE MORE OF AN ATTACK. 1968 asig oscili -aAmpEnv*0.6,ifrq*afmod,gi_808_sine ;SINE TONE SIGNAL 1969 1970 ;NOISE SIGNAL 1971 aEnvNse transeg 1,p3,-6,0.001 ;AMPLITUDE ENVELOPE FOR NOISE SIGNAL 1972 anoise dust2 0.4, 8000 ;GENERATE NOISE SIGNAL 1973 anoise reson anoise, 400*ioct,800,1 ;BANDPASS FILTER THE NOISE SIGNAL 1974 anoise buthp anoise,100*ioct ;HIGHPASS FILTER THE NOSIE SIGNAL 1975 anoise butlp anoise,600*ioct ;LOWPASS FILTER THE NOISE SIGNAL 1976 anoise = anoise * aEnvNse ;SCALE NOISE SIGNAL WITH AMPLITUDE ENVELOPE 1977 1978 ;MIX THE TWO SOUND COMPONENTS 1979 amix = (asig + anoise)*ilevel*p5 1980 1981 pan_verb_mix(amix, xchan:k("MidTom.pan", 0.5), xchan:k("MidTom.rvb", chnget:i("drums.rvb.default"))) 1982endin 1983 1984/** Low Tom - From Iain McCurdy's TR-808.csd */ 1985instr LowTom ;LOW TOM 1986 idur = xchan("LowTom.decay", 1.0) 1987 ilevel = xchan("LowTom.level", 1) 1988 itune = xchan("LowTom.tune", 0) 1989 ioct = octave:i(itune) 1990 1991 ifrq = 90 * ioct ;FREQUENCY 1992 p3 = 0.7*idur ;DURATION OF THIS NOTE 1993 1994 ;SINE TONE SIGNAL 1995 aAmpEnv transeg 1,p3,-10,0.001 ;AMPLITUDE ENVELOPE FOR SINE TONE SIGNAL 1996 afmod expsega 5,0.125/ifrq,1,1,1 ;FREQUENCY MODULATION ENVELOPE. GIVES THE TONE MORE OF AN ATTACK. 1997 asig oscili -aAmpEnv*0.6,ifrq*afmod,gi_808_sine ;SINE TONE SIGNAL 1998 1999 ;NOISE SIGNAL 2000 aEnvNse transeg 1,p3,-6,0.001 ;AMPLITUDE ENVELOPE FOR NOISE SIGNAL 2001 anoise dust2 0.4, 8000 ;GENERATE NOISE SIGNAL 2002 anoise reson anoise,40*ioct,800,1 ;BANDPASS FILTER THE NOISE SIGNAL 2003 anoise buthp anoise,100*ioct ;HIGHPASS FILTER THE NOSIE SIGNAL 2004 anoise butlp anoise,600*ioct ;LOWPASS FILTER THE NOISE SIGNAL 2005 anoise = anoise * aEnvNse ;SCALE NOISE SIGNAL WITH AMPLITUDE ENVELOPE 2006 2007 ;MIX THE TWO SOUND COMPONENTS 2008 amix = (asig + anoise)*ilevel*p5 2009 2010 pan_verb_mix(amix, xchan:k("LowTom.pan", 0.5), xchan:k("LowTom.rvb", chnget:i("drums.rvb.default"))) 2011endin 2012 2013 2014 2015/** Cymbal - From Iain McCurdy's TR-808.csd */ 2016instr Cymbal ;CYMBAL 2017 idur = xchan("Cymbal.decay", 1.0) 2018 ilevel = xchan("Cymbal.level", 1) 2019 itune = xchan("Cymbal.tune", 0) 2020 ioct = octave:i(itune) 2021 2022 iFrq1 = 296*ioct ;FREQUENCIES OF THE 6 OSCILLATORS 2023 iFrq2 = 285*ioct 2024 iFrq3 = 365*ioct 2025 iFrq4 = 348*ioct 2026 iFrq5 = 420*ioct 2027 iFrq6 = 835*ioct 2028 p3 = 2*idur ;DURATION OF THE NOTE 2029 2030 ;SOUND CONSISTS OF 6 PULSE OSCILLATORS MIXED WITH A NOISE COMPONENT 2031 ;PITCHED ELEMENT 2032 aenv expon 1,p3,0.0001 ;AMPLITUDE ENVELOPE FOR THE PULSE OSCILLATORS 2033 ipw = 0.25 ;PULSE WIDTH 2034 a1 vco2 0.5,iFrq1,2,ipw ;PULSE OSCILLATORS... 2035 a2 vco2 0.5,iFrq2,2,ipw 2036 a3 vco2 0.5,iFrq3,2,ipw 2037 a4 vco2 0.5,iFrq4,2,ipw 2038 a5 vco2 0.5,iFrq5,2,ipw 2039 a6 vco2 0.5,iFrq6,2,ipw 2040 2041 amix sum a1,a2,a3,a4,a5,a6 ;MIX THE PULSE OSCILLATORS 2042 amix reson amix,5000 * ioct,5000,1 ;BANDPASS FILTER THE MIXTURE 2043 amix buthp amix,10000 ;HIGHPASS FILTER THE SOUND 2044 amix butlp amix,12000 ;LOWPASS FILTER THE SOUND... 2045 amix butlp amix,12000 ;AND AGAIN... 2046 amix = amix*aenv ;APPLY THE AMPLITUDE ENVELOPE 2047 2048 ;NOISE ELEMENT 2049 anoise noise 0.8,0 ;GENERATE SOME WHITE NOISE 2050 aenv expsega 1,0.3,0.07,p3-0.1,0.00001 ;CREATE AN AMPLITUDE ENVELOPE 2051 kcf expseg 14000,0.7,7000,p3-0.1,5000 ;CREATE A CUTOFF FREQ. ENVELOPE 2052 anoise butlp anoise,kcf ;LOWPASS FILTER THE NOISE SIGNAL 2053 anoise buthp anoise,8000 ;HIGHPASS FILTER THE NOISE SIGNAL 2054 anoise = anoise*aenv ;APPLY THE AMPLITUDE ENVELOPE 2055 2056 ;MIX PULSE OSCILLATOR AND NOISE COMPONENTS 2057 amix = (amix+anoise)*ilevel*p5*0.85 2058 2059 pan_verb_mix(amix, xchan:k("Cymbal.pan", 0.5), xchan:k("Cymbal.rvb", chnget:i("drums.rvb.default"))) 2060endin 2061 2062;WAVEFORM FOR TR808 RIMSHOT 2063giTR808RimShot ftgen 0,0,1024,10, 0.971,0.269,0.041,0.054,0.011,0.013,0.08,0.0065,0.005,0.004,0.003,0.003,0.002,0.002,0.002,0.002,0.002,0.001,0.001,0.001,0.001,0.001,0.002,0.001,0.001 2064 2065/** Rimshot - From Iain McCurdy's TR-808.csd */ 2066instr Rimshot ;RIM SHOT 2067 2068 idur = xchan("Rimshot.decay", 1.0) 2069 ilevel = xchan("Rimshot.level", 1) 2070 itune = xchan("Rimshot.tune", 0) 2071 2072 idur = 0.027*idur ;NOTE DURATION 2073 p3 limit idur,0.1,10 ;LIMIT THE MINIMUM DURATION OF THE NOTE (VERY SHORT NOTES CAN RESULT IN THE INDICATOR LIGHT ON-OFF NOTE BEING TO0 SHORT) 2074 2075 ;RING 2076 aenv1 expsega 1,idur,0.001,1,0.001 ;AMPLITUDE ENVELOPE FOR SUSTAIN ELEMENT OF SOUND 2077 ifrq1 = 1700*octave(itune) ;FREQUENCY OF SUSTAIN ELEMENT OF SOUND 2078 aring oscili 1,ifrq1,giTR808RimShot,0 ;CREATE SUSTAIN ELEMENT OF SOUND 2079 aring butbp aring,ifrq1,ifrq1*8 2080 aring = aring*(aenv1-0.001)*0.5 ;APPLY AMPLITUDE ENVELOPE 2081 2082 ;NOISE 2083 anoise noise 1,0 ;CREATE A NOISE SIGNAL 2084 aenv2 expsega 1, 0.002, 0.8, 0.005, 0.5, idur-0.002-0.005, 0.0001, 1, 0.0001 ;CREATE AMPLITUDE ENVELOPE 2085 anoise buthp anoise,800 ;HIGHPASS FILTER THE NOISE SOUND 2086 kcf expseg 4000,idur,20 ;CUTOFF FREQUENCY FUNCTION FOR LOWPASS FILTER 2087 anoise butlp anoise,kcf ;LOWPASS FILTER THE SOUND 2088 anoise = anoise*(aenv2-0.001) ;APPLY ENVELOPE TO NOISE SIGNAL 2089 2090 ;MIX 2091 amix = (aring+anoise)*ilevel*p5*0.8 2092 2093 pan_verb_mix(amix, xchan:k("Rimshot.pan", 0.5), xchan:k("Rimshot.rvb", chnget:i("drums.rvb.default"))) 2094endin 2095 2096 2097/** Claves - From Iain McCurdy's TR-808.csd */ 2098instr Claves 2099 idur = xchan("Claves.decay", 1.0) 2100 ilevel = xchan("Claves.level", 1) 2101 itune = xchan("Claves.tune", 0) 2102 2103 ifrq = 2500*octave(itune) ;FREQUENCY OF OSCILLATOR 2104 idur = 0.045 * idur ;DURATION OF THE NOTE 2105 p3 limit idur,0.1,10 ;LIMIT THE MINIMUM DURATION OF THE NOTE (VERY SHORT NOTES CAN RESULT IN THE INDICATOR LIGHT ON-OFF NOTE BEING TO0 SHORT) 2106 aenv expsega 1,idur,0.001,1,0.001 ;AMPLITUDE ENVELOPE 2107 afmod expsega 3,0.00005,1,1,1 ;FREQUENCY MODULATION ENVELOPE. GIVES THE SOUND A LITTLE MORE ATTACK. 2108 asig oscili -(aenv-0.001),ifrq*afmod,gi_808_sine,0 ;AUDIO OSCILLATOR 2109 asig = asig * 0.4 * ilevel * p5 ;RESCALE AMPLITUDE 2110 2111 pan_verb_mix(asig, xchan:k("Claves.pan", 0.5), xchan:k("Claves.rvb", chnget:i("drums.rvb.default"))) 2112endin 2113 2114 2115/** Cowbell - From Iain McCurdy's TR-808.csd */ 2116instr Cowbell 2117 idur = xchan("Cowbell.decay", 1.0) 2118 ilevel = xchan("Cowbell.level", 1) 2119 itune = xchan("Cowbell.tune", 0) 2120 2121 ifrq1 = 562 * octave(itune) ;FREQUENCIES OF THE TWO OSCILLATORS 2122 ifrq2 = 845 * octave(itune) ; 2123 ipw = 0.5 ;PULSE WIDTH OF THE OSCILLATOR 2124 ishp = -30 2125 idur = 0.7 ;NOTE DURATION 2126 p3 = 0.7*idur ;LIMIT THE MINIMUM DURATION OF THE NOTE (VERY SHORT NOTES CAN RESULT IN THE INDICATOR LIGHT ON-OFF NOTE BEING TO0 SHORT) 2127 ishape = -30 ;SHAPE OF THE CURVES IN THE AMPLITUDE ENVELOPE 2128 kenv1 transeg 1,p3*0.3,ishape,0.2, p3*0.7,ishape,0.2 ;FIRST AMPLITUDE ENVELOPE - PRINCIPALLY THE ATTACK OF THE NOTE 2129 kenv2 expon 1,p3,0.0005 ;SECOND AMPLITUDE ENVELOPE - THE SUSTAIN PORTION OF THE NOTE 2130 kenv = kenv1*kenv2 ;COMBINE THE TWO ENVELOPES 2131 itype = 2 ;WAVEFORM FOR VCO2 (2=PULSE) 2132 a1 vco2 0.65,ifrq1,itype,ipw ;CREATE THE TWO OSCILLATORS 2133 a2 vco2 0.65,ifrq2,itype,ipw 2134 amix = a1+a2 ;MIX THE TWO OSCILLATORS 2135 iLPF2 = 10000 ;LOWPASS FILTER RESTING FREQUENCY 2136 kcf expseg 12000,0.07,iLPF2,1,iLPF2 ;LOWPASS FILTER CUTOFF FREQUENCY ENVELOPE 2137 alpf butlp amix,kcf ;LOWPASS FILTER THE MIX OF THE TWO OSCILLATORS (CREATE A NEW SIGNAL) 2138 abpf reson amix, ifrq2, 25 ;BANDPASS FILTER THE MIX OF THE TWO OSCILLATORS (CREATE A NEW SIGNAL) 2139 amix dcblock2 (abpf*0.06*kenv1)+(alpf*0.5)+(amix*0.9) ;MIX ALL SIGNALS AND BLOCK DC OFFSET 2140 amix buthp amix,700 ;HIGHPASS FILTER THE MIX OF ALL SIGNALS 2141 amix = amix * 0.07 * kenv * p5 * ilevel ;RESCALE AMPLITUDE 2142 2143 pan_verb_mix(amix, xchan:k("Cowbell.pan", 0.5), xchan:k("Cowbell.rvb", chnget:i("drums.rvb.default"))) 2144endin 2145 2146/** Maraca - from Iain McCurdy's TR-808.csd */ 2147instr Maraca ;MARACA 2148 idur = xchan("Maraca.decay", 1.0) 2149 ilevel = xchan("Maraca.level", 1) 2150 itune = xchan("Maraca.tune", 0) 2151 ioct = octave:i(itune) 2152 2153 idur = 0.07*idur ;DURATION 3 2154 p3 limit idur,0.1,10 ;LIMIT THE MINIMUM DURATION OF THE NOTE (VERY SHORT NOTES CAN RESULT IN THE INDICATOR LIGHT ON-OFF NOTE BEING TO0 SHORT) 2155 iHPF limit 6000*ioct,20,sr/2 ;HIGHPASS FILTER FREQUENCY 2156 iLPF limit 12000*ioct,20,sr/3 ;LOWPASS FILTER FREQUENCY. (LIMIT MAXIMUM TO PREVENT OUT OF RANGE VALUES) 2157 ;AMPLITUDE ENVELOPE 2158 iBP1 = 0.4 ;BREAK-POINT 1 2159 iDur1 = 0.014*idur ;DURATION 1 2160 iBP2 = 1 ;BREAKPOINT 2 2161 iDur2 = 0.01 *idur ;DURATION 2 2162 iBP3 = 0.05 ;BREAKPOINT 3 2163 p3 limit idur,0.1,10 ;LIMIT THE MINIMUM DURATION OF THE NOTE (VERY SHORT NOTES CAN RESULT IN THE INDICATOR LIGHT ON-OFF NOTE BEING TO0 SHORT) 2164 aenv expsega iBP1,iDur1,iBP2,iDur2,iBP3 ;CREATE AMPLITUDE ENVELOPE 2165 anoise noise 0.75,0 ;CREATE A NOISE SIGNAL 2166 anoise buthp anoise,iHPF ;HIGHPASS FILTER THE SOUND 2167 anoise butlp anoise,iLPF ;LOWPASS FILTER THE SOUND 2168 anoise = anoise*aenv*p5*ilevel ;SCALE THE AMPLITUDE 2169 2170 pan_verb_mix(anoise, xchan:k("Maraca.pan", 0.5), xchan:k("Maraca.rvb", chnget:i("drums.rvb.default"))) 2171endin 2172 2173/** High Conga - From Iain McCurdy's TR-808.csd */ 2174instr HiConga ;HIGH CONGA 2175 idur = xchan("HiConga.decay", 1.0) 2176 ilevel = xchan("HiConga.level", 1) 2177 itune = xchan("HiConga.tune", 0) 2178 ioct = octave:i(itune) 2179 2180 ifrq = 420*ioct ;FREQUENCY OF NOTE 2181 p3 = 0.22*idur ;DURATION OF NOTE 2182 aenv transeg 0.7,1/ifrq,1,1,p3,-6,0.001 ;AMPLITUDE ENVELOPE 2183 afrq expsega ifrq*3,0.25/ifrq,ifrq,1,ifrq ;FREQUENCY ENVELOPE (CREATE A SHARPER ATTACK) 2184 asig oscili -aenv*0.25,afrq,gi_808_sine ;CREATE THE AUDIO OSCILLATOR 2185 asig = asig*p5*ilevel ;SCALE THE AMPLITUDE 2186 2187 pan_verb_mix(asig, xchan:k("HiConga.pan", 0.5), xchan:k("HiConga.rvb", chnget:i("drums.rvb.default"))) 2188endin 2189 2190/** Mid Conga - From Iain McCurdy's TR-808.csd */ 2191instr MidConga ;MID CONGA 2192 idur = xchan("MidConga.decay", 1.0) 2193 ilevel = xchan("MidConga.level", 1) 2194 itune = xchan("MidConga.tune", 0) 2195 ioct = octave:i(itune) 2196 2197 ifrq = 310*ioct ;FREQUENCY OF NOTE 2198 p3 = 0.33*idur ;DURATION OF NOTE 2199 aenv transeg 0.7,1/ifrq,1,1,p3,-6,0.001 ;AMPLITUDE ENVELOPE 2200 afrq expsega ifrq*3,0.25/ifrq,ifrq,1,ifrq ;FREQUENCY ENVELOPE (CREATE A SHARPER ATTACK) 2201 asig oscili -aenv*0.25,afrq,gi_808_sine ;CREATE THE AUDIO OSCILLATOR 2202 asig = asig*p5*ilevel ;SCALE THE AMPLITUDE 2203 2204 pan_verb_mix(asig, xchan:k("MidConga.pan", 0.5), xchan:k("MidConga.rvb", chnget:i("drums.rvb.default"))) 2205endin 2206 2207/** Low Conga - From Iain McCurdy's TR-808.csd */ 2208instr LowConga ;LOW CONGA 2209 idur = xchan("LowConga.decay", 1.0) 2210 ilevel = xchan("LowConga.level", 1) 2211 itune = xchan("LowConga.tune", 0) 2212 ioct = octave:i(itune) 2213 2214 ifrq = 227*ioct ;FREQUENCY OF NOTE 2215 p3 = 0.41*idur ;DURATION OF NOTE 2216 aenv transeg 0.7,1/ifrq,1,1,p3,-6,0.001 ;AMPLITUDE ENVELOPE 2217 afrq expsega ifrq*3,0.25/ifrq,ifrq,1,ifrq ;FREQUENCY ENVELOPE (CREATE A SHARPER ATTACK) 2218 asig oscili -aenv*0.25,afrq,gi_808_sine ;CREATE THE AUDIO OSCILLATOR 2219 asig = asig*p5*ilevel ;SCALE THE AMPLITUDE 2220 2221 pan_verb_mix(asig, xchan:k("LowConga.pan", 0.5), xchan:k("LowConga.rvb", chnget:i("drums.rvb.default"))) 2222endin 2223 2224;; INITIALIZATION OF SYSTEM 2225 2226start("Clock")