diff options
| author | Nebuleon <2391500+Nebuleon@users.noreply.github.com> | 2023-09-24 22:26:02 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-25 12:26:02 +1000 |
| commit | 1d94de5358a44e08d9c1a07ab76df0b85d029ab7 (patch) | |
| tree | 99714a2488e05abe50ac4256959f0ad89fcd1447 | |
| parent | 7850f0d8c6083a72d4d37018e74eb24d607ffb09 (diff) | |
Optimize the additive DAC code, fixing performance-related hangs (#21662)
| -rw-r--r-- | platforms/chibios/drivers/audio_dac_additive.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/platforms/chibios/drivers/audio_dac_additive.c b/platforms/chibios/drivers/audio_dac_additive.c index 22e4fa2608..7bb5cfffb5 100644 --- a/platforms/chibios/drivers/audio_dac_additive.c +++ b/platforms/chibios/drivers/audio_dac_additive.c | |||
| @@ -121,24 +121,27 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { | |||
| 121 | /* doing additive wave synthesis over all currently playing tones = adding up | 121 | /* doing additive wave synthesis over all currently playing tones = adding up |
| 122 | * sine-wave-samples for each frequency, scaled by the number of active tones | 122 | * sine-wave-samples for each frequency, scaled by the number of active tones |
| 123 | */ | 123 | */ |
| 124 | uint16_t value = 0; | 124 | uint_fast16_t value = 0; |
| 125 | float frequency = 0.0f; | 125 | float frequency = 0.0f; |
| 126 | 126 | ||
| 127 | for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { | 127 | for (size_t i = 0; i < active_tones_snapshot_length; i++) { |
| 128 | /* Note: a user implementation does not have to rely on the active_tones_snapshot, but | 128 | /* Note: a user implementation does not have to rely on the active_tones_snapshot, but |
| 129 | * could directly query the active frequencies through audio_get_processed_frequency */ | 129 | * could directly query the active frequencies through audio_get_processed_frequency */ |
| 130 | frequency = active_tones_snapshot[i]; | 130 | frequency = active_tones_snapshot[i]; |
| 131 | 131 | ||
| 132 | dac_if[i] = dac_if[i] + ((frequency * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2 / 3; | 132 | float new_dac_if = dac_if[i]; |
| 133 | new_dac_if += frequency * ((float)AUDIO_DAC_BUFFER_SIZE / AUDIO_DAC_SAMPLE_RATE * 2.0f / 3.0f); | ||
| 133 | /*Note: the 2/3 are necessary to get the correct frequencies on the | 134 | /*Note: the 2/3 are necessary to get the correct frequencies on the |
| 134 | * DAC output (as measured with an oscilloscope), since the gpt | 135 | * DAC output (as measured with an oscilloscope), since the gpt |
| 135 | * timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback | 136 | * timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback |
| 136 | * is called twice per conversion.*/ | 137 | * is called twice per conversion.*/ |
| 137 | 138 | ||
| 138 | dac_if[i] = fmodf(dac_if[i], AUDIO_DAC_BUFFER_SIZE); | 139 | while (new_dac_if >= AUDIO_DAC_BUFFER_SIZE) |
| 140 | new_dac_if -= AUDIO_DAC_BUFFER_SIZE; | ||
| 141 | dac_if[i] = new_dac_if; | ||
| 139 | 142 | ||
| 140 | // Wavetable generation/lookup | 143 | // Wavetable generation/lookup |
| 141 | uint16_t dac_i = (uint16_t)dac_if[i]; | 144 | size_t dac_i = (size_t)new_dac_if; |
| 142 | 145 | ||
| 143 | #if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) | 146 | #if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) |
| 144 | value += dac_buffer_sine[dac_i] / active_tones_snapshot_length; | 147 | value += dac_buffer_sine[dac_i] / active_tones_snapshot_length; |
