aboutsummaryrefslogtreecommitdiff
path: root/quantum/audio/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/audio/audio.c')
-rw-r--r--quantum/audio/audio.c766
1 files changed, 322 insertions, 444 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index e85370d95..3a7f0f556 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -1,6 +1,6 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <string.h> 2#include <string.h>
3#include <math.h> 3//#include <math.h>
4#include <avr/pgmspace.h> 4#include <avr/pgmspace.h>
5#include <avr/interrupt.h> 5#include <avr/interrupt.h>
6#include <avr/io.h> 6#include <avr/io.h>
@@ -10,30 +10,28 @@
10 10
11#include "eeconfig.h" 11#include "eeconfig.h"
12 12
13#ifdef VIBRATO_ENABLE 13#define CPU_PRESCALER 8
14 #include "vibrato_lut.h"
15#endif
16 14
17#define PI 3.14159265 15// -----------------------------------------------------------------------------
16// Timer Abstractions
17// -----------------------------------------------------------------------------
18 18
19#define CPU_PRESCALER 8 19// TIMSK3 - Timer/Counter #3 Interrupt Mask Register
20// Turn on/off 3A interputs, stopping/enabling the ISR calls
21#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
22#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
20 23
21#ifdef PWM_AUDIO 24// TCCR3A: Timer/Counter #3 Control Register
22 #include "wave.h" 25// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
23 #define SAMPLE_DIVIDER 39 26#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
24 #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) 27#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
25 // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
26 28
27 float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 29// Fast PWM Mode Controls
28 uint16_t place_int = 0; 30#define TIMER_3_PERIOD ICR3
29 bool repeat = true; 31#define TIMER_3_DUTY_CYCLE OCR3A
30#endif 32
33// -----------------------------------------------------------------------------
31 34
32void delay_us(int count) {
33 while(count--) {
34 _delay_us(1);
35 }
36}
37 35
38int voices = 0; 36int voices = 0;
39int voice_place = 0; 37int voice_place = 0;
@@ -45,26 +43,23 @@ float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
45int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 43int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
46bool sliding = false; 44bool sliding = false;
47 45
48int max = 0xFF;
49float sum = 0;
50float place = 0; 46float place = 0;
51 47
52uint8_t * sample; 48uint8_t * sample;
53uint16_t sample_length = 0; 49uint16_t sample_length = 0;
54// float freq = 0; 50
55 51bool playing_notes = false;
56bool notes = false; 52bool playing_note = false;
57bool note = false; 53float note_frequency = 0;
58float note_frequency = 0; 54float note_length = 0;
59float note_length = 0; 55uint8_t note_tempo = TEMPO_DEFAULT;
60float note_tempo = TEMPO_DEFAULT; 56float note_timbre = TIMBRE_DEFAULT;
61float note_timbre = TIMBRE_DEFAULT;
62uint16_t note_position = 0; 57uint16_t note_position = 0;
63float (* notes_pointer)[][2]; 58float (* notes_pointer)[][2];
64uint16_t notes_count; 59uint16_t notes_count;
65bool notes_repeat; 60bool notes_repeat;
66float notes_rest; 61float notes_rest;
67bool note_resting = false; 62bool note_resting = false;
68 63
69uint8_t current_note = 0; 64uint8_t current_note = 0;
70uint8_t rest_counter = 0; 65uint8_t rest_counter = 0;
@@ -77,175 +72,65 @@ float vibrato_rate = 0.125;
77 72
78float polyphony_rate = 0; 73float polyphony_rate = 0;
79 74
80bool inited = false; 75static bool audio_initialized = false;
81 76
82audio_config_t audio_config; 77audio_config_t audio_config;
83 78
84uint16_t envelope_index = 0; 79uint16_t envelope_index = 0;
85 80
86void audio_toggle(void) { 81void audio_init()
87 audio_config.enable ^= 1; 82{
88 eeconfig_update_audio(audio_config.raw);
89}
90
91void audio_on(void) {
92 audio_config.enable = 1;
93 eeconfig_update_audio(audio_config.raw);
94}
95
96void audio_off(void) {
97 audio_config.enable = 0;
98 eeconfig_update_audio(audio_config.raw);
99}
100
101#ifdef VIBRATO_ENABLE
102// Vibrato rate functions
103
104void set_vibrato_rate(float rate) {
105 vibrato_rate = rate;
106}
107
108void increase_vibrato_rate(float change) {
109 vibrato_rate *= change;
110}
111
112void decrease_vibrato_rate(float change) {
113 vibrato_rate /= change;
114}
115
116#ifdef VIBRATO_STRENGTH_ENABLE
117
118void set_vibrato_strength(float strength) {
119 vibrato_strength = strength;
120}
121
122void increase_vibrato_strength(float change) {
123 vibrato_strength *= change;
124}
125
126void decrease_vibrato_strength(float change) {
127 vibrato_strength /= change;
128}
129
130#endif
131
132#endif
133
134// Polyphony functions
135
136void set_polyphony_rate(float rate) {
137 polyphony_rate = rate;
138}
139
140void enable_polyphony() {
141 polyphony_rate = 5;
142}
143
144void disable_polyphony() {
145 polyphony_rate = 0;
146}
147
148void increase_polyphony_rate(float change) {
149 polyphony_rate *= change;
150}
151
152void decrease_polyphony_rate(float change) {
153 polyphony_rate /= change;
154}
155
156// Timbre function
157
158void set_timbre(float timbre) {
159 note_timbre = timbre;
160}
161
162// Tempo functions
163
164void set_tempo(float tempo) {
165 note_tempo = tempo;
166}
167
168void decrease_tempo(uint8_t tempo_change) {
169 note_tempo += (float) tempo_change;
170}
171
172void increase_tempo(uint8_t tempo_change) {
173 if (note_tempo - (float) tempo_change < 10) {
174 note_tempo = 10;
175 } else {
176 note_tempo -= (float) tempo_change;
177 }
178}
179
180void audio_init() {
181 83
182 /* check signature */ 84 // Check EEPROM
183 if (!eeconfig_is_enabled()) { 85 if (!eeconfig_is_enabled())
86 {
184 eeconfig_init(); 87 eeconfig_init();
185 } 88 }
186 audio_config.raw = eeconfig_read_audio(); 89 audio_config.raw = eeconfig_read_audio();
187 90
188 #ifdef PWM_AUDIO 91 // Set port PC6 (OC3A and /OC4A) as output
189 PLLFRQ = _BV(PDIV2); 92 DDRC |= _BV(PORTC6);
190 PLLCSR = _BV(PLLE);
191 while(!(PLLCSR & _BV(PLOCK)));
192 PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
193 93
194 /* Init a fast PWM on Timer4 */ 94 DISABLE_AUDIO_COUNTER_3_ISR;
195 TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
196 TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
197 OCR4A = 0;
198 95
199 /* Enable the OC4A output */ 96 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
200 DDRC |= _BV(PORTC6); 97 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
98 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
99 // Clock Select (CS3n) = 0b010 = Clock / 8
100 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
101 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
201 102
202 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs 103 audio_initialized = true;
203
204 TCCR3A = 0x0; // Options not needed
205 TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
206 OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
207 #else
208 DDRC |= _BV(PORTC6);
209
210 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
211
212 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
213 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
214 #endif
215
216 inited = true;
217} 104}
218 105
219void stop_all_notes() { 106void stop_all_notes()
220 if (!inited) { 107{
108 if (!audio_initialized) {
221 audio_init(); 109 audio_init();
222 } 110 }
223 voices = 0; 111 voices = 0;
224 #ifdef PWM_AUDIO 112
225 TIMSK3 &= ~_BV(OCIE3A); 113 DISABLE_AUDIO_COUNTER_3_ISR;
226 #else 114 DISABLE_AUDIO_COUNTER_3_OUTPUT;
227 TIMSK3 &= ~_BV(OCIE3A); 115
228 TCCR3A &= ~_BV(COM3A1); 116 playing_notes = false;
229 #endif 117 playing_note = false;
230 notes = false;
231 note = false;
232 frequency = 0; 118 frequency = 0;
233 volume = 0; 119 volume = 0;
234 120
235 for (int i = 0; i < 8; i++) { 121 for (uint8_t i = 0; i < 8; i++)
122 {
236 frequencies[i] = 0; 123 frequencies[i] = 0;
237 volumes[i] = 0; 124 volumes[i] = 0;
238 } 125 }
239} 126}
240 127
241void stop_note(float freq) { 128void stop_note(float freq)
242 if (note) { 129{
243 if (!inited) { 130 if (playing_note) {
131 if (!audio_initialized) {
244 audio_init(); 132 audio_init();
245 } 133 }
246 #ifdef PWM_AUDIO
247 freq = freq / SAMPLE_RATE;
248 #endif
249 for (int i = 7; i >= 0; i--) { 134 for (int i = 7; i >= 0; i--) {
250 if (frequencies[i] == freq) { 135 if (frequencies[i] == freq) {
251 frequencies[i] = 0; 136 frequencies[i] = 0;
@@ -266,15 +151,11 @@ void stop_note(float freq) {
266 voice_place = 0; 151 voice_place = 0;
267 } 152 }
268 if (voices == 0) { 153 if (voices == 0) {
269 #ifdef PWM_AUDIO 154 DISABLE_AUDIO_COUNTER_3_ISR;
270 TIMSK3 &= ~_BV(OCIE3A); 155 DISABLE_AUDIO_COUNTER_3_OUTPUT;
271 #else
272 TIMSK3 &= ~_BV(OCIE3A);
273 TCCR3A &= ~_BV(COM3A1);
274 #endif
275 frequency = 0; 156 frequency = 0;
276 volume = 0; 157 volume = 0;
277 note = false; 158 playing_note = false;
278 } 159 }
279 } 160 }
280} 161}
@@ -289,9 +170,9 @@ float mod(float a, int b)
289 170
290float vibrato(float average_freq) { 171float vibrato(float average_freq) {
291 #ifdef VIBRATO_STRENGTH_ENABLE 172 #ifdef VIBRATO_STRENGTH_ENABLE
292 float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); 173 float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
293 #else 174 #else
294 float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; 175 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
295 #endif 176 #endif
296 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); 177 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
297 return vibrated_freq; 178 return vibrated_freq;
@@ -299,295 +180,295 @@ float vibrato(float average_freq) {
299 180
300#endif 181#endif
301 182
302ISR(TIMER3_COMPA_vect) { 183ISR(TIMER3_COMPA_vect)
303 if (note) { 184{
304 #ifdef PWM_AUDIO 185 float freq;
305 if (voices == 1) { 186
306 // SINE 187 if (playing_note) {
307 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; 188 if (voices > 0) {
308 189 if (polyphony_rate > 0) {
309 // SQUARE 190 if (voices > 1) {
310 // if (((int)place) >= 1024){ 191 voice_place %= voices;
311 // OCR4A = 0xFF >> 2; 192 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
312 // } else { 193 voice_place = (voice_place + 1) % voices;
313 // OCR4A = 0x00; 194 place = 0.0;
314 // } 195 }
315 196 }
316 // SAWTOOTH 197
317 // OCR4A = (int)place / 4; 198 #ifdef VIBRATO_ENABLE
318 199 if (vibrato_strength > 0) {
319 // TRIANGLE 200 freq = vibrato(frequencies[voice_place]);
320 // if (((int)place) >= 1024) { 201 } else {
321 // OCR4A = (int)place / 2; 202 freq = frequencies[voice_place];
322 // } else { 203 }
323 // OCR4A = 2048 - (int)place / 2; 204 #else
324 // } 205 freq = frequencies[voice_place];
325 206 #endif
326 place += frequency; 207 } else {
327 208 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
328 if (place >= SINE_LENGTH) 209 frequency = frequency * pow(2, 440/frequency/12/2);
329 place -= SINE_LENGTH; 210 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
330 211 frequency = frequency * pow(2, -440/frequency/12/2);
331 } else { 212 } else {
332 int sum = 0; 213 frequency = frequencies[voices - 1];
333 for (int i = 0; i < voices; i++) { 214 }
334 // SINE 215
335 sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; 216 #ifdef VIBRATO_ENABLE
336 217 if (vibrato_strength > 0) {
337 // SQUARE 218 freq = vibrato(frequency);
338 // if (((int)places[i]) >= 1024){ 219 } else {
339 // sum += 0xFF >> 2; 220 freq = frequency;
340 // } else { 221 }
341 // sum += 0x00; 222 #else
342 // } 223 freq = frequency;
343 224 #endif
344 places[i] += frequencies[i]; 225 }
345 226
346 if (places[i] >= SINE_LENGTH) 227 if (envelope_index < 65535) {
347 places[i] -= SINE_LENGTH; 228 envelope_index++;
348 } 229 }
349 OCR4A = sum; 230
350 } 231 freq = voice_envelope(freq);
351 #else 232
352 if (voices > 0) { 233 if (freq < 30.517578125) {
353 float freq; 234 freq = 30.52;
354 if (polyphony_rate > 0) { 235 }
355 if (voices > 1) { 236
356 voice_place %= voices; 237 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
357 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { 238 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
358 voice_place = (voice_place + 1) % voices; 239 }
359 place = 0.0; 240 }
360 } 241
361 } 242 if (playing_notes) {
362 #ifdef VIBRATO_ENABLE 243 if (note_frequency > 0) {
363 if (vibrato_strength > 0) { 244 #ifdef VIBRATO_ENABLE
364 freq = vibrato(frequencies[voice_place]); 245 if (vibrato_strength > 0) {
365 } else { 246 freq = vibrato(note_frequency);
366 #else 247 } else {
367 { 248 freq = note_frequency;
368 #endif 249 }
369 freq = frequencies[voice_place]; 250 #else
370 } 251 freq = note_frequency;
371 } else { 252 #endif
372 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { 253
373 frequency = frequency * pow(2, 440/frequency/12/2); 254 if (envelope_index < 65535) {
374 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { 255 envelope_index++;
375 frequency = frequency * pow(2, -440/frequency/12/2); 256 }
376 } else { 257 freq = voice_envelope(freq);
377 frequency = frequencies[voices - 1]; 258
378 } 259 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
379 260 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
380 261 } else {
381 #ifdef VIBRATO_ENABLE 262 TIMER_3_PERIOD = 0;
382 if (vibrato_strength > 0) { 263 TIMER_3_DUTY_CYCLE = 0;
383 freq = vibrato(frequency); 264 }
384 } else { 265
385 #else 266 note_position++;
386 { 267 bool end_of_note = false;
387 #endif 268 if (TIMER_3_PERIOD > 0) {
388 freq = frequency; 269 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
389 } 270 } else {
390 } 271 end_of_note = (note_position >= (note_length * 0x7FF));
272 }
273
274 if (end_of_note) {
275 current_note++;
276 if (current_note >= notes_count) {
277 if (notes_repeat) {
278 current_note = 0;
279 } else {
280 DISABLE_AUDIO_COUNTER_3_ISR;
281 DISABLE_AUDIO_COUNTER_3_OUTPUT;
282 playing_notes = false;
283 return;
284 }
285 }
286 if (!note_resting && (notes_rest > 0)) {
287 note_resting = true;
288 note_frequency = 0;
289 note_length = notes_rest;
290 current_note--;
291 } else {
292 note_resting = false;
293 envelope_index = 0;
294 note_frequency = (*notes_pointer)[current_note][0];
295 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
296 }
297
298 note_position = 0;
299 }
300 }
301
302 if (!audio_config.enable) {
303 playing_notes = false;
304 playing_note = false;
305 }
306}
391 307
392 if (envelope_index < 65535) { 308void play_note(float freq, int vol) {
393 envelope_index++;
394 }
395 freq = voice_envelope(freq);
396 309
397 if (freq < 30.517578125) 310 if (!audio_initialized) {
398 freq = 30.52; 311 audio_init();
399 ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
400 OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
401 }
402 #endif
403 } 312 }
404 313
405 // SAMPLE 314 if (audio_config.enable && voices < 8) {
406 // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); 315 DISABLE_AUDIO_COUNTER_3_ISR;
407
408 // place_int++;
409
410 // if (place_int >= sample_length)
411 // if (repeat)
412 // place_int -= sample_length;
413 // else
414 // TIMSK3 &= ~_BV(OCIE3A);
415
416
417 if (notes) {
418 #ifdef PWM_AUDIO
419 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
420
421 place += note_frequency;
422 if (place >= SINE_LENGTH)
423 place -= SINE_LENGTH;
424 #else
425 if (note_frequency > 0) {
426 float freq;
427
428 #ifdef VIBRATO_ENABLE
429 if (vibrato_strength > 0) {
430 freq = vibrato(note_frequency);
431 } else {
432 #else
433 {
434 #endif
435 freq = note_frequency;
436 }
437 316
438 if (envelope_index < 65535) { 317 // Cancel notes if notes are playing
439 envelope_index++; 318 if (playing_notes)
440 } 319 stop_all_notes();
441 freq = voice_envelope(freq);
442 320
443 ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period 321 playing_note = true;
444 OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
445 } else {
446 ICR3 = 0;
447 OCR3A = 0;
448 }
449 #endif
450
451
452 note_position++;
453 bool end_of_note = false;
454 if (ICR3 > 0)
455 end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF));
456 else
457 end_of_note = (note_position >= (note_length * 0x7FF));
458 if (end_of_note) {
459 current_note++;
460 if (current_note >= notes_count) {
461 if (notes_repeat) {
462 current_note = 0;
463 } else {
464 #ifdef PWM_AUDIO
465 TIMSK3 &= ~_BV(OCIE3A);
466 #else
467 TIMSK3 &= ~_BV(OCIE3A);
468 TCCR3A &= ~_BV(COM3A1);
469 #endif
470 notes = false;
471 return;
472 }
473 }
474 if (!note_resting && (notes_rest > 0)) {
475 note_resting = true;
476 note_frequency = 0;
477 note_length = notes_rest;
478 current_note--;
479 } else {
480 note_resting = false;
481 #ifdef PWM_AUDIO
482 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
483 note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100);
484 #else
485 envelope_index = 0;
486 note_frequency = (*notes_pointer)[current_note][0];
487 note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100);
488 #endif
489 }
490 note_position = 0;
491 }
492 322
493 } 323 envelope_index = 0;
324
325 if (freq > 0) {
326 frequencies[voices] = freq;
327 volumes[voices] = vol;
328 voices++;
329 }
330
331 ENABLE_AUDIO_COUNTER_3_ISR;
332 ENABLE_AUDIO_COUNTER_3_OUTPUT;
333 }
494 334
495 if (!audio_config.enable) {
496 notes = false;
497 note = false;
498 }
499} 335}
500 336
501void play_note(float freq, int vol) { 337void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
338{
502 339
503 if (!inited) { 340 if (!audio_initialized) {
504 audio_init(); 341 audio_init();
505 } 342 }
506 343
507if (audio_config.enable && voices < 8) { 344 if (audio_config.enable) {
508 TIMSK3 &= ~_BV(OCIE3A); 345
509 // Cancel notes if notes are playing 346 DISABLE_AUDIO_COUNTER_3_ISR;
510 if (notes) 347
511 stop_all_notes(); 348 // Cancel note if a note is playing
512 note = true; 349 if (playing_note)
513 envelope_index = 0; 350 stop_all_notes();
514 #ifdef PWM_AUDIO 351
515 freq = freq / SAMPLE_RATE; 352 playing_notes = true;
516 #endif 353
517 if (freq > 0) { 354 notes_pointer = np;
518 frequencies[voices] = freq; 355 notes_count = n_count;
519 volumes[voices] = vol; 356 notes_repeat = n_repeat;
520 voices++; 357 notes_rest = n_rest;
521 } 358
359 place = 0;
360 current_note = 0;
361
362 note_frequency = (*notes_pointer)[current_note][0];
363 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
364 note_position = 0;
365
366
367 ENABLE_AUDIO_COUNTER_3_ISR;
368 ENABLE_AUDIO_COUNTER_3_OUTPUT;
369 }
522 370
523 #ifdef PWM_AUDIO
524 TIMSK3 |= _BV(OCIE3A);
525 #else
526 TIMSK3 |= _BV(OCIE3A);
527 TCCR3A |= _BV(COM3A1);
528 #endif
529} 371}
530 372
373bool is_playing_notes(void) {
374 return playing_notes;
531} 375}
532 376
533void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { 377void audio_toggle(void) {
378 audio_config.enable ^= 1;
379 eeconfig_update_audio(audio_config.raw);
380}
534 381
535 if (!inited) { 382void audio_on(void) {
536 audio_init(); 383 audio_config.enable = 1;
537 } 384 eeconfig_update_audio(audio_config.raw);
385}
538 386
539if (audio_config.enable) { 387void audio_off(void) {
540 TIMSK3 &= ~_BV(OCIE3A); 388 audio_config.enable = 0;
541 // Cancel note if a note is playing 389 eeconfig_update_audio(audio_config.raw);
542 if (note) 390}
543 stop_all_notes();
544 notes = true;
545
546 notes_pointer = np;
547 notes_count = n_count;
548 notes_repeat = n_repeat;
549 notes_rest = n_rest;
550
551 place = 0;
552 current_note = 0;
553 #ifdef PWM_AUDIO
554 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
555 note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100);
556 #else
557 note_frequency = (*notes_pointer)[current_note][0];
558 note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100);
559 #endif
560 note_position = 0;
561 391
392#ifdef VIBRATO_ENABLE
562 393
563 #ifdef PWM_AUDIO 394// Vibrato rate functions
564 TIMSK3 |= _BV(OCIE3A); 395
565 #else 396void set_vibrato_rate(float rate) {
566 TIMSK3 |= _BV(OCIE3A); 397 vibrato_rate = rate;
567 TCCR3A |= _BV(COM3A1);
568 #endif
569} 398}
570 399
400void increase_vibrato_rate(float change) {
401 vibrato_rate *= change;
571} 402}
572 403
573#ifdef PWM_AUDIO 404void decrease_vibrato_rate(float change) {
574void play_sample(uint8_t * s, uint16_t l, bool r) { 405 vibrato_rate /= change;
575 if (!inited) { 406}
576 audio_init();
577 }
578 407
579 if (audio_config.enable) { 408#ifdef VIBRATO_STRENGTH_ENABLE
580 TIMSK3 &= ~_BV(OCIE3A); 409
581 stop_all_notes(); 410void set_vibrato_strength(float strength) {
582 place_int = 0; 411 vibrato_strength = strength;
583 sample = s; 412}
584 sample_length = l; 413
585 repeat = r; 414void increase_vibrato_strength(float change) {
415 vibrato_strength *= change;
416}
417
418void decrease_vibrato_strength(float change) {
419 vibrato_strength /= change;
420}
421
422#endif /* VIBRATO_STRENGTH_ENABLE */
423
424#endif /* VIBRATO_ENABLE */
586 425
587 TIMSK3 |= _BV(OCIE3A); 426// Polyphony functions
427
428void set_polyphony_rate(float rate) {
429 polyphony_rate = rate;
430}
431
432void enable_polyphony() {
433 polyphony_rate = 5;
434}
435
436void disable_polyphony() {
437 polyphony_rate = 0;
438}
439
440void increase_polyphony_rate(float change) {
441 polyphony_rate *= change;
442}
443
444void decrease_polyphony_rate(float change) {
445 polyphony_rate /= change;
446}
447
448// Timbre function
449
450void set_timbre(float timbre) {
451 note_timbre = timbre;
452}
453
454// Tempo functions
455
456void set_tempo(uint8_t tempo) {
457 note_tempo = tempo;
458}
459
460void decrease_tempo(uint8_t tempo_change) {
461 note_tempo += tempo_change;
462}
463
464void increase_tempo(uint8_t tempo_change) {
465 if (note_tempo - tempo_change < 10) {
466 note_tempo = 10;
467 } else {
468 note_tempo -= tempo_change;
588 } 469 }
589} 470}
590#endif 471
591 472
592//------------------------------------------------------------------------------ 473//------------------------------------------------------------------------------
593// Override these functions in your keymap file to play different tunes on 474// Override these functions in your keymap file to play different tunes on
@@ -597,11 +478,8 @@ void play_startup_tone()
597{ 478{
598} 479}
599 480
600
601
602__attribute__ ((weak)) 481__attribute__ ((weak))
603void play_goodbye_tone() 482void play_goodbye_tone()
604{ 483{
605
606} 484}
607//------------------------------------------------------------------------------ 485//------------------------------------------------------------------------------