Improved audio beep tone (#2014)

* Improved sine wave beep tone

* Prevent divide-by-zero
This commit is contained in:
Mark Thompson 2024-03-19 15:30:05 -05:00 committed by GitHub
parent 308573918c
commit 807c76346b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 2 deletions

View File

@ -239,19 +239,41 @@ void shrink_tx_buffer(bool shrink) {
}
void beep_start(uint32_t freq, uint32_t sample_rate, uint32_t beep_duration_ms) {
tone_gen.configure_beep(freq, sample_rate);
// Prevent divide-by-0
if (freq == 0 || sample_rate == 0)
return;
// Fill entire buffer with sine waves
tone_gen.configure_beep(freq, sample_rate);
for (size_t i = 0; i < buffer_samples; i++)
buffer_tx[i].left = buffer_tx[i].right = tone_gen.process_beep();
uint32_t beep_interrupt_count = beep_duration_ms * sample_rate / (1000 * transfer_samples);
// Try to adjust DMA transfer count to align with full sine waves for a better tone
float samples_per_sine_wave = float(sample_rate) / freq;
uint32_t sine_waves_per_buffer = buffer_samples / samples_per_sine_wave;
size_t sample_count = (sine_waves_per_buffer == 0) ? buffer_samples : sine_waves_per_buffer * samples_per_sine_wave + 0.5;
// Use single larger transfer buffer with sample count determined above
lli_tx_loop[0].lli = lli_pointer(&lli_tx_loop[0]);
lli_tx_loop[0].control = control_tx(sample_count * sizeof(sample_t));
// Convert duration ms to number of buffers to send before stopping
// NB: beep_duration_ms==0 means beep continuously until stopped
uint32_t beep_interrupt_count = beep_duration_ms * sample_rate / (1000 * sample_count);
if ((beep_duration_ms != 0) && (beep_interrupt_count == 0))
beep_interrupt_count = 1;
beep_duration_downcounter = beep_interrupt_count;
}
void beep_stop() {
// Clear audio DMA buffer
memset(&buffer_tx, 0, buffer_bytes);
// Restore DMA linked list to use multiple smaller buffers
lli_tx_loop[0].control = control_tx(transfer_bytes);
if (!single_tx_buffer && (transfers_per_buffer > 1)) {
lli_tx_loop[0].lli = lli_pointer(&lli_tx_loop[1]);
}
}
buffer_t tx_empty_buffer() {

View File

@ -27,6 +27,7 @@
// Functions for audio beep (used by Sonde RSSI)
void ToneGen::configure_beep(const uint32_t freq, const uint32_t sample_rate) {
f_delta_ = (float)(freq * sizeof(sine_table_i8)) / sample_rate;
f_tone_phase_ = 0.0;
}
int16_t ToneGen::process_beep() {
@ -44,6 +45,7 @@ int16_t ToneGen::process_beep() {
void ToneGen::configure(const uint32_t delta, const float tone_mix_weight) {
delta_ = delta;
tone_phase_ = 0;
tone_mix_weight_ = tone_mix_weight;
input_mix_weight_ = 1.0 - tone_mix_weight;
}