diff options
Diffstat (limited to 'quantum/audio/audio_arm.c')
| -rw-r--r-- | quantum/audio/audio_arm.c | 846 |
1 files changed, 391 insertions, 455 deletions
diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c index de0cd15c5..87d625301 100644 --- a/quantum/audio/audio_arm.c +++ b/quantum/audio/audio_arm.c | |||
| @@ -26,41 +26,41 @@ | |||
| 26 | 26 | ||
| 27 | // ----------------------------------------------------------------------------- | 27 | // ----------------------------------------------------------------------------- |
| 28 | 28 | ||
| 29 | int voices = 0; | 29 | int voices = 0; |
| 30 | int voice_place = 0; | 30 | int voice_place = 0; |
| 31 | float frequency = 0; | 31 | float frequency = 0; |
| 32 | float frequency_alt = 0; | 32 | float frequency_alt = 0; |
| 33 | int volume = 0; | 33 | int volume = 0; |
| 34 | long position = 0; | 34 | long position = 0; |
| 35 | 35 | ||
| 36 | float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | 36 | float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| 37 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | 37 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| 38 | bool sliding = false; | 38 | bool sliding = false; |
| 39 | 39 | ||
| 40 | float place = 0; | 40 | float place = 0; |
| 41 | 41 | ||
| 42 | uint8_t * sample; | 42 | uint8_t *sample; |
| 43 | uint16_t sample_length = 0; | 43 | uint16_t sample_length = 0; |
| 44 | 44 | ||
| 45 | bool playing_notes = false; | 45 | bool playing_notes = false; |
| 46 | bool playing_note = false; | 46 | bool playing_note = false; |
| 47 | float note_frequency = 0; | 47 | float note_frequency = 0; |
| 48 | float note_length = 0; | 48 | float note_length = 0; |
| 49 | uint8_t note_tempo = TEMPO_DEFAULT; | 49 | uint8_t note_tempo = TEMPO_DEFAULT; |
| 50 | float note_timbre = TIMBRE_DEFAULT; | 50 | float note_timbre = TIMBRE_DEFAULT; |
| 51 | uint16_t note_position = 0; | 51 | uint16_t note_position = 0; |
| 52 | float (* notes_pointer)[][2]; | 52 | float (*notes_pointer)[][2]; |
| 53 | uint16_t notes_count; | 53 | uint16_t notes_count; |
| 54 | bool notes_repeat; | 54 | bool notes_repeat; |
| 55 | bool note_resting = false; | 55 | bool note_resting = false; |
| 56 | 56 | ||
| 57 | uint16_t current_note = 0; | 57 | uint16_t current_note = 0; |
| 58 | uint8_t rest_counter = 0; | 58 | uint8_t rest_counter = 0; |
| 59 | 59 | ||
| 60 | #ifdef VIBRATO_ENABLE | 60 | #ifdef VIBRATO_ENABLE |
| 61 | float vibrato_counter = 0; | 61 | float vibrato_counter = 0; |
| 62 | float vibrato_strength = .5; | 62 | float vibrato_strength = .5; |
| 63 | float vibrato_rate = 0.125; | 63 | float vibrato_rate = 0.125; |
| 64 | #endif | 64 | #endif |
| 65 | 65 | ||
| 66 | float polyphony_rate = 0; | 66 | float polyphony_rate = 0; |
| @@ -70,10 +70,10 @@ static bool audio_initialized = false; | |||
| 70 | audio_config_t audio_config; | 70 | audio_config_t audio_config; |
| 71 | 71 | ||
| 72 | uint16_t envelope_index = 0; | 72 | uint16_t envelope_index = 0; |
| 73 | bool glissando = true; | 73 | bool glissando = true; |
| 74 | 74 | ||
| 75 | #ifndef STARTUP_SONG | 75 | #ifndef STARTUP_SONG |
| 76 | #define STARTUP_SONG SONG(STARTUP_SOUND) | 76 | # define STARTUP_SONG SONG(STARTUP_SOUND) |
| 77 | #endif | 77 | #endif |
| 78 | float startup_song[][2] = STARTUP_SONG; | 78 | float startup_song[][2] = STARTUP_SONG; |
| 79 | 79 | ||
| @@ -81,27 +81,32 @@ static void gpt_cb8(GPTDriver *gptp); | |||
| 81 | 81 | ||
| 82 | #define DAC_BUFFER_SIZE 100 | 82 | #define DAC_BUFFER_SIZE 100 |
| 83 | #ifndef DAC_SAMPLE_MAX | 83 | #ifndef DAC_SAMPLE_MAX |
| 84 | #define DAC_SAMPLE_MAX 65535U | 84 | # define DAC_SAMPLE_MAX 65535U |
| 85 | #endif | 85 | #endif |
| 86 | 86 | ||
| 87 | #define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \ | 87 | #define START_CHANNEL_1() \ |
| 88 | gptStart(&GPTD6, &gpt6cfg1); \ | ||
| 88 | gptStartContinuous(&GPTD6, 2U) | 89 | gptStartContinuous(&GPTD6, 2U) |
| 89 | #define START_CHANNEL_2() gptStart(&GPTD7, &gpt7cfg1); \ | 90 | #define START_CHANNEL_2() \ |
| 91 | gptStart(&GPTD7, &gpt7cfg1); \ | ||
| 90 | gptStartContinuous(&GPTD7, 2U) | 92 | gptStartContinuous(&GPTD7, 2U) |
| 91 | #define STOP_CHANNEL_1() gptStopTimer(&GPTD6) | 93 | #define STOP_CHANNEL_1() gptStopTimer(&GPTD6) |
| 92 | #define STOP_CHANNEL_2() gptStopTimer(&GPTD7) | 94 | #define STOP_CHANNEL_2() gptStopTimer(&GPTD7) |
| 93 | #define RESTART_CHANNEL_1() STOP_CHANNEL_1(); \ | 95 | #define RESTART_CHANNEL_1() \ |
| 96 | STOP_CHANNEL_1(); \ | ||
| 94 | START_CHANNEL_1() | 97 | START_CHANNEL_1() |
| 95 | #define RESTART_CHANNEL_2() STOP_CHANNEL_2(); \ | 98 | #define RESTART_CHANNEL_2() \ |
| 99 | STOP_CHANNEL_2(); \ | ||
| 96 | START_CHANNEL_2() | 100 | START_CHANNEL_2() |
| 97 | #define UPDATE_CHANNEL_1_FREQ(freq) gpt6cfg1.frequency = freq * DAC_BUFFER_SIZE; \ | 101 | #define UPDATE_CHANNEL_1_FREQ(freq) \ |
| 102 | gpt6cfg1.frequency = freq * DAC_BUFFER_SIZE; \ | ||
| 98 | RESTART_CHANNEL_1() | 103 | RESTART_CHANNEL_1() |
| 99 | #define UPDATE_CHANNEL_2_FREQ(freq) gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \ | 104 | #define UPDATE_CHANNEL_2_FREQ(freq) \ |
| 105 | gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \ | ||
| 100 | RESTART_CHANNEL_2() | 106 | RESTART_CHANNEL_2() |
| 101 | #define GET_CHANNEL_1_FREQ (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE) | 107 | #define GET_CHANNEL_1_FREQ (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE) |
| 102 | #define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE) | 108 | #define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE) |
| 103 | 109 | ||
| 104 | |||
| 105 | /* | 110 | /* |
| 106 | * GPT6 configuration. | 111 | * GPT6 configuration. |
| 107 | */ | 112 | */ |
| @@ -112,27 +117,20 @@ static void gpt_cb8(GPTDriver *gptp); | |||
| 112 | // .dier = 0U | 117 | // .dier = 0U |
| 113 | // }; | 118 | // }; |
| 114 | 119 | ||
| 115 | GPTConfig gpt6cfg1 = { | 120 | GPTConfig gpt6cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, |
| 116 | .frequency = 440U*DAC_BUFFER_SIZE, | 121 | .callback = NULL, |
| 117 | .callback = NULL, | 122 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ |
| 118 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | 123 | .dier = 0U}; |
| 119 | .dier = 0U | ||
| 120 | }; | ||
| 121 | 124 | ||
| 122 | GPTConfig gpt7cfg1 = { | 125 | GPTConfig gpt7cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, |
| 123 | .frequency = 440U*DAC_BUFFER_SIZE, | 126 | .callback = NULL, |
| 124 | .callback = NULL, | 127 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ |
| 125 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | 128 | .dier = 0U}; |
| 126 | .dier = 0U | ||
| 127 | }; | ||
| 128 | |||
| 129 | GPTConfig gpt8cfg1 = { | ||
| 130 | .frequency = 10, | ||
| 131 | .callback = gpt_cb8, | ||
| 132 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | ||
| 133 | .dier = 0U | ||
| 134 | }; | ||
| 135 | 129 | ||
| 130 | GPTConfig gpt8cfg1 = {.frequency = 10, | ||
| 131 | .callback = gpt_cb8, | ||
| 132 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | ||
| 133 | .dier = 0U}; | ||
| 136 | 134 | ||
| 137 | /* | 135 | /* |
| 138 | * DAC test buffer (sine wave). | 136 | * DAC test buffer (sine wave). |
| @@ -205,122 +203,101 @@ GPTConfig gpt8cfg1 = { | |||
| 205 | 203 | ||
| 206 | // squarewave | 204 | // squarewave |
| 207 | static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { | 205 | static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { |
| 208 | // First half is max, second half is 0 | 206 | // First half is max, second half is 0 |
| 209 | [0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX, | 207 | [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, |
| 210 | [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0, | 208 | [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, |
| 211 | }; | 209 | }; |
| 212 | 210 | ||
| 213 | // squarewave | 211 | // squarewave |
| 214 | static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { | 212 | static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { |
| 215 | // opposite of dac_buffer above | 213 | // opposite of dac_buffer above |
| 216 | [0 ... DAC_BUFFER_SIZE/2-1] = 0, | 214 | [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, |
| 217 | [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = DAC_SAMPLE_MAX, | 215 | [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, |
| 218 | }; | 216 | }; |
| 219 | 217 | ||
| 220 | /* | 218 | /* |
| 221 | * DAC streaming callback. | 219 | * DAC streaming callback. |
| 222 | */ | 220 | */ |
| 223 | size_t nx = 0, ny = 0, nz = 0; | 221 | size_t nx = 0, ny = 0, nz = 0; |
| 224 | static void end_cb1(DACDriver *dacp, dacsample_t *buffer, size_t n) { | 222 | static void end_cb1(DACDriver *dacp, dacsample_t *buffer, size_t n) { |
| 223 | (void)dacp; | ||
| 225 | 224 | ||
| 226 | (void)dacp; | 225 | nz++; |
| 227 | 226 | if (dac_buffer == buffer) { | |
| 228 | nz++; | 227 | nx += n; |
| 229 | if (dac_buffer == buffer) { | 228 | } else { |
| 230 | nx += n; | 229 | ny += n; |
| 231 | } | 230 | } |
| 232 | else { | ||
| 233 | ny += n; | ||
| 234 | } | ||
| 235 | 231 | ||
| 236 | if ((nz % 1000) == 0) { | 232 | if ((nz % 1000) == 0) { |
| 237 | // palTogglePad(GPIOD, GPIOD_LED3); | 233 | // palTogglePad(GPIOD, GPIOD_LED3); |
| 238 | } | 234 | } |
| 239 | } | 235 | } |
| 240 | 236 | ||
| 241 | /* | 237 | /* |
| 242 | * DAC error callback. | 238 | * DAC error callback. |
| 243 | */ | 239 | */ |
| 244 | static void error_cb1(DACDriver *dacp, dacerror_t err) { | 240 | static void error_cb1(DACDriver *dacp, dacerror_t err) { |
| 241 | (void)dacp; | ||
| 242 | (void)err; | ||
| 245 | 243 | ||
| 246 | (void)dacp; | 244 | chSysHalt("DAC failure"); |
| 247 | (void)err; | ||
| 248 | |||
| 249 | chSysHalt("DAC failure"); | ||
| 250 | } | 245 | } |
| 251 | 246 | ||
| 252 | static const DACConfig dac1cfg1 = { | 247 | static const DACConfig dac1cfg1 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; |
| 253 | .init = DAC_SAMPLE_MAX, | ||
| 254 | .datamode = DAC_DHRM_12BIT_RIGHT | ||
| 255 | }; | ||
| 256 | 248 | ||
| 257 | static const DACConversionGroup dacgrpcfg1 = { | 249 | static const DACConversionGroup dacgrpcfg1 = {.num_channels = 1U, .end_cb = end_cb1, .error_cb = error_cb1, .trigger = DAC_TRG(0)}; |
| 258 | .num_channels = 1U, | ||
| 259 | .end_cb = end_cb1, | ||
| 260 | .error_cb = error_cb1, | ||
| 261 | .trigger = DAC_TRG(0) | ||
| 262 | }; | ||
| 263 | 250 | ||
| 264 | static const DACConfig dac1cfg2 = { | 251 | static const DACConfig dac1cfg2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; |
| 265 | .init = DAC_SAMPLE_MAX, | ||
| 266 | .datamode = DAC_DHRM_12BIT_RIGHT | ||
| 267 | }; | ||
| 268 | 252 | ||
| 269 | static const DACConversionGroup dacgrpcfg2 = { | 253 | static const DACConversionGroup dacgrpcfg2 = {.num_channels = 1U, .end_cb = end_cb1, .error_cb = error_cb1, .trigger = DAC_TRG(0)}; |
| 270 | .num_channels = 1U, | ||
| 271 | .end_cb = end_cb1, | ||
| 272 | .error_cb = error_cb1, | ||
| 273 | .trigger = DAC_TRG(0) | ||
| 274 | }; | ||
| 275 | 254 | ||
| 276 | void audio_init() { | 255 | void audio_init() { |
| 256 | if (audio_initialized) { | ||
| 257 | return; | ||
| 258 | } | ||
| 277 | 259 | ||
| 278 | if (audio_initialized) { | 260 | // Check EEPROM |
| 279 | return; | 261 | #if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) |
| 280 | } | ||
| 281 | |||
| 282 | // Check EEPROM | ||
| 283 | #if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) | ||
| 284 | if (!eeconfig_is_enabled()) { | 262 | if (!eeconfig_is_enabled()) { |
| 285 | eeconfig_init(); | 263 | eeconfig_init(); |
| 286 | } | 264 | } |
| 287 | audio_config.raw = eeconfig_read_audio(); | 265 | audio_config.raw = eeconfig_read_audio(); |
| 288 | #else // ARM EEPROM | 266 | #else // ARM EEPROM |
| 289 | audio_config.enable = true; | 267 | audio_config.enable = true; |
| 290 | #ifdef AUDIO_CLICKY_ON | 268 | # ifdef AUDIO_CLICKY_ON |
| 291 | audio_config.clicky_enable = true; | 269 | audio_config.clicky_enable = true; |
| 292 | #endif | 270 | # endif |
| 293 | #endif // ARM EEPROM | 271 | #endif // ARM EEPROM |
| 294 | 272 | ||
| 295 | /* | 273 | /* |
| 296 | * Starting DAC1 driver, setting up the output pin as analog as suggested | 274 | * Starting DAC1 driver, setting up the output pin as analog as suggested |
| 297 | * by the Reference Manual. | 275 | * by the Reference Manual. |
| 298 | */ | 276 | */ |
| 299 | palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); | 277 | palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); |
| 300 | palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); | 278 | palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); |
| 301 | dacStart(&DACD1, &dac1cfg1); | 279 | dacStart(&DACD1, &dac1cfg1); |
| 302 | dacStart(&DACD2, &dac1cfg2); | 280 | dacStart(&DACD2, &dac1cfg2); |
| 303 | 281 | ||
| 304 | /* | 282 | /* |
| 305 | * Starting GPT6/7 driver, it is used for triggering the DAC. | 283 | * Starting GPT6/7 driver, it is used for triggering the DAC. |
| 306 | */ | 284 | */ |
| 307 | START_CHANNEL_1(); | 285 | START_CHANNEL_1(); |
| 308 | START_CHANNEL_2(); | 286 | START_CHANNEL_2(); |
| 309 | 287 | ||
| 310 | /* | 288 | /* |
| 311 | * Starting a continuous conversion. | 289 | * Starting a continuous conversion. |
| 312 | */ | 290 | */ |
| 313 | dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE); | 291 | dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE); |
| 314 | dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); | 292 | dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); |
| 315 | 293 | ||
| 316 | audio_initialized = true; | 294 | audio_initialized = true; |
| 317 | 295 | ||
| 318 | if (audio_config.enable) { | 296 | if (audio_config.enable) { |
| 319 | PLAY_SONG(startup_song); | 297 | PLAY_SONG(startup_song); |
| 320 | } else { | 298 | } else { |
| 321 | stop_all_notes(); | 299 | stop_all_notes(); |
| 322 | } | 300 | } |
| 323 | |||
| 324 | } | 301 | } |
| 325 | 302 | ||
| 326 | void stop_all_notes() { | 303 | void stop_all_notes() { |
| @@ -336,437 +313,396 @@ void stop_all_notes() { | |||
| 336 | gptStopTimer(&GPTD8); | 313 | gptStopTimer(&GPTD8); |
| 337 | 314 | ||
| 338 | playing_notes = false; | 315 | playing_notes = false; |
| 339 | playing_note = false; | 316 | playing_note = false; |
| 340 | frequency = 0; | 317 | frequency = 0; |
| 341 | frequency_alt = 0; | 318 | frequency_alt = 0; |
| 342 | volume = 0; | 319 | volume = 0; |
| 343 | 320 | ||
| 344 | for (uint8_t i = 0; i < 8; i++) | 321 | for (uint8_t i = 0; i < 8; i++) { |
| 345 | { | ||
| 346 | frequencies[i] = 0; | 322 | frequencies[i] = 0; |
| 347 | volumes[i] = 0; | 323 | volumes[i] = 0; |
| 348 | } | 324 | } |
| 349 | } | 325 | } |
| 350 | 326 | ||
| 351 | void stop_note(float freq) { | 327 | void stop_note(float freq) { |
| 352 | dprintf("audio stop note freq=%d", (int)freq); | 328 | dprintf("audio stop note freq=%d", (int)freq); |
| 353 | 329 | ||
| 354 | if (playing_note) { | 330 | if (playing_note) { |
| 355 | if (!audio_initialized) { | 331 | if (!audio_initialized) { |
| 356 | audio_init(); | 332 | audio_init(); |
| 357 | } | 333 | } |
| 358 | for (int i = 7; i >= 0; i--) { | 334 | for (int i = 7; i >= 0; i--) { |
| 359 | if (frequencies[i] == freq) { | 335 | if (frequencies[i] == freq) { |
| 360 | frequencies[i] = 0; | 336 | frequencies[i] = 0; |
| 361 | volumes[i] = 0; | 337 | volumes[i] = 0; |
| 362 | for (int j = i; (j < 7); j++) { | 338 | for (int j = i; (j < 7); j++) { |
| 363 | frequencies[j] = frequencies[j+1]; | 339 | frequencies[j] = frequencies[j + 1]; |
| 364 | frequencies[j+1] = 0; | 340 | frequencies[j + 1] = 0; |
| 365 | volumes[j] = volumes[j+1]; | 341 | volumes[j] = volumes[j + 1]; |
| 366 | volumes[j+1] = 0; | 342 | volumes[j + 1] = 0; |
| 343 | } | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | } | ||
| 347 | voices--; | ||
| 348 | if (voices < 0) { | ||
| 349 | voices = 0; | ||
| 350 | } | ||
| 351 | if (voice_place >= voices) { | ||
| 352 | voice_place = 0; | ||
| 353 | } | ||
| 354 | if (voices == 0) { | ||
| 355 | STOP_CHANNEL_1(); | ||
| 356 | STOP_CHANNEL_2(); | ||
| 357 | gptStopTimer(&GPTD8); | ||
| 358 | frequency = 0; | ||
| 359 | frequency_alt = 0; | ||
| 360 | volume = 0; | ||
| 361 | playing_note = false; | ||
| 367 | } | 362 | } |
| 368 | break; | ||
| 369 | } | ||
| 370 | } | ||
| 371 | voices--; | ||
| 372 | if (voices < 0) { | ||
| 373 | voices = 0; | ||
| 374 | } | ||
| 375 | if (voice_place >= voices) { | ||
| 376 | voice_place = 0; | ||
| 377 | } | ||
| 378 | if (voices == 0) { | ||
| 379 | STOP_CHANNEL_1(); | ||
| 380 | STOP_CHANNEL_2(); | ||
| 381 | gptStopTimer(&GPTD8); | ||
| 382 | frequency = 0; | ||
| 383 | frequency_alt = 0; | ||
| 384 | volume = 0; | ||
| 385 | playing_note = false; | ||
| 386 | } | 363 | } |
| 387 | } | ||
| 388 | } | 364 | } |
| 389 | 365 | ||
| 390 | #ifdef VIBRATO_ENABLE | 366 | #ifdef VIBRATO_ENABLE |
| 391 | 367 | ||
| 392 | float mod(float a, int b) { | 368 | float mod(float a, int b) { |
| 393 | float r = fmod(a, b); | 369 | float r = fmod(a, b); |
| 394 | return r < 0 ? r + b : r; | 370 | return r < 0 ? r + b : r; |
| 395 | } | 371 | } |
| 396 | 372 | ||
| 397 | float vibrato(float average_freq) { | 373 | float vibrato(float average_freq) { |
| 398 | #ifdef VIBRATO_STRENGTH_ENABLE | 374 | # ifdef VIBRATO_STRENGTH_ENABLE |
| 399 | float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); | 375 | float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); |
| 400 | #else | 376 | # else |
| 401 | float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; | 377 | float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; |
| 402 | #endif | 378 | # endif |
| 403 | vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); | 379 | vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); |
| 404 | return vibrated_freq; | 380 | return vibrated_freq; |
| 405 | } | 381 | } |
| 406 | 382 | ||
| 407 | #endif | 383 | #endif |
| 408 | 384 | ||
| 409 | static void gpt_cb8(GPTDriver *gptp) { | 385 | static void gpt_cb8(GPTDriver *gptp) { |
| 410 | float freq; | 386 | float freq; |
| 411 | |||
| 412 | if (playing_note) { | ||
| 413 | if (voices > 0) { | ||
| 414 | |||
| 415 | float freq_alt = 0; | ||
| 416 | if (voices > 1) { | ||
| 417 | if (polyphony_rate == 0) { | ||
| 418 | if (glissando) { | ||
| 419 | if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) { | ||
| 420 | frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2); | ||
| 421 | } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) { | ||
| 422 | frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2); | ||
| 423 | } else { | ||
| 424 | frequency_alt = frequencies[voices - 2]; | ||
| 425 | } | ||
| 426 | } else { | ||
| 427 | frequency_alt = frequencies[voices - 2]; | ||
| 428 | } | ||
| 429 | 387 | ||
| 430 | #ifdef VIBRATO_ENABLE | 388 | if (playing_note) { |
| 431 | if (vibrato_strength > 0) { | 389 | if (voices > 0) { |
| 432 | freq_alt = vibrato(frequency_alt); | 390 | float freq_alt = 0; |
| 433 | } else { | 391 | if (voices > 1) { |
| 434 | freq_alt = frequency_alt; | 392 | if (polyphony_rate == 0) { |
| 435 | } | 393 | if (glissando) { |
| 436 | #else | 394 | if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440 / frequencies[voices - 2] / 12 / 2)) { |
| 437 | freq_alt = frequency_alt; | 395 | frequency_alt = frequency_alt * pow(2, 440 / frequency_alt / 12 / 2); |
| 438 | #endif | 396 | } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440 / frequencies[voices - 2] / 12 / 2)) { |
| 439 | } | 397 | frequency_alt = frequency_alt * pow(2, -440 / frequency_alt / 12 / 2); |
| 398 | } else { | ||
| 399 | frequency_alt = frequencies[voices - 2]; | ||
| 400 | } | ||
| 401 | } else { | ||
| 402 | frequency_alt = frequencies[voices - 2]; | ||
| 403 | } | ||
| 440 | 404 | ||
| 441 | if (envelope_index < 65535) { | 405 | #ifdef VIBRATO_ENABLE |
| 442 | envelope_index++; | 406 | if (vibrato_strength > 0) { |
| 443 | } | 407 | freq_alt = vibrato(frequency_alt); |
| 408 | } else { | ||
| 409 | freq_alt = frequency_alt; | ||
| 410 | } | ||
| 411 | #else | ||
| 412 | freq_alt = frequency_alt; | ||
| 413 | #endif | ||
| 414 | } | ||
| 444 | 415 | ||
| 445 | freq_alt = voice_envelope(freq_alt); | 416 | if (envelope_index < 65535) { |
| 417 | envelope_index++; | ||
| 418 | } | ||
| 446 | 419 | ||
| 447 | if (freq_alt < 30.517578125) { | 420 | freq_alt = voice_envelope(freq_alt); |
| 448 | freq_alt = 30.52; | ||
| 449 | } | ||
| 450 | 421 | ||
| 451 | if (GET_CHANNEL_2_FREQ != (uint16_t)freq_alt) { | 422 | if (freq_alt < 30.517578125) { |
| 452 | UPDATE_CHANNEL_2_FREQ(freq_alt); | 423 | freq_alt = 30.52; |
| 453 | } else { | 424 | } |
| 454 | RESTART_CHANNEL_2(); | ||
| 455 | } | ||
| 456 | //note_timbre; | ||
| 457 | } | ||
| 458 | |||
| 459 | if (polyphony_rate > 0) { | ||
| 460 | if (voices > 1) { | ||
| 461 | voice_place %= voices; | ||
| 462 | if (place++ > (frequencies[voice_place] / polyphony_rate)) { | ||
| 463 | voice_place = (voice_place + 1) % voices; | ||
| 464 | place = 0.0; | ||
| 465 | } | ||
| 466 | } | ||
| 467 | 425 | ||
| 468 | #ifdef VIBRATO_ENABLE | 426 | if (GET_CHANNEL_2_FREQ != (uint16_t)freq_alt) { |
| 469 | if (vibrato_strength > 0) { | 427 | UPDATE_CHANNEL_2_FREQ(freq_alt); |
| 470 | freq = vibrato(frequencies[voice_place]); | 428 | } else { |
| 471 | } else { | 429 | RESTART_CHANNEL_2(); |
| 472 | freq = frequencies[voice_place]; | 430 | } |
| 473 | } | 431 | // note_timbre; |
| 474 | #else | 432 | } |
| 475 | freq = frequencies[voice_place]; | ||
| 476 | #endif | ||
| 477 | } else { | ||
| 478 | if (glissando) { | ||
| 479 | if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { | ||
| 480 | frequency = frequency * pow(2, 440/frequency/12/2); | ||
| 481 | } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { | ||
| 482 | frequency = frequency * pow(2, -440/frequency/12/2); | ||
| 483 | } else { | ||
| 484 | frequency = frequencies[voices - 1]; | ||
| 485 | } | ||
| 486 | } else { | ||
| 487 | frequency = frequencies[voices - 1]; | ||
| 488 | } | ||
| 489 | 433 | ||
| 490 | #ifdef VIBRATO_ENABLE | 434 | if (polyphony_rate > 0) { |
| 491 | if (vibrato_strength > 0) { | 435 | if (voices > 1) { |
| 492 | freq = vibrato(frequency); | 436 | voice_place %= voices; |
| 493 | } else { | 437 | if (place++ > (frequencies[voice_place] / polyphony_rate)) { |
| 494 | freq = frequency; | 438 | voice_place = (voice_place + 1) % voices; |
| 495 | } | 439 | place = 0.0; |
| 496 | #else | 440 | } |
| 497 | freq = frequency; | 441 | } |
| 498 | #endif | ||
| 499 | } | ||
| 500 | 442 | ||
| 501 | if (envelope_index < 65535) { | 443 | #ifdef VIBRATO_ENABLE |
| 502 | envelope_index++; | 444 | if (vibrato_strength > 0) { |
| 503 | } | 445 | freq = vibrato(frequencies[voice_place]); |
| 446 | } else { | ||
| 447 | freq = frequencies[voice_place]; | ||
| 448 | } | ||
| 449 | #else | ||
| 450 | freq = frequencies[voice_place]; | ||
| 451 | #endif | ||
| 452 | } else { | ||
| 453 | if (glissando) { | ||
| 454 | if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { | ||
| 455 | frequency = frequency * pow(2, 440 / frequency / 12 / 2); | ||
| 456 | } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { | ||
| 457 | frequency = frequency * pow(2, -440 / frequency / 12 / 2); | ||
| 458 | } else { | ||
| 459 | frequency = frequencies[voices - 1]; | ||
| 460 | } | ||
| 461 | } else { | ||
| 462 | frequency = frequencies[voices - 1]; | ||
| 463 | } | ||
| 504 | 464 | ||
| 505 | freq = voice_envelope(freq); | 465 | #ifdef VIBRATO_ENABLE |
| 466 | if (vibrato_strength > 0) { | ||
| 467 | freq = vibrato(frequency); | ||
| 468 | } else { | ||
| 469 | freq = frequency; | ||
| 470 | } | ||
| 471 | #else | ||
| 472 | freq = frequency; | ||
| 473 | #endif | ||
| 474 | } | ||
| 506 | 475 | ||
| 507 | if (freq < 30.517578125) { | 476 | if (envelope_index < 65535) { |
| 508 | freq = 30.52; | 477 | envelope_index++; |
| 509 | } | 478 | } |
| 510 | 479 | ||
| 480 | freq = voice_envelope(freq); | ||
| 511 | 481 | ||
| 512 | if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { | 482 | if (freq < 30.517578125) { |
| 513 | UPDATE_CHANNEL_1_FREQ(freq); | 483 | freq = 30.52; |
| 514 | } else { | 484 | } |
| 515 | RESTART_CHANNEL_1(); | ||
| 516 | } | ||
| 517 | //note_timbre; | ||
| 518 | } | ||
| 519 | } | ||
| 520 | 485 | ||
| 521 | if (playing_notes) { | 486 | if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { |
| 522 | if (note_frequency > 0) { | 487 | UPDATE_CHANNEL_1_FREQ(freq); |
| 523 | #ifdef VIBRATO_ENABLE | 488 | } else { |
| 524 | if (vibrato_strength > 0) { | 489 | RESTART_CHANNEL_1(); |
| 525 | freq = vibrato(note_frequency); | 490 | } |
| 526 | } else { | 491 | // note_timbre; |
| 527 | freq = note_frequency; | ||
| 528 | } | 492 | } |
| 529 | #else | ||
| 530 | freq = note_frequency; | ||
| 531 | #endif | ||
| 532 | |||
| 533 | if (envelope_index < 65535) { | ||
| 534 | envelope_index++; | ||
| 535 | } | ||
| 536 | freq = voice_envelope(freq); | ||
| 537 | |||
| 538 | |||
| 539 | if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { | ||
| 540 | UPDATE_CHANNEL_1_FREQ(freq); | ||
| 541 | UPDATE_CHANNEL_2_FREQ(freq); | ||
| 542 | } | ||
| 543 | //note_timbre; | ||
| 544 | } else { | ||
| 545 | // gptStopTimer(&GPTD6); | ||
| 546 | // gptStopTimer(&GPTD7); | ||
| 547 | } | 493 | } |
| 548 | 494 | ||
| 549 | note_position++; | 495 | if (playing_notes) { |
| 550 | bool end_of_note = false; | 496 | if (note_frequency > 0) { |
| 551 | if (GET_CHANNEL_1_FREQ > 0) { | 497 | #ifdef VIBRATO_ENABLE |
| 552 | if (!note_resting) | 498 | if (vibrato_strength > 0) { |
| 553 | end_of_note = (note_position >= (note_length*8 - 1)); | 499 | freq = vibrato(note_frequency); |
| 554 | else | 500 | } else { |
| 555 | end_of_note = (note_position >= (note_length*8)); | 501 | freq = note_frequency; |
| 556 | } else { | 502 | } |
| 557 | end_of_note = (note_position >= (note_length*8)); | 503 | #else |
| 558 | } | 504 | freq = note_frequency; |
| 505 | #endif | ||
| 559 | 506 | ||
| 560 | if (end_of_note) { | 507 | if (envelope_index < 65535) { |
| 561 | current_note++; | 508 | envelope_index++; |
| 562 | if (current_note >= notes_count) { | 509 | } |
| 563 | if (notes_repeat) { | 510 | freq = voice_envelope(freq); |
| 564 | current_note = 0; | 511 | |
| 512 | if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { | ||
| 513 | UPDATE_CHANNEL_1_FREQ(freq); | ||
| 514 | UPDATE_CHANNEL_2_FREQ(freq); | ||
| 515 | } | ||
| 516 | // note_timbre; | ||
| 565 | } else { | 517 | } else { |
| 566 | STOP_CHANNEL_1(); | 518 | // gptStopTimer(&GPTD6); |
| 567 | STOP_CHANNEL_2(); | 519 | // gptStopTimer(&GPTD7); |
| 568 | // gptStopTimer(&GPTD8); | ||
| 569 | playing_notes = false; | ||
| 570 | return; | ||
| 571 | } | 520 | } |
| 572 | } | 521 | |
| 573 | if (!note_resting) { | 522 | note_position++; |
| 574 | note_resting = true; | 523 | bool end_of_note = false; |
| 575 | current_note--; | 524 | if (GET_CHANNEL_1_FREQ > 0) { |
| 576 | if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { | 525 | if (!note_resting) |
| 577 | note_frequency = 0; | 526 | end_of_note = (note_position >= (note_length * 8 - 1)); |
| 578 | note_length = 1; | 527 | else |
| 528 | end_of_note = (note_position >= (note_length * 8)); | ||
| 579 | } else { | 529 | } else { |
| 580 | note_frequency = (*notes_pointer)[current_note][0]; | 530 | end_of_note = (note_position >= (note_length * 8)); |
| 581 | note_length = 1; | ||
| 582 | } | 531 | } |
| 583 | } else { | ||
| 584 | note_resting = false; | ||
| 585 | envelope_index = 0; | ||
| 586 | note_frequency = (*notes_pointer)[current_note][0]; | ||
| 587 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||
| 588 | } | ||
| 589 | 532 | ||
| 590 | note_position = 0; | 533 | if (end_of_note) { |
| 534 | current_note++; | ||
| 535 | if (current_note >= notes_count) { | ||
| 536 | if (notes_repeat) { | ||
| 537 | current_note = 0; | ||
| 538 | } else { | ||
| 539 | STOP_CHANNEL_1(); | ||
| 540 | STOP_CHANNEL_2(); | ||
| 541 | // gptStopTimer(&GPTD8); | ||
| 542 | playing_notes = false; | ||
| 543 | return; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | if (!note_resting) { | ||
| 547 | note_resting = true; | ||
| 548 | current_note--; | ||
| 549 | if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { | ||
| 550 | note_frequency = 0; | ||
| 551 | note_length = 1; | ||
| 552 | } else { | ||
| 553 | note_frequency = (*notes_pointer)[current_note][0]; | ||
| 554 | note_length = 1; | ||
| 555 | } | ||
| 556 | } else { | ||
| 557 | note_resting = false; | ||
| 558 | envelope_index = 0; | ||
| 559 | note_frequency = (*notes_pointer)[current_note][0]; | ||
| 560 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | ||
| 561 | } | ||
| 562 | |||
| 563 | note_position = 0; | ||
| 564 | } | ||
| 591 | } | 565 | } |
| 592 | } | ||
| 593 | 566 | ||
| 594 | if (!audio_config.enable) { | 567 | if (!audio_config.enable) { |
| 595 | playing_notes = false; | 568 | playing_notes = false; |
| 596 | playing_note = false; | 569 | playing_note = false; |
| 597 | } | 570 | } |
| 598 | } | 571 | } |
| 599 | 572 | ||
| 600 | void play_note(float freq, int vol) { | 573 | void play_note(float freq, int vol) { |
| 574 | dprintf("audio play note freq=%d vol=%d", (int)freq, vol); | ||
| 601 | 575 | ||
| 602 | dprintf("audio play note freq=%d vol=%d", (int)freq, vol); | 576 | if (!audio_initialized) { |
| 603 | 577 | audio_init(); | |
| 604 | if (!audio_initialized) { | ||
| 605 | audio_init(); | ||
| 606 | } | ||
| 607 | |||
| 608 | if (audio_config.enable && voices < 8) { | ||
| 609 | |||
| 610 | // Cancel notes if notes are playing | ||
| 611 | if (playing_notes) { | ||
| 612 | stop_all_notes(); | ||
| 613 | } | 578 | } |
| 614 | 579 | ||
| 615 | playing_note = true; | 580 | if (audio_config.enable && voices < 8) { |
| 581 | // Cancel notes if notes are playing | ||
| 582 | if (playing_notes) { | ||
| 583 | stop_all_notes(); | ||
| 584 | } | ||
| 616 | 585 | ||
| 617 | envelope_index = 0; | 586 | playing_note = true; |
| 618 | 587 | ||
| 619 | if (freq > 0) { | 588 | envelope_index = 0; |
| 620 | frequencies[voices] = freq; | ||
| 621 | volumes[voices] = vol; | ||
| 622 | voices++; | ||
| 623 | } | ||
| 624 | 589 | ||
| 625 | gptStart(&GPTD8, &gpt8cfg1); | 590 | if (freq > 0) { |
| 626 | gptStartContinuous(&GPTD8, 2U); | 591 | frequencies[voices] = freq; |
| 627 | RESTART_CHANNEL_1(); | 592 | volumes[voices] = vol; |
| 628 | RESTART_CHANNEL_2(); | 593 | voices++; |
| 629 | } | 594 | } |
| 630 | 595 | ||
| 596 | gptStart(&GPTD8, &gpt8cfg1); | ||
| 597 | gptStartContinuous(&GPTD8, 2U); | ||
| 598 | RESTART_CHANNEL_1(); | ||
| 599 | RESTART_CHANNEL_2(); | ||
| 600 | } | ||
| 631 | } | 601 | } |
| 632 | 602 | ||
| 633 | void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { | 603 | void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { |
| 634 | 604 | if (!audio_initialized) { | |
| 635 | if (!audio_initialized) { | 605 | audio_init(); |
| 636 | audio_init(); | ||
| 637 | } | ||
| 638 | |||
| 639 | if (audio_config.enable) { | ||
| 640 | |||
| 641 | // Cancel note if a note is playing | ||
| 642 | if (playing_note) { | ||
| 643 | stop_all_notes(); | ||
| 644 | } | 606 | } |
| 645 | 607 | ||
| 646 | playing_notes = true; | 608 | if (audio_config.enable) { |
| 609 | // Cancel note if a note is playing | ||
| 610 | if (playing_note) { | ||
| 611 | stop_all_notes(); | ||
| 612 | } | ||
| 647 | 613 | ||
| 648 | notes_pointer = np; | 614 | playing_notes = true; |
| 649 | notes_count = n_count; | ||
| 650 | notes_repeat = n_repeat; | ||
| 651 | 615 | ||
| 652 | place = 0; | 616 | notes_pointer = np; |
| 653 | current_note = 0; | 617 | notes_count = n_count; |
| 618 | notes_repeat = n_repeat; | ||
| 654 | 619 | ||
| 655 | note_frequency = (*notes_pointer)[current_note][0]; | 620 | place = 0; |
| 656 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | 621 | current_note = 0; |
| 657 | note_position = 0; | ||
| 658 | 622 | ||
| 659 | gptStart(&GPTD8, &gpt8cfg1); | 623 | note_frequency = (*notes_pointer)[current_note][0]; |
| 660 | gptStartContinuous(&GPTD8, 2U); | 624 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); |
| 661 | RESTART_CHANNEL_1(); | 625 | note_position = 0; |
| 662 | RESTART_CHANNEL_2(); | ||
| 663 | } | ||
| 664 | } | ||
| 665 | 626 | ||
| 666 | bool is_playing_notes(void) { | 627 | gptStart(&GPTD8, &gpt8cfg1); |
| 667 | return playing_notes; | 628 | gptStartContinuous(&GPTD8, 2U); |
| 629 | RESTART_CHANNEL_1(); | ||
| 630 | RESTART_CHANNEL_2(); | ||
| 631 | } | ||
| 668 | } | 632 | } |
| 669 | 633 | ||
| 670 | bool is_audio_on(void) { | 634 | bool is_playing_notes(void) { return playing_notes; } |
| 671 | return (audio_config.enable != 0); | 635 | |
| 672 | } | 636 | bool is_audio_on(void) { return (audio_config.enable != 0); } |
| 673 | 637 | ||
| 674 | void audio_toggle(void) { | 638 | void audio_toggle(void) { |
| 675 | audio_config.enable ^= 1; | 639 | audio_config.enable ^= 1; |
| 676 | eeconfig_update_audio(audio_config.raw); | 640 | eeconfig_update_audio(audio_config.raw); |
| 677 | if (audio_config.enable) { | 641 | if (audio_config.enable) { |
| 678 | audio_on_user(); | 642 | audio_on_user(); |
| 679 | } | 643 | } |
| 680 | } | 644 | } |
| 681 | 645 | ||
| 682 | void audio_on(void) { | 646 | void audio_on(void) { |
| 683 | audio_config.enable = 1; | 647 | audio_config.enable = 1; |
| 684 | eeconfig_update_audio(audio_config.raw); | 648 | eeconfig_update_audio(audio_config.raw); |
| 685 | audio_on_user(); | 649 | audio_on_user(); |
| 686 | } | 650 | } |
| 687 | 651 | ||
| 688 | void audio_off(void) { | 652 | void audio_off(void) { |
| 689 | stop_all_notes(); | 653 | stop_all_notes(); |
| 690 | audio_config.enable = 0; | 654 | audio_config.enable = 0; |
| 691 | eeconfig_update_audio(audio_config.raw); | 655 | eeconfig_update_audio(audio_config.raw); |
| 692 | } | 656 | } |
| 693 | 657 | ||
| 694 | #ifdef VIBRATO_ENABLE | 658 | #ifdef VIBRATO_ENABLE |
| 695 | 659 | ||
| 696 | // Vibrato rate functions | 660 | // Vibrato rate functions |
| 697 | 661 | ||
| 698 | void set_vibrato_rate(float rate) { | 662 | void set_vibrato_rate(float rate) { vibrato_rate = rate; } |
| 699 | vibrato_rate = rate; | ||
| 700 | } | ||
| 701 | 663 | ||
| 702 | void increase_vibrato_rate(float change) { | 664 | void increase_vibrato_rate(float change) { vibrato_rate *= change; } |
| 703 | vibrato_rate *= change; | ||
| 704 | } | ||
| 705 | 665 | ||
| 706 | void decrease_vibrato_rate(float change) { | 666 | void decrease_vibrato_rate(float change) { vibrato_rate /= change; } |
| 707 | vibrato_rate /= change; | ||
| 708 | } | ||
| 709 | 667 | ||
| 710 | #ifdef VIBRATO_STRENGTH_ENABLE | 668 | # ifdef VIBRATO_STRENGTH_ENABLE |
| 711 | 669 | ||
| 712 | void set_vibrato_strength(float strength) { | 670 | void set_vibrato_strength(float strength) { vibrato_strength = strength; } |
| 713 | vibrato_strength = strength; | ||
| 714 | } | ||
| 715 | 671 | ||
| 716 | void increase_vibrato_strength(float change) { | 672 | void increase_vibrato_strength(float change) { vibrato_strength *= change; } |
| 717 | vibrato_strength *= change; | ||
| 718 | } | ||
| 719 | 673 | ||
| 720 | void decrease_vibrato_strength(float change) { | 674 | void decrease_vibrato_strength(float change) { vibrato_strength /= change; } |
| 721 | vibrato_strength /= change; | ||
| 722 | } | ||
| 723 | 675 | ||
| 724 | #endif /* VIBRATO_STRENGTH_ENABLE */ | 676 | # endif /* VIBRATO_STRENGTH_ENABLE */ |
| 725 | 677 | ||
| 726 | #endif /* VIBRATO_ENABLE */ | 678 | #endif /* VIBRATO_ENABLE */ |
| 727 | 679 | ||
| 728 | // Polyphony functions | 680 | // Polyphony functions |
| 729 | 681 | ||
| 730 | void set_polyphony_rate(float rate) { | 682 | void set_polyphony_rate(float rate) { polyphony_rate = rate; } |
| 731 | polyphony_rate = rate; | ||
| 732 | } | ||
| 733 | 683 | ||
| 734 | void enable_polyphony() { | 684 | void enable_polyphony() { polyphony_rate = 5; } |
| 735 | polyphony_rate = 5; | ||
| 736 | } | ||
| 737 | 685 | ||
| 738 | void disable_polyphony() { | 686 | void disable_polyphony() { polyphony_rate = 0; } |
| 739 | polyphony_rate = 0; | ||
| 740 | } | ||
| 741 | 687 | ||
| 742 | void increase_polyphony_rate(float change) { | 688 | void increase_polyphony_rate(float change) { polyphony_rate *= change; } |
| 743 | polyphony_rate *= change; | ||
| 744 | } | ||
| 745 | 689 | ||
| 746 | void decrease_polyphony_rate(float change) { | 690 | void decrease_polyphony_rate(float change) { polyphony_rate /= change; } |
| 747 | polyphony_rate /= change; | ||
| 748 | } | ||
| 749 | 691 | ||
| 750 | // Timbre function | 692 | // Timbre function |
| 751 | 693 | ||
| 752 | void set_timbre(float timbre) { | 694 | void set_timbre(float timbre) { note_timbre = timbre; } |
| 753 | note_timbre = timbre; | ||
| 754 | } | ||
| 755 | 695 | ||
| 756 | // Tempo functions | 696 | // Tempo functions |
| 757 | 697 | ||
| 758 | void set_tempo(uint8_t tempo) { | 698 | void set_tempo(uint8_t tempo) { note_tempo = tempo; } |
| 759 | note_tempo = tempo; | ||
| 760 | } | ||
| 761 | 699 | ||
| 762 | void decrease_tempo(uint8_t tempo_change) { | 700 | void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } |
| 763 | note_tempo += tempo_change; | ||
| 764 | } | ||
| 765 | 701 | ||
| 766 | void increase_tempo(uint8_t tempo_change) { | 702 | void increase_tempo(uint8_t tempo_change) { |
| 767 | if (note_tempo - tempo_change < 10) { | 703 | if (note_tempo - tempo_change < 10) { |
| 768 | note_tempo = 10; | 704 | note_tempo = 10; |
| 769 | } else { | 705 | } else { |
| 770 | note_tempo -= tempo_change; | 706 | note_tempo -= tempo_change; |
| 771 | } | 707 | } |
| 772 | } | 708 | } |
