diff options
Diffstat (limited to 'quantum/audio')
| -rw-r--r-- | quantum/audio/audio.c | 477 | ||||
| -rw-r--r-- | quantum/audio/audio.h | 91 | ||||
| -rw-r--r-- | quantum/audio/audio_pwm.c | 643 | ||||
| -rw-r--r-- | quantum/audio/luts.c | 382 | ||||
| -rw-r--r-- | quantum/audio/luts.h | 15 | ||||
| -rw-r--r-- | quantum/audio/musical_notes.h | 217 | ||||
| -rw-r--r-- | quantum/audio/song_list.h | 117 | ||||
| -rw-r--r-- | quantum/audio/voices.c | 165 | ||||
| -rw-r--r-- | quantum/audio/voices.h | 31 | ||||
| -rw-r--r-- | quantum/audio/wave.h | 265 |
10 files changed, 2403 insertions, 0 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c new file mode 100644 index 000000000..ead5fbf3e --- /dev/null +++ b/quantum/audio/audio.c | |||
| @@ -0,0 +1,477 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <string.h> | ||
| 3 | //#include <math.h> | ||
| 4 | #include <avr/pgmspace.h> | ||
| 5 | #include <avr/interrupt.h> | ||
| 6 | #include <avr/io.h> | ||
| 7 | #include "print.h" | ||
| 8 | #include "audio.h" | ||
| 9 | #include "keymap.h" | ||
| 10 | |||
| 11 | #include "eeconfig.h" | ||
| 12 | |||
| 13 | #define CPU_PRESCALER 8 | ||
| 14 | |||
| 15 | // ----------------------------------------------------------------------------- | ||
| 16 | // Timer Abstractions | ||
| 17 | // ----------------------------------------------------------------------------- | ||
| 18 | |||
| 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) | ||
| 23 | |||
| 24 | // TCCR3A: Timer/Counter #3 Control Register | ||
| 25 | // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 | ||
| 26 | #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); | ||
| 27 | #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); | ||
| 28 | |||
| 29 | // Fast PWM Mode Controls | ||
| 30 | #define TIMER_3_PERIOD ICR3 | ||
| 31 | #define TIMER_3_DUTY_CYCLE OCR3A | ||
| 32 | |||
| 33 | // ----------------------------------------------------------------------------- | ||
| 34 | |||
| 35 | |||
| 36 | int voices = 0; | ||
| 37 | int voice_place = 0; | ||
| 38 | float frequency = 0; | ||
| 39 | int volume = 0; | ||
| 40 | long position = 0; | ||
| 41 | |||
| 42 | float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 43 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 44 | bool sliding = false; | ||
| 45 | |||
| 46 | float place = 0; | ||
| 47 | |||
| 48 | uint8_t * sample; | ||
| 49 | uint16_t sample_length = 0; | ||
| 50 | |||
| 51 | bool playing_notes = false; | ||
| 52 | bool playing_note = false; | ||
| 53 | float note_frequency = 0; | ||
| 54 | float note_length = 0; | ||
| 55 | uint8_t note_tempo = TEMPO_DEFAULT; | ||
| 56 | float note_timbre = TIMBRE_DEFAULT; | ||
| 57 | uint16_t note_position = 0; | ||
| 58 | float (* notes_pointer)[][2]; | ||
| 59 | uint16_t notes_count; | ||
| 60 | bool notes_repeat; | ||
| 61 | float notes_rest; | ||
| 62 | bool note_resting = false; | ||
| 63 | |||
| 64 | uint8_t current_note = 0; | ||
| 65 | uint8_t rest_counter = 0; | ||
| 66 | |||
| 67 | #ifdef VIBRATO_ENABLE | ||
| 68 | float vibrato_counter = 0; | ||
| 69 | float vibrato_strength = .5; | ||
| 70 | float vibrato_rate = 0.125; | ||
| 71 | #endif | ||
| 72 | |||
| 73 | float polyphony_rate = 0; | ||
| 74 | |||
| 75 | static bool audio_initialized = false; | ||
| 76 | |||
| 77 | audio_config_t audio_config; | ||
| 78 | |||
| 79 | uint16_t envelope_index = 0; | ||
| 80 | |||
| 81 | void audio_init() | ||
| 82 | { | ||
| 83 | |||
| 84 | // Check EEPROM | ||
| 85 | if (!eeconfig_is_enabled()) | ||
| 86 | { | ||
| 87 | eeconfig_init(); | ||
| 88 | } | ||
| 89 | audio_config.raw = eeconfig_read_audio(); | ||
| 90 | |||
| 91 | // Set port PC6 (OC3A and /OC4A) as output | ||
| 92 | DDRC |= _BV(PORTC6); | ||
| 93 | |||
| 94 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 95 | |||
| 96 | // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers | ||
| 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); | ||
| 102 | |||
| 103 | audio_initialized = true; | ||
| 104 | } | ||
| 105 | |||
| 106 | void stop_all_notes() | ||
| 107 | { | ||
| 108 | if (!audio_initialized) { | ||
| 109 | audio_init(); | ||
| 110 | } | ||
| 111 | voices = 0; | ||
| 112 | |||
| 113 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 114 | DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 115 | |||
| 116 | playing_notes = false; | ||
| 117 | playing_note = false; | ||
| 118 | frequency = 0; | ||
| 119 | volume = 0; | ||
| 120 | |||
| 121 | for (uint8_t i = 0; i < 8; i++) | ||
| 122 | { | ||
| 123 | frequencies[i] = 0; | ||
| 124 | volumes[i] = 0; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | void stop_note(float freq) | ||
| 129 | { | ||
| 130 | if (playing_note) { | ||
| 131 | if (!audio_initialized) { | ||
| 132 | audio_init(); | ||
| 133 | } | ||
| 134 | for (int i = 7; i >= 0; i--) { | ||
| 135 | if (frequencies[i] == freq) { | ||
| 136 | frequencies[i] = 0; | ||
| 137 | volumes[i] = 0; | ||
| 138 | for (int j = i; (j < 7); j++) { | ||
| 139 | frequencies[j] = frequencies[j+1]; | ||
| 140 | frequencies[j+1] = 0; | ||
| 141 | volumes[j] = volumes[j+1]; | ||
| 142 | volumes[j+1] = 0; | ||
| 143 | } | ||
| 144 | break; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | voices--; | ||
| 148 | if (voices < 0) | ||
| 149 | voices = 0; | ||
| 150 | if (voice_place >= voices) { | ||
| 151 | voice_place = 0; | ||
| 152 | } | ||
| 153 | if (voices == 0) { | ||
| 154 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 155 | DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 156 | frequency = 0; | ||
| 157 | volume = 0; | ||
| 158 | playing_note = false; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | #ifdef VIBRATO_ENABLE | ||
| 164 | |||
| 165 | float mod(float a, int b) | ||
| 166 | { | ||
| 167 | float r = fmod(a, b); | ||
| 168 | return r < 0 ? r + b : r; | ||
| 169 | } | ||
| 170 | |||
| 171 | float vibrato(float average_freq) { | ||
| 172 | #ifdef VIBRATO_STRENGTH_ENABLE | ||
| 173 | float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); | ||
| 174 | #else | ||
| 175 | float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; | ||
| 176 | #endif | ||
| 177 | vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); | ||
| 178 | return vibrated_freq; | ||
| 179 | } | ||
| 180 | |||
| 181 | #endif | ||
| 182 | |||
| 183 | ISR(TIMER3_COMPA_vect) | ||
| 184 | { | ||
| 185 | float freq; | ||
| 186 | |||
| 187 | if (playing_note) { | ||
| 188 | if (voices > 0) { | ||
| 189 | if (polyphony_rate > 0) { | ||
| 190 | if (voices > 1) { | ||
| 191 | voice_place %= voices; | ||
| 192 | if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { | ||
| 193 | voice_place = (voice_place + 1) % voices; | ||
| 194 | place = 0.0; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | #ifdef VIBRATO_ENABLE | ||
| 199 | if (vibrato_strength > 0) { | ||
| 200 | freq = vibrato(frequencies[voice_place]); | ||
| 201 | } else { | ||
| 202 | freq = frequencies[voice_place]; | ||
| 203 | } | ||
| 204 | #else | ||
| 205 | freq = frequencies[voice_place]; | ||
| 206 | #endif | ||
| 207 | } else { | ||
| 208 | if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { | ||
| 209 | frequency = frequency * pow(2, 440/frequency/12/2); | ||
| 210 | } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { | ||
| 211 | frequency = frequency * pow(2, -440/frequency/12/2); | ||
| 212 | } else { | ||
| 213 | frequency = frequencies[voices - 1]; | ||
| 214 | } | ||
| 215 | |||
| 216 | #ifdef VIBRATO_ENABLE | ||
| 217 | if (vibrato_strength > 0) { | ||
| 218 | freq = vibrato(frequency); | ||
| 219 | } else { | ||
| 220 | freq = frequency; | ||
| 221 | } | ||
| 222 | #else | ||
| 223 | freq = frequency; | ||
| 224 | #endif | ||
| 225 | } | ||
| 226 | |||
| 227 | if (envelope_index < 65535) { | ||
| 228 | envelope_index++; | ||
| 229 | } | ||
| 230 | |||
| 231 | freq = voice_envelope(freq); | ||
| 232 | |||
| 233 | if (freq < 30.517578125) { | ||
| 234 | freq = 30.52; | ||
| 235 | } | ||
| 236 | |||
| 237 | TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); | ||
| 238 | TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | if (playing_notes) { | ||
| 243 | if (note_frequency > 0) { | ||
| 244 | #ifdef VIBRATO_ENABLE | ||
| 245 | if (vibrato_strength > 0) { | ||
| 246 | freq = vibrato(note_frequency); | ||
| 247 | } else { | ||
| 248 | freq = note_frequency; | ||
| 249 | } | ||
| 250 | #else | ||
| 251 | freq = note_frequency; | ||
| 252 | #endif | ||
| 253 | |||
| 254 | if (envelope_index < 65535) { | ||
| 255 | envelope_index++; | ||
| 256 | } | ||
| 257 | freq = voice_envelope(freq); | ||
| 258 | |||
| 259 | TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); | ||
| 260 | TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); | ||
| 261 | } else { | ||
| 262 | TIMER_3_PERIOD = 0; | ||
| 263 | TIMER_3_DUTY_CYCLE = 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | note_position++; | ||
| 267 | bool end_of_note = false; | ||
| 268 | if (TIMER_3_PERIOD > 0) { | ||
| 269 | end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF)); | ||
| 270 | } else { | ||
| 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 | } | ||
| 307 | |||
| 308 | void play_note(float freq, int vol) { | ||
| 309 | |||
| 310 | if (!audio_initialized) { | ||
| 311 | audio_init(); | ||
| 312 | } | ||
| 313 | |||
| 314 | if (audio_config.enable && voices < 8) { | ||
| 315 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 316 | |||
| 317 | // Cancel notes if notes are playing | ||
| 318 | if (playing_notes) | ||
| 319 | stop_all_notes(); | ||
| 320 | |||
| 321 | playing_note = true; | ||
| 322 | |||
| 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 | } | ||
| 334 | |||
| 335 | } | ||
| 336 | |||
| 337 | void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) | ||
| 338 | { | ||
| 339 | |||
| 340 | if (!audio_initialized) { | ||
| 341 | audio_init(); | ||
| 342 | } | ||
| 343 | |||
| 344 | if (audio_config.enable) { | ||
| 345 | |||
| 346 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 347 | |||
| 348 | // Cancel note if a note is playing | ||
| 349 | if (playing_note) | ||
| 350 | stop_all_notes(); | ||
| 351 | |||
| 352 | playing_notes = true; | ||
| 353 | |||
| 354 | notes_pointer = np; | ||
| 355 | notes_count = n_count; | ||
| 356 | notes_repeat = n_repeat; | ||
| 357 | notes_rest = n_rest; | ||
| 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 | } | ||
| 370 | |||
| 371 | } | ||
| 372 | |||
| 373 | bool is_playing_notes(void) { | ||
| 374 | return playing_notes; | ||
| 375 | } | ||
| 376 | |||
| 377 | bool is_audio_on(void) { | ||
| 378 | return (audio_config.enable != 0); | ||
| 379 | } | ||
| 380 | |||
| 381 | void audio_toggle(void) { | ||
| 382 | audio_config.enable ^= 1; | ||
| 383 | eeconfig_update_audio(audio_config.raw); | ||
| 384 | if (audio_config.enable) | ||
| 385 | audio_on_user(); | ||
| 386 | } | ||
| 387 | |||
| 388 | void audio_on(void) { | ||
| 389 | audio_config.enable = 1; | ||
| 390 | eeconfig_update_audio(audio_config.raw); | ||
| 391 | audio_on_user(); | ||
| 392 | } | ||
| 393 | |||
| 394 | void audio_off(void) { | ||
| 395 | audio_config.enable = 0; | ||
| 396 | eeconfig_update_audio(audio_config.raw); | ||
| 397 | } | ||
| 398 | |||
| 399 | #ifdef VIBRATO_ENABLE | ||
| 400 | |||
| 401 | // Vibrato rate functions | ||
| 402 | |||
| 403 | void set_vibrato_rate(float rate) { | ||
| 404 | vibrato_rate = rate; | ||
| 405 | } | ||
| 406 | |||
| 407 | void increase_vibrato_rate(float change) { | ||
| 408 | vibrato_rate *= change; | ||
| 409 | } | ||
| 410 | |||
| 411 | void decrease_vibrato_rate(float change) { | ||
| 412 | vibrato_rate /= change; | ||
| 413 | } | ||
| 414 | |||
| 415 | #ifdef VIBRATO_STRENGTH_ENABLE | ||
| 416 | |||
| 417 | void set_vibrato_strength(float strength) { | ||
| 418 | vibrato_strength = strength; | ||
| 419 | } | ||
| 420 | |||
| 421 | void increase_vibrato_strength(float change) { | ||
| 422 | vibrato_strength *= change; | ||
| 423 | } | ||
| 424 | |||
| 425 | void decrease_vibrato_strength(float change) { | ||
| 426 | vibrato_strength /= change; | ||
| 427 | } | ||
| 428 | |||
| 429 | #endif /* VIBRATO_STRENGTH_ENABLE */ | ||
| 430 | |||
| 431 | #endif /* VIBRATO_ENABLE */ | ||
| 432 | |||
| 433 | // Polyphony functions | ||
| 434 | |||
| 435 | void set_polyphony_rate(float rate) { | ||
| 436 | polyphony_rate = rate; | ||
| 437 | } | ||
| 438 | |||
| 439 | void enable_polyphony() { | ||
| 440 | polyphony_rate = 5; | ||
| 441 | } | ||
| 442 | |||
| 443 | void disable_polyphony() { | ||
| 444 | polyphony_rate = 0; | ||
| 445 | } | ||
| 446 | |||
| 447 | void increase_polyphony_rate(float change) { | ||
| 448 | polyphony_rate *= change; | ||
| 449 | } | ||
| 450 | |||
| 451 | void decrease_polyphony_rate(float change) { | ||
| 452 | polyphony_rate /= change; | ||
| 453 | } | ||
| 454 | |||
| 455 | // Timbre function | ||
| 456 | |||
| 457 | void set_timbre(float timbre) { | ||
| 458 | note_timbre = timbre; | ||
| 459 | } | ||
| 460 | |||
| 461 | // Tempo functions | ||
| 462 | |||
| 463 | void set_tempo(uint8_t tempo) { | ||
| 464 | note_tempo = tempo; | ||
| 465 | } | ||
| 466 | |||
| 467 | void decrease_tempo(uint8_t tempo_change) { | ||
| 468 | note_tempo += tempo_change; | ||
| 469 | } | ||
| 470 | |||
| 471 | void increase_tempo(uint8_t tempo_change) { | ||
| 472 | if (note_tempo - tempo_change < 10) { | ||
| 473 | note_tempo = 10; | ||
| 474 | } else { | ||
| 475 | note_tempo -= tempo_change; | ||
| 476 | } | ||
| 477 | } | ||
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h new file mode 100644 index 000000000..47f326ea0 --- /dev/null +++ b/quantum/audio/audio.h | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | #ifndef AUDIO_H | ||
| 2 | #define AUDIO_H | ||
| 3 | |||
| 4 | #include <stdint.h> | ||
| 5 | #include <stdbool.h> | ||
| 6 | #include <avr/io.h> | ||
| 7 | #include <util/delay.h> | ||
| 8 | #include "musical_notes.h" | ||
| 9 | #include "song_list.h" | ||
| 10 | #include "voices.h" | ||
| 11 | #include "quantum.h" | ||
| 12 | |||
| 13 | // Largely untested PWM audio mode (doesn't sound as good) | ||
| 14 | // #define PWM_AUDIO | ||
| 15 | |||
| 16 | // #define VIBRATO_ENABLE | ||
| 17 | |||
| 18 | // Enable vibrato strength/amplitude - slows down ISR too much | ||
| 19 | // #define VIBRATO_STRENGTH_ENABLE | ||
| 20 | |||
| 21 | typedef union { | ||
| 22 | uint8_t raw; | ||
| 23 | struct { | ||
| 24 | bool enable :1; | ||
| 25 | uint8_t level :7; | ||
| 26 | }; | ||
| 27 | } audio_config_t; | ||
| 28 | |||
| 29 | bool is_audio_on(void); | ||
| 30 | void audio_toggle(void); | ||
| 31 | void audio_on(void); | ||
| 32 | void audio_off(void); | ||
| 33 | |||
| 34 | // Vibrato rate functions | ||
| 35 | |||
| 36 | #ifdef VIBRATO_ENABLE | ||
| 37 | |||
| 38 | void set_vibrato_rate(float rate); | ||
| 39 | void increase_vibrato_rate(float change); | ||
| 40 | void decrease_vibrato_rate(float change); | ||
| 41 | |||
| 42 | #ifdef VIBRATO_STRENGTH_ENABLE | ||
| 43 | |||
| 44 | void set_vibrato_strength(float strength); | ||
| 45 | void increase_vibrato_strength(float change); | ||
| 46 | void decrease_vibrato_strength(float change); | ||
| 47 | |||
| 48 | #endif | ||
| 49 | |||
| 50 | #endif | ||
| 51 | |||
| 52 | // Polyphony functions | ||
| 53 | |||
| 54 | void set_polyphony_rate(float rate); | ||
| 55 | void enable_polyphony(void); | ||
| 56 | void disable_polyphony(void); | ||
| 57 | void increase_polyphony_rate(float change); | ||
| 58 | void decrease_polyphony_rate(float change); | ||
| 59 | |||
| 60 | void set_timbre(float timbre); | ||
| 61 | void set_tempo(uint8_t tempo); | ||
| 62 | |||
| 63 | void increase_tempo(uint8_t tempo_change); | ||
| 64 | void decrease_tempo(uint8_t tempo_change); | ||
| 65 | |||
| 66 | void audio_init(void); | ||
| 67 | |||
| 68 | #ifdef PWM_AUDIO | ||
| 69 | void play_sample(uint8_t * s, uint16_t l, bool r); | ||
| 70 | #endif | ||
| 71 | void play_note(float freq, int vol); | ||
| 72 | void stop_note(float freq); | ||
| 73 | void stop_all_notes(void); | ||
| 74 | void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); | ||
| 75 | |||
| 76 | #define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ | ||
| 77 | 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ | ||
| 78 | 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ | ||
| 79 | 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ | ||
| 80 | 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } | ||
| 81 | |||
| 82 | // These macros are used to allow play_notes to play an array of indeterminate | ||
| 83 | // length. This works around the limitation of C's sizeof operation on pointers. | ||
| 84 | // The global float array for the song must be used here. | ||
| 85 | #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) | ||
| 86 | #define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); | ||
| 87 | |||
| 88 | |||
| 89 | bool is_playing_notes(void); | ||
| 90 | |||
| 91 | #endif \ No newline at end of file | ||
diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c new file mode 100644 index 000000000..f820eec1b --- /dev/null +++ b/quantum/audio/audio_pwm.c | |||
| @@ -0,0 +1,643 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <string.h> | ||
| 3 | //#include <math.h> | ||
| 4 | #include <avr/pgmspace.h> | ||
| 5 | #include <avr/interrupt.h> | ||
| 6 | #include <avr/io.h> | ||
| 7 | #include "print.h" | ||
| 8 | #include "audio.h" | ||
| 9 | #include "keymap.h" | ||
| 10 | |||
| 11 | #include "eeconfig.h" | ||
| 12 | |||
| 13 | #define PI 3.14159265 | ||
| 14 | |||
| 15 | #define CPU_PRESCALER 8 | ||
| 16 | |||
| 17 | |||
| 18 | // Timer Abstractions | ||
| 19 | |||
| 20 | // TIMSK3 - Timer/Counter #3 Interrupt Mask Register | ||
| 21 | // Turn on/off 3A interputs, stopping/enabling the ISR calls | ||
| 22 | #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) | ||
| 23 | #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) | ||
| 24 | |||
| 25 | |||
| 26 | // TCCR3A: Timer/Counter #3 Control Register | ||
| 27 | // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 | ||
| 28 | #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); | ||
| 29 | #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); | ||
| 30 | |||
| 31 | |||
| 32 | #define NOTE_PERIOD ICR3 | ||
| 33 | #define NOTE_DUTY_CYCLE OCR3A | ||
| 34 | |||
| 35 | |||
| 36 | #ifdef PWM_AUDIO | ||
| 37 | #include "wave.h" | ||
| 38 | #define SAMPLE_DIVIDER 39 | ||
| 39 | #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) | ||
| 40 | // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap | ||
| 41 | |||
| 42 | float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 43 | uint16_t place_int = 0; | ||
| 44 | bool repeat = true; | ||
| 45 | #endif | ||
| 46 | |||
| 47 | void delay_us(int count) { | ||
| 48 | while(count--) { | ||
| 49 | _delay_us(1); | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | int voices = 0; | ||
| 54 | int voice_place = 0; | ||
| 55 | float frequency = 0; | ||
| 56 | int volume = 0; | ||
| 57 | long position = 0; | ||
| 58 | |||
| 59 | float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 60 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 61 | bool sliding = false; | ||
| 62 | |||
| 63 | float place = 0; | ||
| 64 | |||
| 65 | uint8_t * sample; | ||
| 66 | uint16_t sample_length = 0; | ||
| 67 | // float freq = 0; | ||
| 68 | |||
| 69 | bool playing_notes = false; | ||
| 70 | bool playing_note = false; | ||
| 71 | float note_frequency = 0; | ||
| 72 | float note_length = 0; | ||
| 73 | uint8_t note_tempo = TEMPO_DEFAULT; | ||
| 74 | float note_timbre = TIMBRE_DEFAULT; | ||
| 75 | uint16_t note_position = 0; | ||
| 76 | float (* notes_pointer)[][2]; | ||
| 77 | uint16_t notes_count; | ||
| 78 | bool notes_repeat; | ||
| 79 | float notes_rest; | ||
| 80 | bool note_resting = false; | ||
| 81 | |||
| 82 | uint8_t current_note = 0; | ||
| 83 | uint8_t rest_counter = 0; | ||
| 84 | |||
| 85 | #ifdef VIBRATO_ENABLE | ||
| 86 | float vibrato_counter = 0; | ||
| 87 | float vibrato_strength = .5; | ||
| 88 | float vibrato_rate = 0.125; | ||
| 89 | #endif | ||
| 90 | |||
| 91 | float polyphony_rate = 0; | ||
| 92 | |||
| 93 | static bool audio_initialized = false; | ||
| 94 | |||
| 95 | audio_config_t audio_config; | ||
| 96 | |||
| 97 | uint16_t envelope_index = 0; | ||
| 98 | |||
| 99 | void audio_init() { | ||
| 100 | |||
| 101 | // Check EEPROM | ||
| 102 | if (!eeconfig_is_enabled()) | ||
| 103 | { | ||
| 104 | eeconfig_init(); | ||
| 105 | } | ||
| 106 | audio_config.raw = eeconfig_read_audio(); | ||
| 107 | |||
| 108 | #ifdef PWM_AUDIO | ||
| 109 | |||
| 110 | PLLFRQ = _BV(PDIV2); | ||
| 111 | PLLCSR = _BV(PLLE); | ||
| 112 | while(!(PLLCSR & _BV(PLOCK))); | ||
| 113 | PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ | ||
| 114 | |||
| 115 | /* Init a fast PWM on Timer4 */ | ||
| 116 | TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ | ||
| 117 | TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ | ||
| 118 | OCR4A = 0; | ||
| 119 | |||
| 120 | /* Enable the OC4A output */ | ||
| 121 | DDRC |= _BV(PORTC6); | ||
| 122 | |||
| 123 | DISABLE_AUDIO_COUNTER_3_ISR; // Turn off 3A interputs | ||
| 124 | |||
| 125 | TCCR3A = 0x0; // Options not needed | ||
| 126 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC | ||
| 127 | OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback | ||
| 128 | |||
| 129 | #else | ||
| 130 | |||
| 131 | // Set port PC6 (OC3A and /OC4A) as output | ||
| 132 | DDRC |= _BV(PORTC6); | ||
| 133 | |||
| 134 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 135 | |||
| 136 | // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers | ||
| 137 | // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 | ||
| 138 | // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) | ||
| 139 | // Clock Select (CS3n) = 0b010 = Clock / 8 | ||
| 140 | TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | ||
| 141 | TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); | ||
| 142 | |||
| 143 | #endif | ||
| 144 | |||
| 145 | audio_initialized = true; | ||
| 146 | } | ||
| 147 | |||
| 148 | void stop_all_notes() { | ||
| 149 | if (!audio_initialized) { | ||
| 150 | audio_init(); | ||
| 151 | } | ||
| 152 | voices = 0; | ||
| 153 | #ifdef PWM_AUDIO | ||
| 154 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 155 | #else | ||
| 156 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 157 | DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 158 | #endif | ||
| 159 | |||
| 160 | playing_notes = false; | ||
| 161 | playing_note = false; | ||
| 162 | frequency = 0; | ||
| 163 | volume = 0; | ||
| 164 | |||
| 165 | for (uint8_t i = 0; i < 8; i++) | ||
| 166 | { | ||
| 167 | frequencies[i] = 0; | ||
| 168 | volumes[i] = 0; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | void stop_note(float freq) | ||
| 173 | { | ||
| 174 | if (playing_note) { | ||
| 175 | if (!audio_initialized) { | ||
| 176 | audio_init(); | ||
| 177 | } | ||
| 178 | #ifdef PWM_AUDIO | ||
| 179 | freq = freq / SAMPLE_RATE; | ||
| 180 | #endif | ||
| 181 | for (int i = 7; i >= 0; i--) { | ||
| 182 | if (frequencies[i] == freq) { | ||
| 183 | frequencies[i] = 0; | ||
| 184 | volumes[i] = 0; | ||
| 185 | for (int j = i; (j < 7); j++) { | ||
| 186 | frequencies[j] = frequencies[j+1]; | ||
| 187 | frequencies[j+1] = 0; | ||
| 188 | volumes[j] = volumes[j+1]; | ||
| 189 | volumes[j+1] = 0; | ||
| 190 | } | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | voices--; | ||
| 195 | if (voices < 0) | ||
| 196 | voices = 0; | ||
| 197 | if (voice_place >= voices) { | ||
| 198 | voice_place = 0; | ||
| 199 | } | ||
| 200 | if (voices == 0) { | ||
| 201 | #ifdef PWM_AUDIO | ||
| 202 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 203 | #else | ||
| 204 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 205 | DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 206 | #endif | ||
| 207 | frequency = 0; | ||
| 208 | volume = 0; | ||
| 209 | playing_note = false; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | #ifdef VIBRATO_ENABLE | ||
| 215 | |||
| 216 | float mod(float a, int b) | ||
| 217 | { | ||
| 218 | float r = fmod(a, b); | ||
| 219 | return r < 0 ? r + b : r; | ||
| 220 | } | ||
| 221 | |||
| 222 | float vibrato(float average_freq) { | ||
| 223 | #ifdef VIBRATO_STRENGTH_ENABLE | ||
| 224 | float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); | ||
| 225 | #else | ||
| 226 | float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; | ||
| 227 | #endif | ||
| 228 | vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); | ||
| 229 | return vibrated_freq; | ||
| 230 | } | ||
| 231 | |||
| 232 | #endif | ||
| 233 | |||
| 234 | ISR(TIMER3_COMPA_vect) | ||
| 235 | { | ||
| 236 | if (playing_note) { | ||
| 237 | #ifdef PWM_AUDIO | ||
| 238 | if (voices == 1) { | ||
| 239 | // SINE | ||
| 240 | OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; | ||
| 241 | |||
| 242 | // SQUARE | ||
| 243 | // if (((int)place) >= 1024){ | ||
| 244 | // OCR4A = 0xFF >> 2; | ||
| 245 | // } else { | ||
| 246 | // OCR4A = 0x00; | ||
| 247 | // } | ||
| 248 | |||
| 249 | // SAWTOOTH | ||
| 250 | // OCR4A = (int)place / 4; | ||
| 251 | |||
| 252 | // TRIANGLE | ||
| 253 | // if (((int)place) >= 1024) { | ||
| 254 | // OCR4A = (int)place / 2; | ||
| 255 | // } else { | ||
| 256 | // OCR4A = 2048 - (int)place / 2; | ||
| 257 | // } | ||
| 258 | |||
| 259 | place += frequency; | ||
| 260 | |||
| 261 | if (place >= SINE_LENGTH) | ||
| 262 | place -= SINE_LENGTH; | ||
| 263 | |||
| 264 | } else { | ||
| 265 | int sum = 0; | ||
| 266 | for (int i = 0; i < voices; i++) { | ||
| 267 | // SINE | ||
| 268 | sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; | ||
| 269 | |||
| 270 | // SQUARE | ||
| 271 | // if (((int)places[i]) >= 1024){ | ||
| 272 | // sum += 0xFF >> 2; | ||
| 273 | // } else { | ||
| 274 | // sum += 0x00; | ||
| 275 | // } | ||
| 276 | |||
| 277 | places[i] += frequencies[i]; | ||
| 278 | |||
| 279 | if (places[i] >= SINE_LENGTH) | ||
| 280 | places[i] -= SINE_LENGTH; | ||
| 281 | } | ||
| 282 | OCR4A = sum; | ||
| 283 | } | ||
| 284 | #else | ||
| 285 | if (voices > 0) { | ||
| 286 | float freq; | ||
| 287 | if (polyphony_rate > 0) { | ||
| 288 | if (voices > 1) { | ||
| 289 | voice_place %= voices; | ||
| 290 | if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { | ||
| 291 | voice_place = (voice_place + 1) % voices; | ||
| 292 | place = 0.0; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | #ifdef VIBRATO_ENABLE | ||
| 296 | if (vibrato_strength > 0) { | ||
| 297 | freq = vibrato(frequencies[voice_place]); | ||
| 298 | } else { | ||
| 299 | #else | ||
| 300 | { | ||
| 301 | #endif | ||
| 302 | freq = frequencies[voice_place]; | ||
| 303 | } | ||
| 304 | } else { | ||
| 305 | if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { | ||
| 306 | frequency = frequency * pow(2, 440/frequency/12/2); | ||
| 307 | } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { | ||
| 308 | frequency = frequency * pow(2, -440/frequency/12/2); | ||
| 309 | } else { | ||
| 310 | frequency = frequencies[voices - 1]; | ||
| 311 | } | ||
| 312 | |||
| 313 | |||
| 314 | #ifdef VIBRATO_ENABLE | ||
| 315 | if (vibrato_strength > 0) { | ||
| 316 | freq = vibrato(frequency); | ||
| 317 | } else { | ||
| 318 | #else | ||
| 319 | { | ||
| 320 | #endif | ||
| 321 | freq = frequency; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | if (envelope_index < 65535) { | ||
| 326 | envelope_index++; | ||
| 327 | } | ||
| 328 | freq = voice_envelope(freq); | ||
| 329 | |||
| 330 | if (freq < 30.517578125) | ||
| 331 | freq = 30.52; | ||
| 332 | NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period | ||
| 333 | NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period | ||
| 334 | } | ||
| 335 | #endif | ||
| 336 | } | ||
| 337 | |||
| 338 | // SAMPLE | ||
| 339 | // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); | ||
| 340 | |||
| 341 | // place_int++; | ||
| 342 | |||
| 343 | // if (place_int >= sample_length) | ||
| 344 | // if (repeat) | ||
| 345 | // place_int -= sample_length; | ||
| 346 | // else | ||
| 347 | // DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 348 | |||
| 349 | |||
| 350 | if (playing_notes) { | ||
| 351 | #ifdef PWM_AUDIO | ||
| 352 | OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; | ||
| 353 | |||
| 354 | place += note_frequency; | ||
| 355 | if (place >= SINE_LENGTH) | ||
| 356 | place -= SINE_LENGTH; | ||
| 357 | #else | ||
| 358 | if (note_frequency > 0) { | ||
| 359 | float freq; | ||
| 360 | |||
| 361 | #ifdef VIBRATO_ENABLE | ||
| 362 | if (vibrato_strength > 0) { | ||
| 363 | freq = vibrato(note_frequency); | ||
| 364 | } else { | ||
| 365 | #else | ||
| 366 | { | ||
| 367 | #endif | ||
| 368 | freq = note_frequency; | ||
| 369 | } | ||
| 370 | |||
| 371 | if (envelope_index < 65535) { | ||
| 372 | envelope_index++; | ||
| 373 | } | ||
| 374 | freq = voice_envelope(freq); | ||
| 375 | |||
| 376 | NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period | ||
| 377 | NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period | ||
| 378 | } else { | ||
| 379 | NOTE_PERIOD = 0; | ||
| 380 | NOTE_DUTY_CYCLE = 0; | ||
| 381 | } | ||
| 382 | #endif | ||
| 383 | |||
| 384 | |||
| 385 | note_position++; | ||
| 386 | bool end_of_note = false; | ||
| 387 | if (NOTE_PERIOD > 0) | ||
| 388 | end_of_note = (note_position >= (note_length / NOTE_PERIOD * 0xFFFF)); | ||
| 389 | else | ||
| 390 | end_of_note = (note_position >= (note_length * 0x7FF)); | ||
| 391 | if (end_of_note) { | ||
| 392 | current_note++; | ||
| 393 | if (current_note >= notes_count) { | ||
| 394 | if (notes_repeat) { | ||
| 395 | current_note = 0; | ||
| 396 | } else { | ||
| 397 | #ifdef PWM_AUDIO | ||
| 398 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 399 | #else | ||
| 400 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 401 | DISABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 402 | #endif | ||
| 403 | playing_notes = false; | ||
| 404 | return; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | if (!note_resting && (notes_rest > 0)) { | ||
| 408 | note_resting = true; | ||
| 409 | note_frequency = 0; | ||
| 410 | note_length = notes_rest; | ||
| 411 | current_note--; | ||
| 412 | } else { | ||
| 413 | note_resting = false; | ||
| 414 | #ifdef PWM_AUDIO | ||
| 415 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | ||
| 416 | note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); | ||
| 417 | #else | ||
| 418 | envelope_index = 0; | ||
| 419 | note_frequency = (*notes_pointer)[current_note][0]; | ||
| 420 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||
| 421 | #endif | ||
| 422 | } | ||
| 423 | note_position = 0; | ||
| 424 | } | ||
| 425 | |||
| 426 | } | ||
| 427 | |||
| 428 | if (!audio_config.enable) { | ||
| 429 | playing_notes = false; | ||
| 430 | playing_note = false; | ||
| 431 | } | ||
| 432 | } | ||
| 433 | |||
| 434 | void play_note(float freq, int vol) { | ||
| 435 | |||
| 436 | if (!audio_initialized) { | ||
| 437 | audio_init(); | ||
| 438 | } | ||
| 439 | |||
| 440 | if (audio_config.enable && voices < 8) { | ||
| 441 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 442 | |||
| 443 | // Cancel notes if notes are playing | ||
| 444 | if (playing_notes) | ||
| 445 | stop_all_notes(); | ||
| 446 | |||
| 447 | playing_note = true; | ||
| 448 | |||
| 449 | envelope_index = 0; | ||
| 450 | |||
| 451 | #ifdef PWM_AUDIO | ||
| 452 | freq = freq / SAMPLE_RATE; | ||
| 453 | #endif | ||
| 454 | if (freq > 0) { | ||
| 455 | frequencies[voices] = freq; | ||
| 456 | volumes[voices] = vol; | ||
| 457 | voices++; | ||
| 458 | } | ||
| 459 | |||
| 460 | #ifdef PWM_AUDIO | ||
| 461 | ENABLE_AUDIO_COUNTER_3_ISR; | ||
| 462 | #else | ||
| 463 | ENABLE_AUDIO_COUNTER_3_ISR; | ||
| 464 | ENABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 465 | #endif | ||
| 466 | } | ||
| 467 | |||
| 468 | } | ||
| 469 | |||
| 470 | void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) | ||
| 471 | { | ||
| 472 | |||
| 473 | if (!audio_initialized) { | ||
| 474 | audio_init(); | ||
| 475 | } | ||
| 476 | |||
| 477 | if (audio_config.enable) { | ||
| 478 | |||
| 479 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 480 | |||
| 481 | // Cancel note if a note is playing | ||
| 482 | if (playing_note) | ||
| 483 | stop_all_notes(); | ||
| 484 | |||
| 485 | playing_notes = true; | ||
| 486 | |||
| 487 | notes_pointer = np; | ||
| 488 | notes_count = n_count; | ||
| 489 | notes_repeat = n_repeat; | ||
| 490 | notes_rest = n_rest; | ||
| 491 | |||
| 492 | place = 0; | ||
| 493 | current_note = 0; | ||
| 494 | |||
| 495 | #ifdef PWM_AUDIO | ||
| 496 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | ||
| 497 | note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); | ||
| 498 | #else | ||
| 499 | note_frequency = (*notes_pointer)[current_note][0]; | ||
| 500 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||
| 501 | #endif | ||
| 502 | note_position = 0; | ||
| 503 | |||
| 504 | |||
| 505 | #ifdef PWM_AUDIO | ||
| 506 | ENABLE_AUDIO_COUNTER_3_ISR; | ||
| 507 | #else | ||
| 508 | ENABLE_AUDIO_COUNTER_3_ISR; | ||
| 509 | ENABLE_AUDIO_COUNTER_3_OUTPUT; | ||
| 510 | #endif | ||
| 511 | } | ||
| 512 | |||
| 513 | } | ||
| 514 | |||
| 515 | #ifdef PWM_AUDIO | ||
| 516 | void play_sample(uint8_t * s, uint16_t l, bool r) { | ||
| 517 | if (!audio_initialized) { | ||
| 518 | audio_init(); | ||
| 519 | } | ||
| 520 | |||
| 521 | if (audio_config.enable) { | ||
| 522 | DISABLE_AUDIO_COUNTER_3_ISR; | ||
| 523 | stop_all_notes(); | ||
| 524 | place_int = 0; | ||
| 525 | sample = s; | ||
| 526 | sample_length = l; | ||
| 527 | repeat = r; | ||
| 528 | |||
| 529 | ENABLE_AUDIO_COUNTER_3_ISR; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | #endif | ||
| 533 | |||
| 534 | |||
| 535 | void audio_toggle(void) { | ||
| 536 | audio_config.enable ^= 1; | ||
| 537 | eeconfig_update_audio(audio_config.raw); | ||
| 538 | } | ||
| 539 | |||
| 540 | void audio_on(void) { | ||
| 541 | audio_config.enable = 1; | ||
| 542 | eeconfig_update_audio(audio_config.raw); | ||
| 543 | } | ||
| 544 | |||
| 545 | void audio_off(void) { | ||
| 546 | audio_config.enable = 0; | ||
| 547 | eeconfig_update_audio(audio_config.raw); | ||
| 548 | } | ||
| 549 | |||
| 550 | #ifdef VIBRATO_ENABLE | ||
| 551 | |||
| 552 | // Vibrato rate functions | ||
| 553 | |||
| 554 | void set_vibrato_rate(float rate) { | ||
| 555 | vibrato_rate = rate; | ||
| 556 | } | ||
| 557 | |||
| 558 | void increase_vibrato_rate(float change) { | ||
| 559 | vibrato_rate *= change; | ||
| 560 | } | ||
| 561 | |||
| 562 | void decrease_vibrato_rate(float change) { | ||
| 563 | vibrato_rate /= change; | ||
| 564 | } | ||
| 565 | |||
| 566 | #ifdef VIBRATO_STRENGTH_ENABLE | ||
| 567 | |||
| 568 | void set_vibrato_strength(float strength) { | ||
| 569 | vibrato_strength = strength; | ||
| 570 | } | ||
| 571 | |||
| 572 | void increase_vibrato_strength(float change) { | ||
| 573 | vibrato_strength *= change; | ||
| 574 | } | ||
| 575 | |||
| 576 | void decrease_vibrato_strength(float change) { | ||
| 577 | vibrato_strength /= change; | ||
| 578 | } | ||
| 579 | |||
| 580 | #endif /* VIBRATO_STRENGTH_ENABLE */ | ||
| 581 | |||
| 582 | #endif /* VIBRATO_ENABLE */ | ||
| 583 | |||
| 584 | // Polyphony functions | ||
| 585 | |||
| 586 | void set_polyphony_rate(float rate) { | ||
| 587 | polyphony_rate = rate; | ||
| 588 | } | ||
| 589 | |||
| 590 | void enable_polyphony() { | ||
| 591 | polyphony_rate = 5; | ||
| 592 | } | ||
| 593 | |||
| 594 | void disable_polyphony() { | ||
| 595 | polyphony_rate = 0; | ||
| 596 | } | ||
| 597 | |||
| 598 | void increase_polyphony_rate(float change) { | ||
| 599 | polyphony_rate *= change; | ||
| 600 | } | ||
| 601 | |||
| 602 | void decrease_polyphony_rate(float change) { | ||
| 603 | polyphony_rate /= change; | ||
| 604 | } | ||
| 605 | |||
| 606 | // Timbre function | ||
| 607 | |||
| 608 | void set_timbre(float timbre) { | ||
| 609 | note_timbre = timbre; | ||
| 610 | } | ||
| 611 | |||
| 612 | // Tempo functions | ||
| 613 | |||
| 614 | void set_tempo(uint8_t tempo) { | ||
| 615 | note_tempo = tempo; | ||
| 616 | } | ||
| 617 | |||
| 618 | void decrease_tempo(uint8_t tempo_change) { | ||
| 619 | note_tempo += tempo_change; | ||
| 620 | } | ||
| 621 | |||
| 622 | void increase_tempo(uint8_t tempo_change) { | ||
| 623 | if (note_tempo - tempo_change < 10) { | ||
| 624 | note_tempo = 10; | ||
| 625 | } else { | ||
| 626 | note_tempo -= tempo_change; | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 630 | |||
| 631 | //------------------------------------------------------------------------------ | ||
| 632 | // Override these functions in your keymap file to play different tunes on | ||
| 633 | // startup and bootloader jump | ||
| 634 | __attribute__ ((weak)) | ||
| 635 | void play_startup_tone() | ||
| 636 | { | ||
| 637 | } | ||
| 638 | |||
| 639 | __attribute__ ((weak)) | ||
| 640 | void play_goodbye_tone() | ||
| 641 | { | ||
| 642 | } | ||
| 643 | //------------------------------------------------------------------------------ | ||
diff --git a/quantum/audio/luts.c b/quantum/audio/luts.c new file mode 100644 index 000000000..9f3de9a05 --- /dev/null +++ b/quantum/audio/luts.c | |||
| @@ -0,0 +1,382 @@ | |||
| 1 | #include <avr/io.h> | ||
| 2 | #include <avr/interrupt.h> | ||
| 3 | #include <avr/pgmspace.h> | ||
| 4 | #include "luts.h" | ||
| 5 | |||
| 6 | const float vibrato_lut[VIBRATO_LUT_LENGTH] = | ||
| 7 | { | ||
| 8 | 1.0022336811487, | ||
| 9 | 1.0042529943610, | ||
| 10 | 1.0058584256028, | ||
| 11 | 1.0068905285205, | ||
| 12 | 1.0072464122237, | ||
| 13 | 1.0068905285205, | ||
| 14 | 1.0058584256028, | ||
| 15 | 1.0042529943610, | ||
| 16 | 1.0022336811487, | ||
| 17 | 1.0000000000000, | ||
| 18 | 0.9977712970630, | ||
| 19 | 0.9957650169978, | ||
| 20 | 0.9941756956510, | ||
| 21 | 0.9931566259436, | ||
| 22 | 0.9928057204913, | ||
| 23 | 0.9931566259436, | ||
| 24 | 0.9941756956510, | ||
| 25 | 0.9957650169978, | ||
| 26 | 0.9977712970630, | ||
| 27 | 1.0000000000000, | ||
| 28 | }; | ||
| 29 | |||
| 30 | const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH] = | ||
| 31 | { | ||
| 32 | 0x8E0B, | ||
| 33 | 0x8C02, | ||
| 34 | 0x8A00, | ||
| 35 | 0x8805, | ||
| 36 | 0x8612, | ||
| 37 | 0x8426, | ||
| 38 | 0x8241, | ||
| 39 | 0x8063, | ||
| 40 | 0x7E8C, | ||
| 41 | 0x7CBB, | ||
| 42 | 0x7AF2, | ||
| 43 | 0x792E, | ||
| 44 | 0x7772, | ||
| 45 | 0x75BB, | ||
| 46 | 0x740B, | ||
| 47 | 0x7261, | ||
| 48 | 0x70BD, | ||
| 49 | 0x6F20, | ||
| 50 | 0x6D88, | ||
| 51 | 0x6BF6, | ||
| 52 | 0x6A69, | ||
| 53 | 0x68E3, | ||
| 54 | 0x6762, | ||
| 55 | 0x65E6, | ||
| 56 | 0x6470, | ||
| 57 | 0x6300, | ||
| 58 | 0x6194, | ||
| 59 | 0x602E, | ||
| 60 | 0x5ECD, | ||
| 61 | 0x5D71, | ||
| 62 | 0x5C1A, | ||
| 63 | 0x5AC8, | ||
| 64 | 0x597B, | ||
| 65 | 0x5833, | ||
| 66 | 0x56EF, | ||
| 67 | 0x55B0, | ||
| 68 | 0x5475, | ||
| 69 | 0x533F, | ||
| 70 | 0x520E, | ||
| 71 | 0x50E1, | ||
| 72 | 0x4FB8, | ||
| 73 | 0x4E93, | ||
| 74 | 0x4D73, | ||
| 75 | 0x4C57, | ||
| 76 | 0x4B3E, | ||
| 77 | 0x4A2A, | ||
| 78 | 0x491A, | ||
| 79 | 0x480E, | ||
| 80 | 0x4705, | ||
| 81 | 0x4601, | ||
| 82 | 0x4500, | ||
| 83 | 0x4402, | ||
| 84 | 0x4309, | ||
| 85 | 0x4213, | ||
| 86 | 0x4120, | ||
| 87 | 0x4031, | ||
| 88 | 0x3F46, | ||
| 89 | 0x3E5D, | ||
| 90 | 0x3D79, | ||
| 91 | 0x3C97, | ||
| 92 | 0x3BB9, | ||
| 93 | 0x3ADD, | ||
| 94 | 0x3A05, | ||
| 95 | 0x3930, | ||
| 96 | 0x385E, | ||
| 97 | 0x3790, | ||
| 98 | 0x36C4, | ||
| 99 | 0x35FB, | ||
| 100 | 0x3534, | ||
| 101 | 0x3471, | ||
| 102 | 0x33B1, | ||
| 103 | 0x32F3, | ||
| 104 | 0x3238, | ||
| 105 | 0x3180, | ||
| 106 | 0x30CA, | ||
| 107 | 0x3017, | ||
| 108 | 0x2F66, | ||
| 109 | 0x2EB8, | ||
| 110 | 0x2E0D, | ||
| 111 | 0x2D64, | ||
| 112 | 0x2CBD, | ||
| 113 | 0x2C19, | ||
| 114 | 0x2B77, | ||
| 115 | 0x2AD8, | ||
| 116 | 0x2A3A, | ||
| 117 | 0x299F, | ||
| 118 | 0x2907, | ||
| 119 | 0x2870, | ||
| 120 | 0x27DC, | ||
| 121 | 0x2749, | ||
| 122 | 0x26B9, | ||
| 123 | 0x262B, | ||
| 124 | 0x259F, | ||
| 125 | 0x2515, | ||
| 126 | 0x248D, | ||
| 127 | 0x2407, | ||
| 128 | 0x2382, | ||
| 129 | 0x2300, | ||
| 130 | 0x2280, | ||
| 131 | 0x2201, | ||
| 132 | 0x2184, | ||
| 133 | 0x2109, | ||
| 134 | 0x2090, | ||
| 135 | 0x2018, | ||
| 136 | 0x1FA3, | ||
| 137 | 0x1F2E, | ||
| 138 | 0x1EBC, | ||
| 139 | 0x1E4B, | ||
| 140 | 0x1DDC, | ||
| 141 | 0x1D6E, | ||
| 142 | 0x1D02, | ||
| 143 | 0x1C98, | ||
| 144 | 0x1C2F, | ||
| 145 | 0x1BC8, | ||
| 146 | 0x1B62, | ||
| 147 | 0x1AFD, | ||
| 148 | 0x1A9A, | ||
| 149 | 0x1A38, | ||
| 150 | 0x19D8, | ||
| 151 | 0x1979, | ||
| 152 | 0x191C, | ||
| 153 | 0x18C0, | ||
| 154 | 0x1865, | ||
| 155 | 0x180B, | ||
| 156 | 0x17B3, | ||
| 157 | 0x175C, | ||
| 158 | 0x1706, | ||
| 159 | 0x16B2, | ||
| 160 | 0x165E, | ||
| 161 | 0x160C, | ||
| 162 | 0x15BB, | ||
| 163 | 0x156C, | ||
| 164 | 0x151D, | ||
| 165 | 0x14CF, | ||
| 166 | 0x1483, | ||
| 167 | 0x1438, | ||
| 168 | 0x13EE, | ||
| 169 | 0x13A4, | ||
| 170 | 0x135C, | ||
| 171 | 0x1315, | ||
| 172 | 0x12CF, | ||
| 173 | 0x128A, | ||
| 174 | 0x1246, | ||
| 175 | 0x1203, | ||
| 176 | 0x11C1, | ||
| 177 | 0x1180, | ||
| 178 | 0x1140, | ||
| 179 | 0x1100, | ||
| 180 | 0x10C2, | ||
| 181 | 0x1084, | ||
| 182 | 0x1048, | ||
| 183 | 0x100C, | ||
| 184 | 0xFD1, | ||
| 185 | 0xF97, | ||
| 186 | 0xF5E, | ||
| 187 | 0xF25, | ||
| 188 | 0xEEE, | ||
| 189 | 0xEB7, | ||
| 190 | 0xE81, | ||
| 191 | 0xE4C, | ||
| 192 | 0xE17, | ||
| 193 | 0xDE4, | ||
| 194 | 0xDB1, | ||
| 195 | 0xD7E, | ||
| 196 | 0xD4D, | ||
| 197 | 0xD1C, | ||
| 198 | 0xCEC, | ||
| 199 | 0xCBC, | ||
| 200 | 0xC8E, | ||
| 201 | 0xC60, | ||
| 202 | 0xC32, | ||
| 203 | 0xC05, | ||
| 204 | 0xBD9, | ||
| 205 | 0xBAE, | ||
| 206 | 0xB83, | ||
| 207 | 0xB59, | ||
| 208 | 0xB2F, | ||
| 209 | 0xB06, | ||
| 210 | 0xADD, | ||
| 211 | 0xAB6, | ||
| 212 | 0xA8E, | ||
| 213 | 0xA67, | ||
| 214 | 0xA41, | ||
| 215 | 0xA1C, | ||
| 216 | 0x9F7, | ||
| 217 | 0x9D2, | ||
| 218 | 0x9AE, | ||
| 219 | 0x98A, | ||
| 220 | 0x967, | ||
| 221 | 0x945, | ||
| 222 | 0x923, | ||
| 223 | 0x901, | ||
| 224 | 0x8E0, | ||
| 225 | 0x8C0, | ||
| 226 | 0x8A0, | ||
| 227 | 0x880, | ||
| 228 | 0x861, | ||
| 229 | 0x842, | ||
| 230 | 0x824, | ||
| 231 | 0x806, | ||
| 232 | 0x7E8, | ||
| 233 | 0x7CB, | ||
| 234 | 0x7AF, | ||
| 235 | 0x792, | ||
| 236 | 0x777, | ||
| 237 | 0x75B, | ||
| 238 | 0x740, | ||
| 239 | 0x726, | ||
| 240 | 0x70B, | ||
| 241 | 0x6F2, | ||
| 242 | 0x6D8, | ||
| 243 | 0x6BF, | ||
| 244 | 0x6A6, | ||
| 245 | 0x68E, | ||
| 246 | 0x676, | ||
| 247 | 0x65E, | ||
| 248 | 0x647, | ||
| 249 | 0x630, | ||
| 250 | 0x619, | ||
| 251 | 0x602, | ||
| 252 | 0x5EC, | ||
| 253 | 0x5D7, | ||
| 254 | 0x5C1, | ||
| 255 | 0x5AC, | ||
| 256 | 0x597, | ||
| 257 | 0x583, | ||
| 258 | 0x56E, | ||
| 259 | 0x55B, | ||
| 260 | 0x547, | ||
| 261 | 0x533, | ||
| 262 | 0x520, | ||
| 263 | 0x50E, | ||
| 264 | 0x4FB, | ||
| 265 | 0x4E9, | ||
| 266 | 0x4D7, | ||
| 267 | 0x4C5, | ||
| 268 | 0x4B3, | ||
| 269 | 0x4A2, | ||
| 270 | 0x491, | ||
| 271 | 0x480, | ||
| 272 | 0x470, | ||
| 273 | 0x460, | ||
| 274 | 0x450, | ||
| 275 | 0x440, | ||
| 276 | 0x430, | ||
| 277 | 0x421, | ||
| 278 | 0x412, | ||
| 279 | 0x403, | ||
| 280 | 0x3F4, | ||
| 281 | 0x3E5, | ||
| 282 | 0x3D7, | ||
| 283 | 0x3C9, | ||
| 284 | 0x3BB, | ||
| 285 | 0x3AD, | ||
| 286 | 0x3A0, | ||
| 287 | 0x393, | ||
| 288 | 0x385, | ||
| 289 | 0x379, | ||
| 290 | 0x36C, | ||
| 291 | 0x35F, | ||
| 292 | 0x353, | ||
| 293 | 0x347, | ||
| 294 | 0x33B, | ||
| 295 | 0x32F, | ||
| 296 | 0x323, | ||
| 297 | 0x318, | ||
| 298 | 0x30C, | ||
| 299 | 0x301, | ||
| 300 | 0x2F6, | ||
| 301 | 0x2EB, | ||
| 302 | 0x2E0, | ||
| 303 | 0x2D6, | ||
| 304 | 0x2CB, | ||
| 305 | 0x2C1, | ||
| 306 | 0x2B7, | ||
| 307 | 0x2AD, | ||
| 308 | 0x2A3, | ||
| 309 | 0x299, | ||
| 310 | 0x290, | ||
| 311 | 0x287, | ||
| 312 | 0x27D, | ||
| 313 | 0x274, | ||
| 314 | 0x26B, | ||
| 315 | 0x262, | ||
| 316 | 0x259, | ||
| 317 | 0x251, | ||
| 318 | 0x248, | ||
| 319 | 0x240, | ||
| 320 | 0x238, | ||
| 321 | 0x230, | ||
| 322 | 0x228, | ||
| 323 | 0x220, | ||
| 324 | 0x218, | ||
| 325 | 0x210, | ||
| 326 | 0x209, | ||
| 327 | 0x201, | ||
| 328 | 0x1FA, | ||
| 329 | 0x1F2, | ||
| 330 | 0x1EB, | ||
| 331 | 0x1E4, | ||
| 332 | 0x1DD, | ||
| 333 | 0x1D6, | ||
| 334 | 0x1D0, | ||
| 335 | 0x1C9, | ||
| 336 | 0x1C2, | ||
| 337 | 0x1BC, | ||
| 338 | 0x1B6, | ||
| 339 | 0x1AF, | ||
| 340 | 0x1A9, | ||
| 341 | 0x1A3, | ||
| 342 | 0x19D, | ||
| 343 | 0x197, | ||
| 344 | 0x191, | ||
| 345 | 0x18C, | ||
| 346 | 0x186, | ||
| 347 | 0x180, | ||
| 348 | 0x17B, | ||
| 349 | 0x175, | ||
| 350 | 0x170, | ||
| 351 | 0x16B, | ||
| 352 | 0x165, | ||
| 353 | 0x160, | ||
| 354 | 0x15B, | ||
| 355 | 0x156, | ||
| 356 | 0x151, | ||
| 357 | 0x14C, | ||
| 358 | 0x148, | ||
| 359 | 0x143, | ||
| 360 | 0x13E, | ||
| 361 | 0x13A, | ||
| 362 | 0x135, | ||
| 363 | 0x131, | ||
| 364 | 0x12C, | ||
| 365 | 0x128, | ||
| 366 | 0x124, | ||
| 367 | 0x120, | ||
| 368 | 0x11C, | ||
| 369 | 0x118, | ||
| 370 | 0x114, | ||
| 371 | 0x110, | ||
| 372 | 0x10C, | ||
| 373 | 0x108, | ||
| 374 | 0x104, | ||
| 375 | 0x100, | ||
| 376 | 0xFD, | ||
| 377 | 0xF9, | ||
| 378 | 0xF5, | ||
| 379 | 0xF2, | ||
| 380 | 0xEE, | ||
| 381 | }; | ||
| 382 | |||
diff --git a/quantum/audio/luts.h b/quantum/audio/luts.h new file mode 100644 index 000000000..7df3078a7 --- /dev/null +++ b/quantum/audio/luts.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | #include <avr/io.h> | ||
| 2 | #include <avr/interrupt.h> | ||
| 3 | #include <avr/pgmspace.h> | ||
| 4 | |||
| 5 | #ifndef LUTS_H | ||
| 6 | #define LUTS_H | ||
| 7 | |||
| 8 | #define VIBRATO_LUT_LENGTH 20 | ||
| 9 | |||
| 10 | #define FREQUENCY_LUT_LENGTH 349 | ||
| 11 | |||
| 12 | extern const float vibrato_lut[VIBRATO_LUT_LENGTH]; | ||
| 13 | extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH]; | ||
| 14 | |||
| 15 | #endif /* LUTS_H */ \ No newline at end of file | ||
diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h new file mode 100644 index 000000000..b08d16a6f --- /dev/null +++ b/quantum/audio/musical_notes.h | |||
| @@ -0,0 +1,217 @@ | |||
| 1 | #ifndef MUSICAL_NOTES_H | ||
| 2 | #define MUSICAL_NOTES_H | ||
| 3 | |||
| 4 | // Tempo Placeholder | ||
| 5 | #define TEMPO_DEFAULT 100 | ||
| 6 | |||
| 7 | |||
| 8 | #define SONG(notes...) { notes } | ||
| 9 | |||
| 10 | |||
| 11 | // Note Types | ||
| 12 | #define MUSICAL_NOTE(note, duration) {(NOTE##note), duration} | ||
| 13 | #define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) | ||
| 14 | #define HALF_NOTE(note) MUSICAL_NOTE(note, 32) | ||
| 15 | #define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) | ||
| 16 | #define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) | ||
| 17 | #define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) | ||
| 18 | |||
| 19 | #define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64+32) | ||
| 20 | #define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32+16) | ||
| 21 | #define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16+8) | ||
| 22 | #define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) | ||
| 23 | #define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) | ||
| 24 | |||
| 25 | // Note Type Shortcuts | ||
| 26 | #define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) | ||
| 27 | #define W__NOTE(n) WHOLE_NOTE(n) | ||
| 28 | #define H__NOTE(n) HALF_NOTE(n) | ||
| 29 | #define Q__NOTE(n) QUARTER_NOTE(n) | ||
| 30 | #define E__NOTE(n) EIGHTH_NOTE(n) | ||
| 31 | #define S__NOTE(n) SIXTEENTH_NOTE(n) | ||
| 32 | #define WD_NOTE(n) WHOLE_DOT_NOTE(n) | ||
| 33 | #define HD_NOTE(n) HALF_DOT_NOTE(n) | ||
| 34 | #define QD_NOTE(n) QUARTER_DOT_NOTE(n) | ||
| 35 | #define ED_NOTE(n) EIGHTH_DOT_NOTE(n) | ||
| 36 | #define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) | ||
| 37 | |||
| 38 | // Note Styles | ||
| 39 | // Staccato makes sure there is a rest between each note. Think: TA TA TA | ||
| 40 | // Legato makes notes flow together. Think: TAAA | ||
| 41 | #define STACCATO 0.01 | ||
| 42 | #define LEGATO 0 | ||
| 43 | |||
| 44 | // Note Timbre | ||
| 45 | // Changes how the notes sound | ||
| 46 | #define TIMBRE_12 0.125 | ||
| 47 | #define TIMBRE_25 0.250 | ||
| 48 | #define TIMBRE_50 0.500 | ||
| 49 | #define TIMBRE_75 0.750 | ||
| 50 | #define TIMBRE_DEFAULT TIMBRE_50 | ||
| 51 | |||
| 52 | |||
| 53 | // Notes - # = Octave | ||
| 54 | |||
| 55 | #define NOTE_REST 0.00 | ||
| 56 | |||
| 57 | /* These notes are currently bugged | ||
| 58 | #define NOTE_C0 16.35 | ||
| 59 | #define NOTE_CS0 17.32 | ||
| 60 | #define NOTE_D0 18.35 | ||
| 61 | #define NOTE_DS0 19.45 | ||
| 62 | #define NOTE_E0 20.60 | ||
| 63 | #define NOTE_F0 21.83 | ||
| 64 | #define NOTE_FS0 23.12 | ||
| 65 | #define NOTE_G0 24.50 | ||
| 66 | #define NOTE_GS0 25.96 | ||
| 67 | #define NOTE_A0 27.50 | ||
| 68 | #define NOTE_AS0 29.14 | ||
| 69 | #define NOTE_B0 30.87 | ||
| 70 | #define NOTE_C1 32.70 | ||
| 71 | #define NOTE_CS1 34.65 | ||
| 72 | #define NOTE_D1 36.71 | ||
| 73 | #define NOTE_DS1 38.89 | ||
| 74 | #define NOTE_E1 41.20 | ||
| 75 | #define NOTE_F1 43.65 | ||
| 76 | #define NOTE_FS1 46.25 | ||
| 77 | #define NOTE_G1 49.00 | ||
| 78 | #define NOTE_GS1 51.91 | ||
| 79 | #define NOTE_A1 55.00 | ||
| 80 | #define NOTE_AS1 58.27 | ||
| 81 | */ | ||
| 82 | |||
| 83 | #define NOTE_B1 61.74 | ||
| 84 | #define NOTE_C2 65.41 | ||
| 85 | #define NOTE_CS2 69.30 | ||
| 86 | #define NOTE_D2 73.42 | ||
| 87 | #define NOTE_DS2 77.78 | ||
| 88 | #define NOTE_E2 82.41 | ||
| 89 | #define NOTE_F2 87.31 | ||
| 90 | #define NOTE_FS2 92.50 | ||
| 91 | #define NOTE_G2 98.00 | ||
| 92 | #define NOTE_GS2 103.83 | ||
| 93 | #define NOTE_A2 110.00 | ||
| 94 | #define NOTE_AS2 116.54 | ||
| 95 | #define NOTE_B2 123.47 | ||
| 96 | #define NOTE_C3 130.81 | ||
| 97 | #define NOTE_CS3 138.59 | ||
| 98 | #define NOTE_D3 146.83 | ||
| 99 | #define NOTE_DS3 155.56 | ||
| 100 | #define NOTE_E3 164.81 | ||
| 101 | #define NOTE_F3 174.61 | ||
| 102 | #define NOTE_FS3 185.00 | ||
| 103 | #define NOTE_G3 196.00 | ||
| 104 | #define NOTE_GS3 207.65 | ||
| 105 | #define NOTE_A3 220.00 | ||
| 106 | #define NOTE_AS3 233.08 | ||
| 107 | #define NOTE_B3 246.94 | ||
| 108 | #define NOTE_C4 261.63 | ||
| 109 | #define NOTE_CS4 277.18 | ||
| 110 | #define NOTE_D4 293.66 | ||
| 111 | #define NOTE_DS4 311.13 | ||
| 112 | #define NOTE_E4 329.63 | ||
| 113 | #define NOTE_F4 349.23 | ||
| 114 | #define NOTE_FS4 369.99 | ||
| 115 | #define NOTE_G4 392.00 | ||
| 116 | #define NOTE_GS4 415.30 | ||
| 117 | #define NOTE_A4 440.00 | ||
| 118 | #define NOTE_AS4 466.16 | ||
| 119 | #define NOTE_B4 493.88 | ||
| 120 | #define NOTE_C5 523.25 | ||
| 121 | #define NOTE_CS5 554.37 | ||
| 122 | #define NOTE_D5 587.33 | ||
| 123 | #define NOTE_DS5 622.25 | ||
| 124 | #define NOTE_E5 659.26 | ||
| 125 | #define NOTE_F5 698.46 | ||
| 126 | #define NOTE_FS5 739.99 | ||
| 127 | #define NOTE_G5 783.99 | ||
| 128 | #define NOTE_GS5 830.61 | ||
| 129 | #define NOTE_A5 880.00 | ||
| 130 | #define NOTE_AS5 932.33 | ||
| 131 | #define NOTE_B5 987.77 | ||
| 132 | #define NOTE_C6 1046.50 | ||
| 133 | #define NOTE_CS6 1108.73 | ||
| 134 | #define NOTE_D6 1174.66 | ||
| 135 | #define NOTE_DS6 1244.51 | ||
| 136 | #define NOTE_E6 1318.51 | ||
| 137 | #define NOTE_F6 1396.91 | ||
| 138 | #define NOTE_FS6 1479.98 | ||
| 139 | #define NOTE_G6 1567.98 | ||
| 140 | #define NOTE_GS6 1661.22 | ||
| 141 | #define NOTE_A6 1760.00 | ||
| 142 | #define NOTE_AS6 1864.66 | ||
| 143 | #define NOTE_B6 1975.53 | ||
| 144 | #define NOTE_C7 2093.00 | ||
| 145 | #define NOTE_CS7 2217.46 | ||
| 146 | #define NOTE_D7 2349.32 | ||
| 147 | #define NOTE_DS7 2489.02 | ||
| 148 | #define NOTE_E7 2637.02 | ||
| 149 | #define NOTE_F7 2793.83 | ||
| 150 | #define NOTE_FS7 2959.96 | ||
| 151 | #define NOTE_G7 3135.96 | ||
| 152 | #define NOTE_GS7 3322.44 | ||
| 153 | #define NOTE_A7 3520.00 | ||
| 154 | #define NOTE_AS7 3729.31 | ||
| 155 | #define NOTE_B7 3951.07 | ||
| 156 | #define NOTE_C8 4186.01 | ||
| 157 | #define NOTE_CS8 4434.92 | ||
| 158 | #define NOTE_D8 4698.64 | ||
| 159 | #define NOTE_DS8 4978.03 | ||
| 160 | #define NOTE_E8 5274.04 | ||
| 161 | #define NOTE_F8 5587.65 | ||
| 162 | #define NOTE_FS8 5919.91 | ||
| 163 | #define NOTE_G8 6271.93 | ||
| 164 | #define NOTE_GS8 6644.88 | ||
| 165 | #define NOTE_A8 7040.00 | ||
| 166 | #define NOTE_AS8 7458.62 | ||
| 167 | #define NOTE_B8 7902.13 | ||
| 168 | |||
| 169 | // Flat Aliases | ||
| 170 | #define NOTE_DF0 NOTE_CS0 | ||
| 171 | #define NOTE_EF0 NOTE_DS0 | ||
| 172 | #define NOTE_GF0 NOTE_FS0 | ||
| 173 | #define NOTE_AF0 NOTE_GS0 | ||
| 174 | #define NOTE_BF0 NOTE_AS0 | ||
| 175 | #define NOTE_DF1 NOTE_CS1 | ||
| 176 | #define NOTE_EF1 NOTE_DS1 | ||
| 177 | #define NOTE_GF1 NOTE_FS1 | ||
| 178 | #define NOTE_AF1 NOTE_GS1 | ||
| 179 | #define NOTE_BF1 NOTE_AS1 | ||
| 180 | #define NOTE_DF2 NOTE_CS2 | ||
| 181 | #define NOTE_EF2 NOTE_DS2 | ||
| 182 | #define NOTE_GF2 NOTE_FS2 | ||
| 183 | #define NOTE_AF2 NOTE_GS2 | ||
| 184 | #define NOTE_BF2 NOTE_AS2 | ||
| 185 | #define NOTE_DF3 NOTE_CS3 | ||
| 186 | #define NOTE_EF3 NOTE_DS3 | ||
| 187 | #define NOTE_GF3 NOTE_FS3 | ||
| 188 | #define NOTE_AF3 NOTE_GS3 | ||
| 189 | #define NOTE_BF3 NOTE_AS3 | ||
| 190 | #define NOTE_DF4 NOTE_CS4 | ||
| 191 | #define NOTE_EF4 NOTE_DS4 | ||
| 192 | #define NOTE_GF4 NOTE_FS4 | ||
| 193 | #define NOTE_AF4 NOTE_GS4 | ||
| 194 | #define NOTE_BF4 NOTE_AS4 | ||
| 195 | #define NOTE_DF5 NOTE_CS5 | ||
| 196 | #define NOTE_EF5 NOTE_DS5 | ||
| 197 | #define NOTE_GF5 NOTE_FS5 | ||
| 198 | #define NOTE_AF5 NOTE_GS5 | ||
| 199 | #define NOTE_BF5 NOTE_AS5 | ||
| 200 | #define NOTE_DF6 NOTE_CS6 | ||
| 201 | #define NOTE_EF6 NOTE_DS6 | ||
| 202 | #define NOTE_GF6 NOTE_FS6 | ||
| 203 | #define NOTE_AF6 NOTE_GS6 | ||
| 204 | #define NOTE_BF6 NOTE_AS6 | ||
| 205 | #define NOTE_DF7 NOTE_CS7 | ||
| 206 | #define NOTE_EF7 NOTE_DS7 | ||
| 207 | #define NOTE_GF7 NOTE_FS7 | ||
| 208 | #define NOTE_AF7 NOTE_GS7 | ||
| 209 | #define NOTE_BF7 NOTE_AS7 | ||
| 210 | #define NOTE_DF8 NOTE_CS8 | ||
| 211 | #define NOTE_EF8 NOTE_DS8 | ||
| 212 | #define NOTE_GF8 NOTE_FS8 | ||
| 213 | #define NOTE_AF8 NOTE_GS8 | ||
| 214 | #define NOTE_BF8 NOTE_AS8 | ||
| 215 | |||
| 216 | |||
| 217 | #endif \ No newline at end of file | ||
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h new file mode 100644 index 000000000..fc6fcdeef --- /dev/null +++ b/quantum/audio/song_list.h | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | #include "musical_notes.h" | ||
| 2 | |||
| 3 | #ifndef SONG_LIST_H | ||
| 4 | #define SONG_LIST_H | ||
| 5 | |||
| 6 | #define ODE_TO_JOY \ | ||
| 7 | Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ | ||
| 8 | Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ | ||
| 9 | Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ | ||
| 10 | QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), | ||
| 11 | |||
| 12 | #define ROCK_A_BYE_BABY \ | ||
| 13 | QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ | ||
| 14 | H__NOTE(_A5), Q__NOTE(_G5), \ | ||
| 15 | QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ | ||
| 16 | H__NOTE(_FS5), | ||
| 17 | |||
| 18 | #define CLOSE_ENCOUNTERS_5_NOTE \ | ||
| 19 | Q__NOTE(_D5), \ | ||
| 20 | Q__NOTE(_E5), \ | ||
| 21 | Q__NOTE(_C5), \ | ||
| 22 | Q__NOTE(_C4), \ | ||
| 23 | Q__NOTE(_G4), | ||
| 24 | |||
| 25 | #define DOE_A_DEER \ | ||
| 26 | QD_NOTE(_C4), E__NOTE(_D4), \ | ||
| 27 | QD_NOTE(_E4), E__NOTE(_C4), \ | ||
| 28 | Q__NOTE(_E4), Q__NOTE(_C4), \ | ||
| 29 | Q__NOTE(_E4), | ||
| 30 | |||
| 31 | #define GOODBYE_SOUND \ | ||
| 32 | E__NOTE(_E7), \ | ||
| 33 | E__NOTE(_A6), \ | ||
| 34 | ED_NOTE(_E6), | ||
| 35 | |||
| 36 | #define STARTUP_SOUND \ | ||
| 37 | ED_NOTE(_E7 ), \ | ||
| 38 | E__NOTE(_CS7), \ | ||
| 39 | E__NOTE(_E6 ), \ | ||
| 40 | E__NOTE(_A6 ), \ | ||
| 41 | M__NOTE(_CS7, 20), | ||
| 42 | |||
| 43 | #define QWERTY_SOUND \ | ||
| 44 | E__NOTE(_GS6 ), \ | ||
| 45 | E__NOTE(_A6 ), \ | ||
| 46 | S__NOTE(_REST), \ | ||
| 47 | Q__NOTE(_E7 ), | ||
| 48 | |||
| 49 | #define COLEMAK_SOUND \ | ||
| 50 | E__NOTE(_GS6 ), \ | ||
| 51 | E__NOTE(_A6 ), \ | ||
| 52 | S__NOTE(_REST), \ | ||
| 53 | ED_NOTE(_E7 ), \ | ||
| 54 | S__NOTE(_REST), \ | ||
| 55 | ED_NOTE(_GS7 ), | ||
| 56 | |||
| 57 | #define DVORAK_SOUND \ | ||
| 58 | E__NOTE(_GS6 ), \ | ||
| 59 | E__NOTE(_A6 ), \ | ||
| 60 | S__NOTE(_REST), \ | ||
| 61 | E__NOTE(_E7 ), \ | ||
| 62 | S__NOTE(_REST), \ | ||
| 63 | E__NOTE(_FS7 ), \ | ||
| 64 | S__NOTE(_REST), \ | ||
| 65 | E__NOTE(_E7 ), | ||
| 66 | |||
| 67 | #define PLOVER_SOUND \ | ||
| 68 | E__NOTE(_GS6 ), \ | ||
| 69 | E__NOTE(_A6 ), \ | ||
| 70 | S__NOTE(_REST), \ | ||
| 71 | ED_NOTE(_E7 ), \ | ||
| 72 | S__NOTE(_REST), \ | ||
| 73 | ED_NOTE(_A7 ), | ||
| 74 | |||
| 75 | #define PLOVER_GOODBYE_SOUND \ | ||
| 76 | E__NOTE(_GS6 ), \ | ||
| 77 | E__NOTE(_A6 ), \ | ||
| 78 | S__NOTE(_REST), \ | ||
| 79 | ED_NOTE(_A7 ), \ | ||
| 80 | S__NOTE(_REST), \ | ||
| 81 | ED_NOTE(_E7 ), | ||
| 82 | |||
| 83 | #define MUSIC_SCALE_SOUND \ | ||
| 84 | E__NOTE(_A5 ), \ | ||
| 85 | E__NOTE(_B5 ), \ | ||
| 86 | E__NOTE(_CS6), \ | ||
| 87 | E__NOTE(_D6 ), \ | ||
| 88 | E__NOTE(_E6 ), \ | ||
| 89 | E__NOTE(_FS6), \ | ||
| 90 | E__NOTE(_GS6), \ | ||
| 91 | E__NOTE(_A6 ), | ||
| 92 | |||
| 93 | #define CAPS_LOCK_ON_SOUND \ | ||
| 94 | E__NOTE(_A3), \ | ||
| 95 | E__NOTE(_B3), | ||
| 96 | |||
| 97 | #define CAPS_LOCK_OFF_SOUND \ | ||
| 98 | E__NOTE(_B3), \ | ||
| 99 | E__NOTE(_A3), | ||
| 100 | |||
| 101 | #define SCROLL_LOCK_ON_SOUND \ | ||
| 102 | E__NOTE(_D4), \ | ||
| 103 | E__NOTE(_E4), | ||
| 104 | |||
| 105 | #define SCROLL_LOCK_OFF_SOUND \ | ||
| 106 | E__NOTE(_E4), \ | ||
| 107 | E__NOTE(_D4), | ||
| 108 | |||
| 109 | #define NUM_LOCK_ON_SOUND \ | ||
| 110 | E__NOTE(_D5), \ | ||
| 111 | E__NOTE(_E5), | ||
| 112 | |||
| 113 | #define NUM_LOCK_OFF_SOUND \ | ||
| 114 | E__NOTE(_E5), \ | ||
| 115 | E__NOTE(_D5), | ||
| 116 | |||
| 117 | #endif | ||
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c new file mode 100644 index 000000000..6d4172a06 --- /dev/null +++ b/quantum/audio/voices.c | |||
| @@ -0,0 +1,165 @@ | |||
| 1 | #include "voices.h" | ||
| 2 | #include "audio.h" | ||
| 3 | #include "stdlib.h" | ||
| 4 | |||
| 5 | // these are imported from audio.c | ||
| 6 | extern uint16_t envelope_index; | ||
| 7 | extern float note_timbre; | ||
| 8 | extern float polyphony_rate; | ||
| 9 | |||
| 10 | voice_type voice = default_voice; | ||
| 11 | |||
| 12 | void set_voice(voice_type v) { | ||
| 13 | voice = v; | ||
| 14 | } | ||
| 15 | |||
| 16 | void voice_iterate() { | ||
| 17 | voice = (voice + 1) % number_of_voices; | ||
| 18 | } | ||
| 19 | |||
| 20 | void voice_deiterate() { | ||
| 21 | voice = (voice - 1) % number_of_voices; | ||
| 22 | } | ||
| 23 | |||
| 24 | float voice_envelope(float frequency) { | ||
| 25 | // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz | ||
| 26 | uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); | ||
| 27 | |||
| 28 | switch (voice) { | ||
| 29 | case default_voice: | ||
| 30 | note_timbre = TIMBRE_50; | ||
| 31 | polyphony_rate = 0; | ||
| 32 | break; | ||
| 33 | |||
| 34 | case butts_fader: | ||
| 35 | polyphony_rate = 0; | ||
| 36 | switch (compensated_index) { | ||
| 37 | case 0 ... 9: | ||
| 38 | frequency = frequency / 4; | ||
| 39 | note_timbre = TIMBRE_12; | ||
| 40 | break; | ||
| 41 | |||
| 42 | case 10 ... 19: | ||
| 43 | frequency = frequency / 2; | ||
| 44 | note_timbre = TIMBRE_12; | ||
| 45 | break; | ||
| 46 | |||
| 47 | case 20 ... 200: | ||
| 48 | note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; | ||
| 49 | break; | ||
| 50 | |||
| 51 | default: | ||
| 52 | note_timbre = 0; | ||
| 53 | break; | ||
| 54 | } | ||
| 55 | break; | ||
| 56 | |||
| 57 | // case octave_crunch: | ||
| 58 | // polyphony_rate = 0; | ||
| 59 | // switch (compensated_index) { | ||
| 60 | // case 0 ... 9: | ||
| 61 | // case 20 ... 24: | ||
| 62 | // case 30 ... 32: | ||
| 63 | // frequency = frequency / 2; | ||
| 64 | // note_timbre = TIMBRE_12; | ||
| 65 | // break; | ||
| 66 | |||
| 67 | // case 10 ... 19: | ||
| 68 | // case 25 ... 29: | ||
| 69 | // case 33 ... 35: | ||
| 70 | // frequency = frequency * 2; | ||
| 71 | // note_timbre = TIMBRE_12; | ||
| 72 | // break; | ||
| 73 | |||
| 74 | // default: | ||
| 75 | // note_timbre = TIMBRE_12; | ||
| 76 | // break; | ||
| 77 | // } | ||
| 78 | // break; | ||
| 79 | |||
| 80 | case duty_osc: | ||
| 81 | // This slows the loop down a substantial amount, so higher notes may freeze | ||
| 82 | polyphony_rate = 0; | ||
| 83 | switch (compensated_index) { | ||
| 84 | default: | ||
| 85 | #define OCS_SPEED 10 | ||
| 86 | #define OCS_AMP .25 | ||
| 87 | // sine wave is slow | ||
| 88 | // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; | ||
| 89 | // triangle wave is a bit faster | ||
| 90 | note_timbre = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; | ||
| 91 | break; | ||
| 92 | } | ||
| 93 | break; | ||
| 94 | |||
| 95 | case duty_octave_down: | ||
| 96 | polyphony_rate = 0; | ||
| 97 | note_timbre = (envelope_index % 2) * .125 + .375 * 2; | ||
| 98 | if ((envelope_index % 4) == 0) | ||
| 99 | note_timbre = 0.5; | ||
| 100 | if ((envelope_index % 8) == 0) | ||
| 101 | note_timbre = 0; | ||
| 102 | break; | ||
| 103 | case delayed_vibrato: | ||
| 104 | polyphony_rate = 0; | ||
| 105 | note_timbre = TIMBRE_50; | ||
| 106 | #define VOICE_VIBRATO_DELAY 150 | ||
| 107 | #define VOICE_VIBRATO_SPEED 50 | ||
| 108 | switch (compensated_index) { | ||
| 109 | case 0 ... VOICE_VIBRATO_DELAY: | ||
| 110 | break; | ||
| 111 | default: | ||
| 112 | frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; | ||
| 113 | break; | ||
| 114 | } | ||
| 115 | break; | ||
| 116 | // case delayed_vibrato_octave: | ||
| 117 | // polyphony_rate = 0; | ||
| 118 | // if ((envelope_index % 2) == 1) { | ||
| 119 | // note_timbre = 0.55; | ||
| 120 | // } else { | ||
| 121 | // note_timbre = 0.45; | ||
| 122 | // } | ||
| 123 | // #define VOICE_VIBRATO_DELAY 150 | ||
| 124 | // #define VOICE_VIBRATO_SPEED 50 | ||
| 125 | // switch (compensated_index) { | ||
| 126 | // case 0 ... VOICE_VIBRATO_DELAY: | ||
| 127 | // break; | ||
| 128 | // default: | ||
| 129 | // frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; | ||
| 130 | // break; | ||
| 131 | // } | ||
| 132 | // break; | ||
| 133 | // case duty_fifth_down: | ||
| 134 | // note_timbre = 0.5; | ||
| 135 | // if ((envelope_index % 3) == 0) | ||
| 136 | // note_timbre = 0.75; | ||
| 137 | // break; | ||
| 138 | // case duty_fourth_down: | ||
| 139 | // note_timbre = 0.0; | ||
| 140 | // if ((envelope_index % 12) == 0) | ||
| 141 | // note_timbre = 0.75; | ||
| 142 | // if (((envelope_index % 12) % 4) != 1) | ||
| 143 | // note_timbre = 0.75; | ||
| 144 | // break; | ||
| 145 | // case duty_third_down: | ||
| 146 | // note_timbre = 0.5; | ||
| 147 | // if ((envelope_index % 5) == 0) | ||
| 148 | // note_timbre = 0.75; | ||
| 149 | // break; | ||
| 150 | // case duty_fifth_third_down: | ||
| 151 | // note_timbre = 0.5; | ||
| 152 | // if ((envelope_index % 5) == 0) | ||
| 153 | // note_timbre = 0.75; | ||
| 154 | // if ((envelope_index % 3) == 0) | ||
| 155 | // note_timbre = 0.25; | ||
| 156 | // break; | ||
| 157 | |||
| 158 | default: | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | |||
| 162 | return frequency; | ||
| 163 | } | ||
| 164 | |||
| 165 | |||
diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h new file mode 100644 index 000000000..b2495b23b --- /dev/null +++ b/quantum/audio/voices.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #include <stdint.h> | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include <avr/io.h> | ||
| 4 | #include <util/delay.h> | ||
| 5 | #include "luts.h" | ||
| 6 | |||
| 7 | #ifndef VOICES_H | ||
| 8 | #define VOICES_H | ||
| 9 | |||
| 10 | float voice_envelope(float frequency); | ||
| 11 | |||
| 12 | typedef enum { | ||
| 13 | default_voice, | ||
| 14 | butts_fader, | ||
| 15 | octave_crunch, | ||
| 16 | duty_osc, | ||
| 17 | duty_octave_down, | ||
| 18 | delayed_vibrato, | ||
| 19 | // delayed_vibrato_octave, | ||
| 20 | // duty_fifth_down, | ||
| 21 | // duty_fourth_down, | ||
| 22 | // duty_third_down, | ||
| 23 | // duty_fifth_third_down, | ||
| 24 | number_of_voices // important that this is last | ||
| 25 | } voice_type; | ||
| 26 | |||
| 27 | void set_voice(voice_type v); | ||
| 28 | void voice_iterate(void); | ||
| 29 | void voice_deiterate(void); | ||
| 30 | |||
| 31 | #endif \ No newline at end of file | ||
diff --git a/quantum/audio/wave.h b/quantum/audio/wave.h new file mode 100644 index 000000000..6ebc34851 --- /dev/null +++ b/quantum/audio/wave.h | |||
| @@ -0,0 +1,265 @@ | |||
| 1 | #include <avr/io.h> | ||
| 2 | #include <avr/interrupt.h> | ||
| 3 | #include <avr/pgmspace.h> | ||
| 4 | |||
| 5 | #define SINE_LENGTH 2048 | ||
| 6 | |||
| 7 | const uint8_t sinewave[] PROGMEM= //2048 values | ||
| 8 | { | ||
| 9 | 0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82, | ||
| 10 | 0x83,0x83,0x83,0x84,0x84,0x85,0x85,0x85, | ||
| 11 | 0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88, | ||
| 12 | 0x89,0x89,0x8a,0x8a,0x8a,0x8b,0x8b,0x8c, | ||
| 13 | 0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f, | ||
| 14 | 0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92, | ||
| 15 | 0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95, | ||
| 16 | 0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98, | ||
| 17 | 0x98,0x99,0x99,0x9a,0x9a,0x9a,0x9b,0x9b, | ||
| 18 | 0x9b,0x9c,0x9c,0x9d,0x9d,0x9d,0x9e,0x9e, | ||
| 19 | 0x9e,0x9f,0x9f,0xa0,0xa0,0xa0,0xa1,0xa1, | ||
| 20 | 0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4, | ||
| 21 | 0xa5,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7, | ||
| 22 | 0xa7,0xa8,0xa8,0xa9,0xa9,0xa9,0xaa,0xaa, | ||
| 23 | 0xaa,0xab,0xab,0xac,0xac,0xac,0xad,0xad, | ||
| 24 | 0xad,0xae,0xae,0xae,0xaf,0xaf,0xb0,0xb0, | ||
| 25 | 0xb0,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb3, | ||
| 26 | 0xb3,0xb4,0xb4,0xb4,0xb5,0xb5,0xb5,0xb6, | ||
| 27 | 0xb6,0xb6,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8, | ||
| 28 | 0xb9,0xb9,0xba,0xba,0xba,0xbb,0xbb,0xbb, | ||
| 29 | 0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbe,0xbe, | ||
| 30 | 0xbe,0xbf,0xbf,0xbf,0xc0,0xc0,0xc0,0xc1, | ||
| 31 | 0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3, | ||
| 32 | 0xc4,0xc4,0xc4,0xc5,0xc5,0xc5,0xc6,0xc6, | ||
| 33 | 0xc6,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc9, | ||
| 34 | 0xc9,0xc9,0xca,0xca,0xca,0xcb,0xcb,0xcb, | ||
| 35 | 0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce, | ||
| 36 | 0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xd0,0xd0, | ||
| 37 | 0xd0,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2, | ||
| 38 | 0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd5,0xd5, | ||
| 39 | 0xd5,0xd5,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7, | ||
| 40 | 0xd7,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9, | ||
| 41 | 0xda,0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdc, | ||
| 42 | 0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xde, | ||
| 43 | 0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xe0, | ||
| 44 | 0xe0,0xe0,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2, | ||
| 45 | 0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe4,0xe4, | ||
| 46 | 0xe4,0xe4,0xe4,0xe5,0xe5,0xe5,0xe5,0xe6, | ||
| 47 | 0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe8, | ||
| 48 | 0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9, | ||
| 49 | 0xea,0xea,0xea,0xea,0xea,0xeb,0xeb,0xeb, | ||
| 50 | 0xeb,0xeb,0xec,0xec,0xec,0xec,0xec,0xed, | ||
| 51 | 0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee, | ||
| 52 | 0xee,0xef,0xef,0xef,0xef,0xef,0xf0,0xf0, | ||
| 53 | 0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf1, | ||
| 54 | 0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3, | ||
| 55 | 0xf3,0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4, | ||
| 56 | 0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5, | ||
| 57 | 0xf5,0xf5,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6, | ||
| 58 | 0xf6,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, | ||
| 59 | 0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, | ||
| 60 | 0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, | ||
| 61 | 0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, | ||
| 62 | 0xfa,0xfa,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb, | ||
| 63 | 0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc, | ||
| 64 | 0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, | ||
| 65 | 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, | ||
| 66 | 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe, | ||
| 67 | 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||
| 68 | 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||
| 69 | 0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff, | ||
| 70 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||
| 71 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||
| 72 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||
| 73 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||
| 74 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||
| 75 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||
| 76 | 0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe, | ||
| 77 | 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||
| 78 | 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, | ||
| 79 | 0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd, | ||
| 80 | 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, | ||
| 81 | 0xfd,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, | ||
| 82 | 0xfc,0xfc,0xfc,0xfc,0xfc,0xfb,0xfb,0xfb, | ||
| 83 | 0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfa, | ||
| 84 | 0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, | ||
| 85 | 0xfa,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, | ||
| 86 | 0xf9,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, | ||
| 87 | 0xf8,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, | ||
| 88 | 0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf5, | ||
| 89 | 0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf4,0xf4, | ||
| 90 | 0xf4,0xf4,0xf4,0xf4,0xf3,0xf3,0xf3,0xf3, | ||
| 91 | 0xf3,0xf3,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2, | ||
| 92 | 0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xf0,0xf0, | ||
| 93 | 0xf0,0xf0,0xf0,0xef,0xef,0xef,0xef,0xef, | ||
| 94 | 0xee,0xee,0xee,0xee,0xee,0xed,0xed,0xed, | ||
| 95 | 0xed,0xed,0xec,0xec,0xec,0xec,0xec,0xeb, | ||
| 96 | 0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea, | ||
| 97 | 0xea,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8, | ||
| 98 | 0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6, | ||
| 99 | 0xe6,0xe6,0xe5,0xe5,0xe5,0xe5,0xe4,0xe4, | ||
| 100 | 0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe3,0xe2, | ||
| 101 | 0xe2,0xe2,0xe2,0xe1,0xe1,0xe1,0xe1,0xe0, | ||
| 102 | 0xe0,0xe0,0xe0,0xdf,0xdf,0xdf,0xde,0xde, | ||
| 103 | 0xde,0xde,0xdd,0xdd,0xdd,0xdd,0xdc,0xdc, | ||
| 104 | 0xdc,0xdc,0xdb,0xdb,0xdb,0xda,0xda,0xda, | ||
| 105 | 0xda,0xd9,0xd9,0xd9,0xd9,0xd8,0xd8,0xd8, | ||
| 106 | 0xd7,0xd7,0xd7,0xd7,0xd6,0xd6,0xd6,0xd5, | ||
| 107 | 0xd5,0xd5,0xd5,0xd4,0xd4,0xd4,0xd3,0xd3, | ||
| 108 | 0xd3,0xd2,0xd2,0xd2,0xd2,0xd1,0xd1,0xd1, | ||
| 109 | 0xd0,0xd0,0xd0,0xcf,0xcf,0xcf,0xcf,0xce, | ||
| 110 | 0xce,0xce,0xcd,0xcd,0xcd,0xcc,0xcc,0xcc, | ||
| 111 | 0xcb,0xcb,0xcb,0xcb,0xca,0xca,0xca,0xc9, | ||
| 112 | 0xc9,0xc9,0xc8,0xc8,0xc8,0xc7,0xc7,0xc7, | ||
| 113 | 0xc6,0xc6,0xc6,0xc5,0xc5,0xc5,0xc4,0xc4, | ||
| 114 | 0xc4,0xc3,0xc3,0xc3,0xc2,0xc2,0xc2,0xc1, | ||
| 115 | 0xc1,0xc1,0xc0,0xc0,0xc0,0xbf,0xbf,0xbf, | ||
| 116 | 0xbe,0xbe,0xbe,0xbd,0xbd,0xbd,0xbc,0xbc, | ||
| 117 | 0xbc,0xbb,0xbb,0xbb,0xba,0xba,0xba,0xb9, | ||
| 118 | 0xb9,0xb8,0xb8,0xb8,0xb7,0xb7,0xb7,0xb6, | ||
| 119 | 0xb6,0xb6,0xb5,0xb5,0xb5,0xb4,0xb4,0xb4, | ||
| 120 | 0xb3,0xb3,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1, | ||
| 121 | 0xb0,0xb0,0xb0,0xaf,0xaf,0xae,0xae,0xae, | ||
| 122 | 0xad,0xad,0xad,0xac,0xac,0xac,0xab,0xab, | ||
| 123 | 0xaa,0xaa,0xaa,0xa9,0xa9,0xa9,0xa8,0xa8, | ||
| 124 | 0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa5,0xa5, | ||
| 125 | 0xa5,0xa4,0xa4,0xa3,0xa3,0xa3,0xa2,0xa2, | ||
| 126 | 0xa2,0xa1,0xa1,0xa0,0xa0,0xa0,0x9f,0x9f, | ||
| 127 | 0x9e,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9c, | ||
| 128 | 0x9b,0x9b,0x9b,0x9a,0x9a,0x9a,0x99,0x99, | ||
| 129 | 0x98,0x98,0x98,0x97,0x97,0x96,0x96,0x96, | ||
| 130 | 0x95,0x95,0x95,0x94,0x94,0x93,0x93,0x93, | ||
| 131 | 0x92,0x92,0x91,0x91,0x91,0x90,0x90,0x8f, | ||
| 132 | 0x8f,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8c, | ||
| 133 | 0x8c,0x8c,0x8b,0x8b,0x8a,0x8a,0x8a,0x89, | ||
| 134 | 0x89,0x88,0x88,0x88,0x87,0x87,0x87,0x86, | ||
| 135 | 0x86,0x85,0x85,0x85,0x84,0x84,0x83,0x83, | ||
| 136 | 0x83,0x82,0x82,0x81,0x81,0x81,0x80,0x80, | ||
| 137 | 0x80,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d, | ||
| 138 | 0x7c,0x7c,0x7c,0x7b,0x7b,0x7a,0x7a,0x7a, | ||
| 139 | 0x79,0x79,0x78,0x78,0x78,0x77,0x77,0x77, | ||
| 140 | 0x76,0x76,0x75,0x75,0x75,0x74,0x74,0x73, | ||
| 141 | 0x73,0x73,0x72,0x72,0x71,0x71,0x71,0x70, | ||
| 142 | 0x70,0x70,0x6f,0x6f,0x6e,0x6e,0x6e,0x6d, | ||
| 143 | 0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,0x6a, | ||
| 144 | 0x6a,0x69,0x69,0x69,0x68,0x68,0x67,0x67, | ||
| 145 | 0x67,0x66,0x66,0x65,0x65,0x65,0x64,0x64, | ||
| 146 | 0x64,0x63,0x63,0x62,0x62,0x62,0x61,0x61, | ||
| 147 | 0x61,0x60,0x60,0x5f,0x5f,0x5f,0x5e,0x5e, | ||
| 148 | 0x5d,0x5d,0x5d,0x5c,0x5c,0x5c,0x5b,0x5b, | ||
| 149 | 0x5a,0x5a,0x5a,0x59,0x59,0x59,0x58,0x58, | ||
| 150 | 0x58,0x57,0x57,0x56,0x56,0x56,0x55,0x55, | ||
| 151 | 0x55,0x54,0x54,0x53,0x53,0x53,0x52,0x52, | ||
| 152 | 0x52,0x51,0x51,0x51,0x50,0x50,0x4f,0x4f, | ||
| 153 | 0x4f,0x4e,0x4e,0x4e,0x4d,0x4d,0x4d,0x4c, | ||
| 154 | 0x4c,0x4b,0x4b,0x4b,0x4a,0x4a,0x4a,0x49, | ||
| 155 | 0x49,0x49,0x48,0x48,0x48,0x47,0x47,0x47, | ||
| 156 | 0x46,0x46,0x45,0x45,0x45,0x44,0x44,0x44, | ||
| 157 | 0x43,0x43,0x43,0x42,0x42,0x42,0x41,0x41, | ||
| 158 | 0x41,0x40,0x40,0x40,0x3f,0x3f,0x3f,0x3e, | ||
| 159 | 0x3e,0x3e,0x3d,0x3d,0x3d,0x3c,0x3c,0x3c, | ||
| 160 | 0x3b,0x3b,0x3b,0x3a,0x3a,0x3a,0x39,0x39, | ||
| 161 | 0x39,0x38,0x38,0x38,0x37,0x37,0x37,0x36, | ||
| 162 | 0x36,0x36,0x35,0x35,0x35,0x34,0x34,0x34, | ||
| 163 | 0x34,0x33,0x33,0x33,0x32,0x32,0x32,0x31, | ||
| 164 | 0x31,0x31,0x30,0x30,0x30,0x30,0x2f,0x2f, | ||
| 165 | 0x2f,0x2e,0x2e,0x2e,0x2d,0x2d,0x2d,0x2d, | ||
| 166 | 0x2c,0x2c,0x2c,0x2b,0x2b,0x2b,0x2a,0x2a, | ||
| 167 | 0x2a,0x2a,0x29,0x29,0x29,0x28,0x28,0x28, | ||
| 168 | 0x28,0x27,0x27,0x27,0x26,0x26,0x26,0x26, | ||
| 169 | 0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x23, | ||
| 170 | 0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x21, | ||
| 171 | 0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f, | ||
| 172 | 0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,0x1d, | ||
| 173 | 0x1d,0x1d,0x1c,0x1c,0x1c,0x1c,0x1b,0x1b, | ||
| 174 | 0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19, | ||
| 175 | 0x19,0x19,0x19,0x18,0x18,0x18,0x18,0x17, | ||
| 176 | 0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x16, | ||
| 177 | 0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14, | ||
| 178 | 0x14,0x14,0x13,0x13,0x13,0x13,0x13,0x12, | ||
| 179 | 0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11, | ||
| 180 | 0x11,0x10,0x10,0x10,0x10,0x10,0xf,0xf, | ||
| 181 | 0xf,0xf,0xf,0xf,0xe,0xe,0xe,0xe, | ||
| 182 | 0xe,0xd,0xd,0xd,0xd,0xd,0xd,0xc, | ||
| 183 | 0xc,0xc,0xc,0xc,0xc,0xb,0xb,0xb, | ||
| 184 | 0xb,0xb,0xb,0xa,0xa,0xa,0xa,0xa, | ||
| 185 | 0xa,0xa,0x9,0x9,0x9,0x9,0x9,0x9, | ||
| 186 | 0x9,0x8,0x8,0x8,0x8,0x8,0x8,0x8, | ||
| 187 | 0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7, | ||
| 188 | 0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6, | ||
| 189 | 0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, | ||
| 190 | 0x5,0x5,0x4,0x4,0x4,0x4,0x4,0x4, | ||
| 191 | 0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3, | ||
| 192 | 0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3, | ||
| 193 | 0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, | ||
| 194 | 0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x1, | ||
| 195 | 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||
| 196 | 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||
| 197 | 0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0, | ||
| 198 | 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||
| 199 | 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||
| 200 | 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||
| 201 | 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||
| 202 | 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||
| 203 | 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, | ||
| 204 | 0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1, | ||
| 205 | 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||
| 206 | 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, | ||
| 207 | 0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2, | ||
| 208 | 0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, | ||
| 209 | 0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3, | ||
| 210 | 0x3,0x3,0x3,0x3,0x3,0x4,0x4,0x4, | ||
| 211 | 0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x5, | ||
| 212 | 0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, | ||
| 213 | 0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6, | ||
| 214 | 0x6,0x7,0x7,0x7,0x7,0x7,0x7,0x7, | ||
| 215 | 0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x8, | ||
| 216 | 0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa, | ||
| 217 | 0xa,0xa,0xa,0xa,0xa,0xa,0xb,0xb, | ||
| 218 | 0xb,0xb,0xb,0xb,0xc,0xc,0xc,0xc, | ||
| 219 | 0xc,0xc,0xd,0xd,0xd,0xd,0xd,0xd, | ||
| 220 | 0xe,0xe,0xe,0xe,0xe,0xf,0xf,0xf, | ||
| 221 | 0xf,0xf,0xf,0x10,0x10,0x10,0x10,0x10, | ||
| 222 | 0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12, | ||
| 223 | 0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x14, | ||
| 224 | 0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15, | ||
| 225 | 0x15,0x16,0x16,0x16,0x16,0x17,0x17,0x17, | ||
| 226 | 0x17,0x17,0x18,0x18,0x18,0x18,0x19,0x19, | ||
| 227 | 0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b, | ||
| 228 | 0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d, | ||
| 229 | 0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f, | ||
| 230 | 0x1f,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21, | ||
| 231 | 0x21,0x21,0x22,0x22,0x22,0x22,0x23,0x23, | ||
| 232 | 0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25, | ||
| 233 | 0x25,0x26,0x26,0x26,0x26,0x27,0x27,0x27, | ||
| 234 | 0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x2a, | ||
| 235 | 0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c, | ||
| 236 | 0x2c,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e, | ||
| 237 | 0x2f,0x2f,0x2f,0x30,0x30,0x30,0x30,0x31, | ||
| 238 | 0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33, | ||
| 239 | 0x34,0x34,0x34,0x34,0x35,0x35,0x35,0x36, | ||
| 240 | 0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38, | ||
| 241 | 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b, | ||
| 242 | 0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e, | ||
| 243 | 0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40, | ||
| 244 | 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43, | ||
| 245 | 0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46, | ||
| 246 | 0x46,0x47,0x47,0x47,0x48,0x48,0x48,0x49, | ||
| 247 | 0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b, | ||
| 248 | 0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e, | ||
| 249 | 0x4f,0x4f,0x4f,0x50,0x50,0x51,0x51,0x51, | ||
| 250 | 0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54, | ||
| 251 | 0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57, | ||
| 252 | 0x58,0x58,0x58,0x59,0x59,0x59,0x5a,0x5a, | ||
| 253 | 0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d, | ||
| 254 | 0x5d,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60, | ||
| 255 | 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63, | ||
| 256 | 0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66, | ||
| 257 | 0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x69, | ||
| 258 | 0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c, | ||
| 259 | 0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x70, | ||
| 260 | 0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x73, | ||
| 261 | 0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76, | ||
| 262 | 0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79, | ||
| 263 | 0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c, | ||
| 264 | 0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f | ||
| 265 | }; \ No newline at end of file | ||
