diff options
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/audio.c | 100 |
1 files changed, 55 insertions, 45 deletions
diff --git a/quantum/audio.c b/quantum/audio.c index 73985479c..5edcccdbe 100644 --- a/quantum/audio.c +++ b/quantum/audio.c | |||
| @@ -32,6 +32,8 @@ int voice_place = 0; | |||
| 32 | double frequency = 0; | 32 | double frequency = 0; |
| 33 | int volume = 0; | 33 | int volume = 0; |
| 34 | long position = 0; | 34 | long position = 0; |
| 35 | int duty_place = 1; | ||
| 36 | int duty_counter = 0; | ||
| 35 | 37 | ||
| 36 | double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | 38 | double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| 37 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | 39 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| @@ -98,53 +100,55 @@ void stop_all_notes() { | |||
| 98 | } | 100 | } |
| 99 | 101 | ||
| 100 | void stop_note(double freq) { | 102 | void stop_note(double freq) { |
| 101 | #ifdef PWM_AUDIO | 103 | if (note) { |
| 102 | freq = freq / SAMPLE_RATE; | ||
| 103 | #endif | ||
| 104 | for (int i = 7; i >= 0; i--) { | ||
| 105 | if (frequencies[i] == freq) { | ||
| 106 | frequencies[i] = 0; | ||
| 107 | volumes[i] = 0; | ||
| 108 | for (int j = i; (j < 7); j++) { | ||
| 109 | frequencies[j] = frequencies[j+1]; | ||
| 110 | frequencies[j+1] = 0; | ||
| 111 | volumes[j] = volumes[j+1]; | ||
| 112 | volumes[j+1] = 0; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | voices--; | ||
| 117 | if (voices < 0) | ||
| 118 | voices = 0; | ||
| 119 | if (voices == 0) { | ||
| 120 | #ifdef PWM_AUDIO | 104 | #ifdef PWM_AUDIO |
| 121 | TIMSK3 &= ~_BV(OCIE3A); | 105 | freq = freq / SAMPLE_RATE; |
| 122 | #else | ||
| 123 | TIMSK3 &= ~_BV(OCIE3A); | ||
| 124 | TCCR3A &= ~_BV(COM3A1); | ||
| 125 | #endif | 106 | #endif |
| 126 | frequency = 0; | 107 | for (int i = 7; i >= 0; i--) { |
| 127 | volume = 0; | 108 | if (frequencies[i] == freq) { |
| 128 | note = false; | 109 | frequencies[i] = 0; |
| 129 | } else { | 110 | volumes[i] = 0; |
| 130 | double freq = frequencies[voices - 1]; | 111 | for (int j = i; (j < 7); j++) { |
| 131 | int vol = volumes[voices - 1]; | 112 | frequencies[j] = frequencies[j+1]; |
| 132 | double starting_f = frequency; | 113 | frequencies[j+1] = 0; |
| 133 | if (frequency < freq) { | 114 | volumes[j] = volumes[j+1]; |
| 134 | sliding = true; | 115 | volumes[j+1] = 0; |
| 135 | for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { | 116 | } |
| 136 | frequency = f; | ||
| 137 | } | 117 | } |
| 138 | sliding = false; | 118 | } |
| 139 | } else if (frequency > freq) { | 119 | voices--; |
| 140 | sliding = true; | 120 | if (voices < 0) |
| 141 | for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { | 121 | voices = 0; |
| 142 | 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; | ||
| 143 | } | 148 | } |
| 144 | sliding = false; | 149 | frequency = freq; |
| 150 | volume = vol; | ||
| 145 | } | 151 | } |
| 146 | frequency = freq; | ||
| 147 | volume = vol; | ||
| 148 | } | 152 | } |
| 149 | } | 153 | } |
| 150 | 154 | ||
| @@ -239,13 +243,19 @@ ISR(TIMER3_COMPA_vect) { | |||
| 239 | if (frequency > 0) { | 243 | if (frequency > 0) { |
| 240 | // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period | 244 | // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period |
| 241 | // 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 |
| 242 | if (place > 10) { | 246 | voice_place %= voices; |
| 247 | if (place > (frequencies[voice_place] / 500)) { | ||
| 243 | voice_place = (voice_place + 1) % voices; | 248 | voice_place = (voice_place + 1) % voices; |
| 244 | place = 0.0; | 249 | place = 0.0; |
| 245 | } | 250 | } |
| 246 | 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 |
| 247 | 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 |
| 248 | 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++; | ||
| 249 | } | 259 | } |
| 250 | #endif | 260 | #endif |
| 251 | } | 261 | } |
| @@ -375,7 +385,7 @@ if (audio_config.enable) { | |||
| 375 | 385 | ||
| 376 | void play_note(double freq, int vol) { | 386 | void play_note(double freq, int vol) { |
| 377 | 387 | ||
| 378 | if (audio_config.enable) { | 388 | if (audio_config.enable && voices < 8) { |
| 379 | 389 | ||
| 380 | if (notes) | 390 | if (notes) |
| 381 | stop_all_notes(); | 391 | stop_all_notes(); |
