Synth.cpp
 All Data Structures Namespaces Files Functions Variables Macros
teensy.ino
Go to the documentation of this file.
1 #include <TimerOne.h>
2 
3 #include "synth.h"
4 #include "voice.h"
5 #include "tests.h"
6 
7 #define KEYBOARD 1
8 #define NUM_KEYS 11
10 
13 class ThreadSafeSynth : public Synth
14 {
15  void write_sample(void) {
16  cli();
18  sei();
19  }
20 };
21 
22 class FunctionKey : public Key
23 {
24  void keyup(void) { /* nada */ }
25  void keydown(void) {
26  switch (id) {
27  case 8:
28  if (keyboard[9].state && keyboard[10].state) {
29  run_tests();
30  Serial.println("Tests done");
31  return;
32  }
33  s.quiet();
34  cli();
35  use_synth(&s);
36  sei();
37  break;
38  case 9:
39  s2.quiet();
40  cli();
41  use_synth(&s2);
42  sei();
43  break;
44  case 10:
45  s3.quiet();
46  cli();
47  use_synth(&s3);
48  sei();
49  break;
50  }
51  }
52 };
53 
54 Key *keyboard[NUM_KEYS];
57 
58 int8_t pitches[] = { 0, 2, 4, 5, 7, 9, 11, 12 };
59 extern uint32_t tune[];
60 uint32_t start_time;
61 uint32_t tune_pointer;
62 
68 void timer_interrupt(void)
69 {
70  static uint8_t led_time;
71  uint32_t x;
72  if (get_synth()->get_sample(&x) == 0) {
73  analogWrite(A14, x);
74  } else {
75  led_time = 100;
76  }
77  if (led_time > 0) {
78  led_time--;
79  digitalWrite(LED_BUILTIN, HIGH);
80  } else {
81  digitalWrite(LED_BUILTIN, LOW);
82  }
83 }
84 
91 uint8_t read_key(uint32_t id)
92 {
93  return (digitalReadFast(id) == LOW);
94 }
95 
106 void setup() {
107  uint8_t i;
108  start_time = micros();
109  tune_pointer = 0;
110  /*
111  * The more complicated a voice is, the less polyphony is possible.
112  * There are two ways to address this. One is to lower the sampling
113  * rate (which adversely impacts sound quality), and speeding up the
114  * code. That means doing a lot of profiling (best done with a GPIO
115  * pin and an oscilloscope in this situation) possibly followed by
116  * tighter C++ code and possibly some assembly language.
117  */
118 #define NUM_NOISY_VOICES 4
119 #define NUM_SIMPLE_VOICES 14
120 #define NUM_SQUARE_VOICES 8
121  synth_ary[0] = &s;
122  synth_ary[1] = &s2;
123  synth_ary[2] = &s3;
124  for (i = 0; i < NUM_NOISY_VOICES; i++)
125  s.add(new NoisyVoice());
126  for (i = 0; i < NUM_SIMPLE_VOICES; i++)
127  s2.add(new SimpleVoice());
128  for (i = 0; i < NUM_SQUARE_VOICES; i++)
129  s3.add(new TwoSquaresVoice());
130  s.quiet();
131  use_synth_array(synth_ary, 3);
132  use_synth(0);
133  analogWriteResolution(12);
134  Timer1.initialize((int) (1000000 * DT));
135  Timer1.attachInterrupt(timer_interrupt);
136  pinMode(0, INPUT_PULLUP);
137  pinMode(1, INPUT_PULLUP);
138  pinMode(2, INPUT_PULLUP);
139  pinMode(3, INPUT_PULLUP);
140  pinMode(4, INPUT_PULLUP);
141  pinMode(5, INPUT_PULLUP);
142  pinMode(6, INPUT_PULLUP);
143  pinMode(7, INPUT_PULLUP);
144  pinMode(8, INPUT_PULLUP);
145  pinMode(9, INPUT_PULLUP);
146  pinMode(10, INPUT_PULLUP);
147  pinMode(LED_BUILTIN, OUTPUT);
148 
149  for (i = 0; i < NUM_KEYS - 3; i++) {
150  keyboard[i] = new Key();
151  keyboard[i]->id = i;
152  keyboard[i]->pitch = ((int8_t*) &pitches)[i];
153  }
154  for ( ; i < NUM_KEYS; i++) {
155  keyboard[i] = new FunctionKey();
156  keyboard[i]->id = i;
157  keyboard[i]->pitch = 0;
158  }
159 }
160 
164 void loop(void) {
165  int i;
166 #if KEYBOARD
167  for (i = 0; i < NUM_KEYS; i++)
168  keyboard[i]->check();
169 #else
170  uint32_t msecs = (micros() - start_time) / 1000;
171  if (play_tune(tune, msecs)) {
172  start_time = micros();
173  }
174 #endif
175  for (i = 0; i < 64; i++)
177 }
Definition: synth.h:58
Definition: synth.h:126
uint32_t id
Definition: synth.h:283
ThreadSafeSynth s
Definition: teensy.ino:55
ThreadSafeSynth s2
Definition: teensy.ino:55
uint32_t start_time
Definition: teensy.ino:60
#define DT
Definition: synth.h:25
void setup()
Definition: teensy.ino:106
void write_sample(void)
Definition: synth.h:162
#define NUM_KEYS
Definition: teensy.ino:8
#define NUM_SIMPLE_VOICES
int8_t pitches[]
Definition: teensy.ino:58
void add(IVoice *voice)
Definition: synth.h:146
ISynth * get_synth(void)
Definition: synth.cpp:34
void use_synth_array(ISynth **s, uint8_t _num_synths)
Definition: synth.cpp:39
uint8_t read_key(uint32_t id)
Definition: teensy.ino:91
uint32_t state
Definition: synth.h:287
void keydown(void)
Definition: teensy.ino:25
uint32_t tune[]
Definition: tune.cpp:3
uint8_t play_tune(uint32_t *tune, uint32_t msecs)
Definition: synth.cpp:51
void keyup(void)
Definition: teensy.ino:24
ISynth * synth_ary[3]
Definition: teensy.ino:56
int8_t run_tests(void)
Definition: tests.cpp:24
void write_sample(void)
Definition: teensy.ino:15
Definition: synth.h:278
Key * keyboard[NUM_KEYS]
Definition: teensy.ino:9
virtual void compute_sample(void)=0
void use_synth(uint8_t i)
Definition: synth.cpp:29
void quiet(void)
Definition: synth.cpp:114
#define NUM_SQUARE_VOICES
ThreadSafeSynth s3
Definition: teensy.ino:55
Synthesizer modules and supporting functions.
int8_t pitch
Definition: synth.h:295
#define NUM_NOISY_VOICES
void timer_interrupt(void)
Definition: teensy.ino:68
uint32_t tune_pointer
Definition: teensy.ino:61
void loop(void)
Definition: teensy.ino:164