Skip to content

Commit

Permalink
Improved audio beep tone (#2014)
Browse files Browse the repository at this point in the history
* Improved sine wave beep tone

* Prevent divide-by-zero
  • Loading branch information
NotherNgineer authored Mar 19, 2024
1 parent 3085739 commit 807c763
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
26 changes: 24 additions & 2 deletions firmware/baseband/audio_dma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 2 additions & 0 deletions firmware/baseband/tone_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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;
}
Expand Down

0 comments on commit 807c763

Please sign in to comment.