1 2 3global { 4 5 srate 48000; // DAT-quality 6 krate 2400; // 417 us 7 8 ksig bal; // position 9 10 11// routes vctone to mixer 12// 13// ---------- --------- 14// | | | |--> stereo 15// | vctone |-->--| mixer | audio 16// | | | |--> out 17// ---------- --------- 18 19 route (tonebus, vctone); 20 send(mixer; 2, 0.25; tonebus); 21 outchannels 2; // stereo 22 23} 24 25// 26// instr vctone 27// shaped sinewave 28// 29 30instr vctone (num) { 31 32 ivar atime; // attack time 33 ivar rtime; // release time 34 ivar attack; 35 ivar release; 36 ivar sustain; 37 38 ksig env; // envelope multiplier 39 40 imports ksig bend; // pitch bend 41 ksig numacc; // pitch bend state 42 ksig a; // oscil constant 43 ksig kinit; // first k pass flag 44 45 asig ainit; // first a pass flag 46 asig x, y; // state vector 47 48 // ********************** 49 // computed during i-pass 50 // ********************** 51 52 // envelope computation 53 54 atime = 0.3; // attack (sec) 55 rtime = 0.2; // decay (sec) 56 57 // envelope state 58 59 if (dur > atime + rtime) 60 { 61 attack = atime; 62 release = rtime; 63 sustain = dur - atime - rtime; 64 } 65 else 66 { 67 attack = dur/2; 68 release = dur/2; 69 sustain = 0; 70 } 71 72 // ********************** 73 // computed during k-pass 74 // ********************** 75 76 // computes envelope 77 78 env = kline(0, attack, 1, sustain, 79 1, release, 0); 80 81 // computes sine const 82 // does pitch bend 83 84 if ( !kinit || bend) 85 { 86 if (!kinit) 87 { 88 numacc = num; 89 kinit = 1; 90 } 91 if (bend) 92 { 93 numacc = numacc + bend; 94 bend = 0; 95 } 96 a = 2*sin(3.1415927* 97 cpsmidi(numacc)/s_rate); 98 } 99 100 // ********************** 101 // computed during a-pass 102 // ********************** 103 104 if (ainit == 0) 105 { 106 x = 0.5; 107 ainit = 1; 108 } 109 110 x = x - a*y; 111 y = y + a*x; 112 113 output(env*y); 114 115} 116 117// instr mixer 118// adds reverb, panning 119 120instr mixer (rt60, wetdry) { 121 122 ivar wet,dry; 123 imports ksig bal; 124 ksig pos[2]; 125 asig out[2]; 126 127 // ********************** 128 // computed during i-pass 129 // ********************** 130 131 wet = wetdry; 132 dry = 1 - wetdry; 133 134 // ********************** 135 // computed during k-pass 136 // ********************** 137 138 pos[0] = dry*(1 - bal); 139 pos[1] = dry*(bal); 140 141 // ********************** 142 // computed during a-pass 143 // ********************** 144 145 out = pos*input + 146 wet*reverb(input[0], rt60); 147 148 output(out); 149 150} 151