Synth.cpp
 All Data Structures Namespaces Files Functions Variables Macros
synth.cpp
Go to the documentation of this file.
1 #if ! __ARM
2 #include <stdio.h>
3 #endif
4 #include <math.h>
5 
6 #include "synth.h"
7 
8 #define GOAL (0.95 * (1 << 28))
9 
10 /* 1 / (1 - 1/e), because exponential */
11 #define BIGGER (1.5819767 * (1 << 28))
12 
13 #define RARE 500
14 
15 #define NOT_TOO_SMALL(x) MAX(x, 0.01)
16 
17 #define KEYDOWN_HYSTERESIS 10
18 
19 ISynth **_synth_ary = NULL;
20 ISynth *_synth = NULL;
21 uint8_t num_synths = 0;
22 uint8_t (*_read_key)(uint32_t) = NULL;
23 
24 void use_read_key(uint8_t (*rk)(uint32_t))
25 {
26  _read_key = rk;
27 }
28 
29 void use_synth(uint8_t i)
30 {
31  _synth = _synth_ary[i % num_synths];
32 }
33 
35 {
36  return _synth;
37 }
38 
39 void use_synth_array(ISynth **s, uint8_t _num_synths)
40 {
41  _synth_ary = s;
42  num_synths = _num_synths;
43 }
44 
45 float small_random() {
46  return -2.0 + 0.01 * (rand() % 400);
47 }
48 
49 static int tune_pointer = 0;
50 
51 uint8_t play_tune(uint32_t *tune, uint32_t msecs)
52 {
53  while (1) {
54  uint32_t t = tune[tune_pointer++];
55  if (t > msecs) {
56  tune_pointer--;
57  return 0;
58  }
59  uint32_t type = tune[tune_pointer++];
60  uint32_t param = tune[tune_pointer++];
61  uint32_t value = tune[tune_pointer++];
62  switch (type) {
63  case 0:
64  tune_pointer = 0;
65  return 1;
66  break;
67  case 1:
68  // keydown
69  get_synth()->keydown((int32_t)param - 50);
70  break;
71  case 2:
72  // keyup
73  get_synth()->keyup((int32_t)param - 50);
74  break;
75  case 3:
76  // voice change
77  use_synth(param);
78  break;
79  default:
80  get_synth()->ioctl(param, value);
81  break;
82  }
83  }
84 }
85 
86 void assertion(int cond, const char *strcond,
87  const char *file, const int line)
88 {
89 #if ! __ARM
90  if (!cond) {
91  fprintf(stderr,
92  "%s(%d) ASSERTION FAILED: %s\n",
93  file, line, strcond);
94  exit(1);
95  }
96 #endif
97 }
98 
99 
100 uint8_t Queue::read(uint32_t *x) {
101  if (empty()) return 1;
102  *x = buffer[rpointer];
103  rpointer = (rpointer + 1) & (BUFSIZE - 1);
104  return 0;
105 }
106 
107 uint8_t Queue::write(uint32_t x) {
108  if (full()) return 1;
109  buffer[wpointer] = x;
110  wpointer = (wpointer + 1) & (BUFSIZE - 1);
111  return 0;
112 }
113 
114 void Synth::quiet(void) {
115  uint8_t i;
116  for (i = 0; i < 100; i++)
117  assignments[i] = NULL;
118  for (i = 0; i < num_voices; i++)
119  voices[i]->quiet();
121 }
122 
123 void Synth::keydown(int8_t pitch) {
124  IVoice *v = assignments[pitch + 50];
125  if (v != NULL) {
126  // we already have a voice for this pitch
127  if (!v->idle())
128  // it's already active, no keydown needed
129  return;
130  } else {
131  v = get_next_available_voice(pitch);
132  v->setfreq(261.6255653f * pow(1.059463094359f, pitch));
133  }
134  v->keydown();
135 }
136 
137 void Synth::keyup(int8_t pitch) {
138  IVoice *v = assignments[pitch + 50];
139  if (v != NULL) {
140  v->keyup();
141  assignments[pitch + 50] = NULL;
142  }
143 }
144 
146  if (!again) {
147  uint8_t i;
148  for(i = 0; i < num_voices; ++i){
149  voices[i]->step();
150  }
151  x = get_12_bit_value();
152  }
153  write_sample();
154 }
155 
157 {
158  uint8_t i, n = 255 / num_voices;
159  int32_t x = 0;
160  for(i = 0; i < num_voices; ++i){
161  x += voices[i]->output();
162  }
163  x = (x * n) >> 8;
164  ASSERT(x < 0x800);
165  ASSERT(x >= -0x800);
166  return (x + 0x800) & 0xFFF;
167 }
168 
170  uint32_t i, j, found;
171  int32_t n;
172  IVoice *v;
173  // Look for the least recently used voice whose state is zero.
175  for (j = 0, found = 0; j < num_voices; j++) {
176  if (voices[i]->idle()) {
177  found = 1;
178  break;
179  }
180  // wrap aropund
181  if (++i == num_voices) i = 0;
182  }
183  // If none is found, just grab the least recently used voice.
184  if (found)
185  v = voices[i];
186  else
188  ASSERT(v != NULL);
189 
191  if (next_voice_to_assign == num_voices) {
192  // wrap aropund
194  }
195 
196  // does some other key already have this voice? If so, remove
197  // the voice from that other key
198  for (n = -50; n < 50; n++) {
199  IVoice *old_voice = assignments[n + 50];
200  if (pitch != n && old_voice == v) {
201  assignments[n + 50] = NULL;
202  break;
203  }
204  }
205  assignments[pitch + 50] = v;
206  return v;
207 }
208 
209 
210 void ADSR::rare_step(void) {
211  // Done rarely, so float arithmetic OK here
212  float next_value, h;
213  switch (_state) {
214  case 1:
215  h = exp(-RARE * DT / attack);
216  next_value = h * _value + (1.0 - h) * BIGGER;
217  if (next_value > GOAL) {
218  _state = 2;
219  next_value = GOAL;
220  }
221  break;
222  case 2:
223  h = exp(-RARE * DT / decay);
224  next_value = h * _value + (1.0 - h) * sustain;
225  break;
226  default:
227  case 0:
228  h = exp(-RARE * DT / release);
229  next_value = h * _value;
230  if (next_value < 1)
231  next_value = 0;
232  break;
233  }
234  dvalue = (next_value - _value) / RARE;
235 }
236 
237 void ADSR::setA(float a) {
238  attack = NOT_TOO_SMALL(a);
239 }
240 
241 void ADSR::setD(float d) {
242  decay = NOT_TOO_SMALL(d);
243 }
244 
245 void ADSR::setS(float s) {
246  sustain = GOAL * s;
247 }
248 
249 void ADSR::setR(float r) {
250  release = NOT_TOO_SMALL(r);
251 }
252 
253 void ADSR::keydown(void) {
254  _state = 1;
255  count = 0;
256 }
257 
258 void ADSR::keyup(void) {
259  _state = 0;
260 }
261 
262 void ADSR::step(void) {
263  if (count == 0) {
264  rare_step();
265  }
266  count = (count + 1) % RARE;
267  _value += dvalue;
268 }
269 
270 int32_t Oscillator::output(void) {
271  switch (waveform) {
272  default:
273  case 0:
274  // ramp
275  if (phase < 0x80000000) return (((int32_t) phase) >> 20);
276  else return (((int32_t) phase) >> 20) - 4096;
277  break;
278  case 1:
279  // triangle
280  switch (phase >> 30) {
281  case 0:
282  return (phase >> 19);
283  case 1:
284  return -(phase >> 19) + 4096;
285  case 2:
286  return -(phase >> 19) + 4096;
287  default:
288  return (phase >> 19) - 8192;
289  }
290  break;
291  case 2:
292  // square
293  if (phase == 0) return 0;
294  if (phase < 0x80000000) return 0x7ff;
295  return -0x800;
296  break;
297  }
298 }
299 
301  // k needs to scale with frequeuncy
302  two_k = (2 * _k * _f) >> 12;
303 }
304 
305 void Filter::setF(uint32_t f) {
306  const int32_t m = 6 * 3.1415926 * (1 << 20) * DT;
307  _f = f;
308  w0dt = m * f;
309  compute_two_k();
310 }
311 
312 void Filter::setQ(float q) {
313  const float kmin = 0.1;
314  float _fk;
315  _fk = 1.0 / q;
316  if (_fk < kmin) _fk = kmin; // stability
317  _k = _fk * (1 << 16);
318  compute_two_k();
319 }
320 
321 void Filter::step(int32_t x) {
322  int32_t y = x >> 2;
323  y -= (two_k * integrator1) >> 12;
324  y -= integrator2;
325  integrator2 = clip(integrator2 + ((w0dt * integrator1) >> 20));
326  integrator1 = clip(integrator1 + ((w0dt * u) >> 20));
327  u = clip(y);
328 }
329 
330 void Key::check(void) {
331  if (_read_key != NULL && _read_key(id)) {
332  if (state) {
333  count = 0;
334  } else {
335  if (count < KEYDOWN_HYSTERESIS) {
336  count++;
337  if (count == KEYDOWN_HYSTERESIS) {
338  state = 1;
339  count = 0;
340  keydown();
341  }
342  }
343  }
344  } else {
345  if (!state) {
346  count = 0;
347  } else {
348  if (count < KEYDOWN_HYSTERESIS) {
349  count++;
350  if (count == KEYDOWN_HYSTERESIS) {
351  state = 0;
352  count = 0;
353  keyup();
354  }
355  }
356  }
357  }
358 }
359 
360 void Key::keydown(void) {
361  if (_synth != NULL) {
362  _synth->keydown(pitch);
363  }
364 }
365 
366 void Key::keyup(void) {
367  if (_synth != NULL) {
368  _synth->keyup(pitch);
369  }
370 }
void keydown(void)
Definition: synth.cpp:253
#define BIGGER
Definition: synth.cpp:11
IVoice * get_next_available_voice(int8_t pitch)
Definition: synth.cpp:169
#define ASSERT(cond)
Definition: synth.h:27
void rare_step(void)
Definition: synth.cpp:210
uint32_t count
Definition: synth.h:179
Definition: synth.h:58
tuple q
Definition: test.py:48
void compute_sample(void)
Definition: synth.cpp:145
uint8_t read(uint32_t *x)
Definition: synth.cpp:100
def f
Definition: test.py:35
ISynth ** _synth_ary
Definition: synth.cpp:19
int32_t output(void)
Definition: synth.cpp:270
void step(void)
Definition: synth.cpp:262
uint32_t _value
Definition: synth.h:177
int32_t integrator2
Definition: synth.h:213
void setR(float r)
Definition: synth.cpp:249
float attack
Definition: synth.h:181
void compute_two_k(void)
Definition: synth.cpp:300
ThreadSafeSynth s
Definition: teensy.ino:55
#define DT
Definition: synth.h:25
int32_t w0dt
Definition: synth.h:213
float small_random()
Definition: synth.cpp:45
void write_sample(void)
Definition: synth.h:162
#define NOT_TOO_SMALL(x)
Definition: synth.cpp:15
virtual bool idle(void)=0
virtual void keyup(int8_t pitch)=0
void assertion(int cond, const char *strcond, const char *file, const int line)
Definition: synth.cpp:86
void setA(float a)
Definition: synth.cpp:237
virtual void keydown(int8_t pitch)=0
#define GOAL
Definition: synth.cpp:8
void setS(float s)
Definition: synth.cpp:245
uint32_t next_voice_to_assign
Definition: synth.h:129
int32_t two_k
Definition: synth.h:213
ISynth * get_synth(void)
Definition: synth.cpp:34
void setD(float d)
Definition: synth.cpp:241
uint32_t again
Definition: synth.h:132
void use_synth_array(ISynth **s, uint8_t _num_synths)
Definition: synth.cpp:39
uint32_t count
Definition: synth.h:291
Definition: synth.h:45
#define KEYDOWN_HYSTERESIS
Definition: synth.cpp:17
void keyup(void)
Definition: synth.cpp:258
uint32_t num_voices
Definition: synth.h:129
void setF(uint32_t f)
Definition: synth.cpp:305
virtual void keydown(void)=0
uint32_t state
Definition: synth.h:287
#define BUFSIZE
Definition: synth.h:36
uint32_t get_12_bit_value(void)
Definition: synth.cpp:156
int rpointer
Definition: synth.h:97
float decay
Definition: synth.h:181
uint32_t x
Definition: synth.h:132
int t
Definition: test.cpp:13
int wpointer
Definition: synth.h:97
uint8_t _state
Definition: synth.h:180
int32_t integrator1
Definition: synth.h:213
uint8_t num_synths
Definition: synth.cpp:21
int32_t _k
Definition: synth.h:213
IVoice * assignments[100]
Definition: synth.h:128
float sustain
Definition: synth.h:181
uint32_t tune[]
Definition: tune.cpp:3
int32_t clip(int32_t x)
Definition: synth.h:41
void step(int32_t x)
Definition: synth.cpp:321
static int tune_pointer
Definition: synth.cpp:49
uint8_t play_tune(uint32_t *tune, uint32_t msecs)
Definition: synth.cpp:51
int full(void)
Definition: synth.h:105
#define RARE
Definition: synth.cpp:13
uint32_t waveform
Definition: synth.h:250
virtual void step(void)=0
uint32_t buffer[BUFSIZE]
Definition: synth.h:98
void keyup(int8_t pitch)
Definition: synth.cpp:137
ISynth * _synth
Definition: synth.cpp:20
virtual void setfreq(float f)=0
int32_t _f
Definition: synth.h:213
virtual int32_t output(void)=0
uint8_t write(uint32_t x)
Definition: synth.cpp:107
int empty(void)
Definition: synth.h:102
void keydown(void)
Definition: synth.cpp:360
void use_read_key(uint8_t(*rk)(uint32_t))
Definition: synth.cpp:24
void use_synth(uint8_t i)
Definition: synth.cpp:29
float release
Definition: synth.h:181
void quiet(void)
Definition: synth.cpp:114
uint8_t(* _read_key)(uint32_t)
Definition: synth.cpp:22
uint32_t phase
Definition: synth.h:243
void check(void)
Definition: synth.cpp:330
void keydown(int8_t pitch)
Definition: synth.cpp:123
int32_t u
Definition: synth.h:213
int32_t dvalue
Definition: synth.h:178
IVoice * voices[32]
Definition: synth.h:127
Synthesizer modules and supporting functions.
void keyup(void)
Definition: synth.cpp:366
virtual void keyup(void)=0
virtual void ioctl(uint32_t, uint32_t)=0
int8_t pitch
Definition: synth.h:295
void setQ(float q)
Definition: synth.cpp:312