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