summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNebuleon <2391500+Nebuleon@users.noreply.github.com>2023-09-24 22:26:02 -0400
committerGitHub <noreply@github.com>2023-09-25 12:26:02 +1000
commit1d94de5358a44e08d9c1a07ab76df0b85d029ab7 (patch)
tree99714a2488e05abe50ac4256959f0ad89fcd1447
parent7850f0d8c6083a72d4d37018e74eb24d607ffb09 (diff)
Optimize the additive DAC code, fixing performance-related hangs (#21662)
-rw-r--r--platforms/chibios/drivers/audio_dac_additive.c15
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;