aboutsummaryrefslogtreecommitdiff
path: root/quantum/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/audio.c')
-rw-r--r--quantum/audio.c146
1 files changed, 101 insertions, 45 deletions
diff --git a/quantum/audio.c b/quantum/audio.c
index 50e5505fe..5edcccdbe 100644
--- a/quantum/audio.c
+++ b/quantum/audio.c
@@ -8,6 +8,8 @@
8#include "audio.h" 8#include "audio.h"
9#include "keymap_common.h" 9#include "keymap_common.h"
10 10
11#include "eeconfig.h"
12
11#define PI 3.14159265 13#define PI 3.14159265
12 14
13// #define PWM_AUDIO 15// #define PWM_AUDIO
@@ -30,6 +32,8 @@ int voice_place = 0;
30double frequency = 0; 32double frequency = 0;
31int volume = 0; 33int volume = 0;
32long position = 0; 34long position = 0;
35int duty_place = 1;
36int duty_counter = 0;
33 37
34double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 38double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
35int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 39int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -57,6 +61,25 @@ uint8_t notes_length;
57bool notes_repeat; 61bool notes_repeat;
58uint8_t current_note = 0; 62uint8_t current_note = 0;
59 63
64audio_config_t audio_config;
65
66
67void audio_toggle(void) {
68 audio_config.enable ^= 1;
69 eeconfig_write_audio(audio_config.raw);
70}
71
72void audio_on(void) {
73 audio_config.enable = 1;
74 eeconfig_write_audio(audio_config.raw);
75}
76
77void audio_off(void) {
78 audio_config.enable = 0;
79 eeconfig_write_audio(audio_config.raw);
80}
81
82
60void stop_all_notes() { 83void stop_all_notes() {
61 voices = 0; 84 voices = 0;
62 #ifdef PWM_AUDIO 85 #ifdef PWM_AUDIO
@@ -77,58 +100,66 @@ void stop_all_notes() {
77} 100}
78 101
79void stop_note(double freq) { 102void stop_note(double freq) {
80 #ifdef PWM_AUDIO 103 if (note) {
81 freq = freq / SAMPLE_RATE;
82 #endif
83 for (int i = 7; i >= 0; i--) {
84 if (frequencies[i] == freq) {
85 frequencies[i] = 0;
86 volumes[i] = 0;
87 for (int j = i; (j < 7); j++) {
88 frequencies[j] = frequencies[j+1];
89 frequencies[j+1] = 0;
90 volumes[j] = volumes[j+1];
91 volumes[j+1] = 0;
92 }
93 }
94 }
95 voices--;
96 if (voices < 0)
97 voices = 0;
98 if (voices == 0) {
99 #ifdef PWM_AUDIO 104 #ifdef PWM_AUDIO
100 TIMSK3 &= ~_BV(OCIE3A); 105 freq = freq / SAMPLE_RATE;
101 #else
102 TIMSK3 &= ~_BV(OCIE3A);
103 TCCR3A &= ~_BV(COM3A1);
104 #endif 106 #endif
105 frequency = 0; 107 for (int i = 7; i >= 0; i--) {
106 volume = 0; 108 if (frequencies[i] == freq) {
107 note = false; 109 frequencies[i] = 0;
108 } else { 110 volumes[i] = 0;
109 double freq = frequencies[voices - 1]; 111 for (int j = i; (j < 7); j++) {
110 int vol = volumes[voices - 1]; 112 frequencies[j] = frequencies[j+1];
111 double starting_f = frequency; 113 frequencies[j+1] = 0;
112 if (frequency < freq) { 114 volumes[j] = volumes[j+1];
113 sliding = true; 115 volumes[j+1] = 0;
114 for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { 116 }
115 frequency = f;
116 } 117 }
117 sliding = false; 118 }
118 } else if (frequency > freq) { 119 voices--;
119 sliding = true; 120 if (voices < 0)
120 for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { 121 voices = 0;
121 frequency = f; 122 if (voices == 0) {
123 #ifdef PWM_AUDIO
124 TIMSK3 &= ~_BV(OCIE3A);
125 #else
126 TIMSK3 &= ~_BV(OCIE3A);
127 TCCR3A &= ~_BV(COM3A1);
128 #endif
129 frequency = 0;
130 volume = 0;
131 note = false;
132 } else {
133 double freq = frequencies[voices - 1];
134 int vol = volumes[voices - 1];
135 double starting_f = frequency;
136 if (frequency < freq) {
137 sliding = true;
138 for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {
139 frequency = f;
140 }
141 sliding = false;
142 } else if (frequency > freq) {
143 sliding = true;
144 for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
145 frequency = f;
146 }
147 sliding = false;
122 } 148 }
123 sliding = false; 149 frequency = freq;
150 volume = vol;
124 } 151 }
125 frequency = freq;
126 volume = vol;
127 } 152 }
128} 153}
129 154
130void init_notes() { 155void init_notes() {
131 156
157 /* check signature */
158 if (!eeconfig_is_enabled()) {
159 eeconfig_init();
160 }
161 audio_config.raw = eeconfig_read_audio();
162
132 #ifdef PWM_AUDIO 163 #ifdef PWM_AUDIO
133 PLLFRQ = _BV(PDIV2); 164 PLLFRQ = _BV(PDIV2);
134 PLLCSR = _BV(PLLE); 165 PLLCSR = _BV(PLLE);
@@ -160,7 +191,6 @@ void init_notes() {
160 191
161 192
162ISR(TIMER3_COMPA_vect) { 193ISR(TIMER3_COMPA_vect) {
163
164 if (note) { 194 if (note) {
165 #ifdef PWM_AUDIO 195 #ifdef PWM_AUDIO
166 if (voices == 1) { 196 if (voices == 1) {
@@ -213,13 +243,19 @@ ISR(TIMER3_COMPA_vect) {
213 if (frequency > 0) { 243 if (frequency > 0) {
214 // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period 244 // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period
215 // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period 245 // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period
216 if (place > 10) { 246 voice_place %= voices;
247 if (place > (frequencies[voice_place] / 500)) {
217 voice_place = (voice_place + 1) % voices; 248 voice_place = (voice_place + 1) % voices;
218 place = 0.0; 249 place = 0.0;
219 } 250 }
220 ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period 251 ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period
221 OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1; // Set compare to half the period 252 OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1 * duty_place; // Set compare to half the period
222 place++; 253 place++;
254 // if (duty_counter > (frequencies[voice_place] / 500)) {
255 // duty_place = (duty_place % 3) + 1;
256 // duty_counter = 0;
257 // }
258 // duty_counter++;
223 } 259 }
224 #endif 260 #endif
225 } 261 }
@@ -288,9 +324,16 @@ ISR(TIMER3_COMPA_vect) {
288 324
289 } 325 }
290 326
327 if (!audio_config.enable) {
328 notes = false;
329 note = false;
330 }
291} 331}
292 332
293void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) { 333void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
334
335if (audio_config.enable) {
336
294 if (note) 337 if (note)
295 stop_all_notes(); 338 stop_all_notes();
296 notes = true; 339 notes = true;
@@ -319,7 +362,12 @@ void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
319 #endif 362 #endif
320} 363}
321 364
365}
366
322void play_sample(uint8_t * s, uint16_t l, bool r) { 367void play_sample(uint8_t * s, uint16_t l, bool r) {
368
369if (audio_config.enable) {
370
323 stop_all_notes(); 371 stop_all_notes();
324 place_int = 0; 372 place_int = 0;
325 sample = s; 373 sample = s;
@@ -330,9 +378,15 @@ void play_sample(uint8_t * s, uint16_t l, bool r) {
330 TIMSK3 |= _BV(OCIE3A); 378 TIMSK3 |= _BV(OCIE3A);
331 #else 379 #else
332 #endif 380 #endif
381
382}
383
333} 384}
334 385
335void play_note(double freq, int vol) { 386void play_note(double freq, int vol) {
387
388if (audio_config.enable && voices < 8) {
389
336 if (notes) 390 if (notes)
337 stop_all_notes(); 391 stop_all_notes();
338 note = true; 392 note = true;
@@ -367,4 +421,6 @@ void play_note(double freq, int vol) {
367 TCCR3A |= _BV(COM3A1); 421 TCCR3A |= _BV(COM3A1);
368 #endif 422 #endif
369 423
424}
425
370} \ No newline at end of file 426} \ No newline at end of file