From 485f57d86b9cdcee7c2f302d414845693cff885c Mon Sep 17 00:00:00 2001 From: Mark Thompson <129641948+NotherNgineer@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:50:45 -0600 Subject: [PATCH] Added Audio Out to Soundboard app (#1748) --- firmware/application/apps/soundboard_app.cpp | 6 +++++- firmware/application/apps/soundboard_app.hpp | 7 +++++-- firmware/baseband/audio_dma.cpp | 15 +++++++++++---- firmware/baseband/audio_dma.hpp | 1 + firmware/baseband/proc_audiotx.cpp | 8 ++++++++ firmware/baseband/proc_audiotx.hpp | 8 ++++++++ 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/firmware/application/apps/soundboard_app.cpp b/firmware/application/apps/soundboard_app.cpp index 2431e6c74..fc774b4ce 100644 --- a/firmware/application/apps/soundboard_app.cpp +++ b/firmware/application/apps/soundboard_app.cpp @@ -26,6 +26,7 @@ #include "string_format.hpp" #include "tonesets.hpp" #include "ui_tone_key.hpp" +#include "audio.hpp" using namespace tonekey; using namespace portapack; @@ -40,6 +41,7 @@ void SoundBoardView::stop() { if (is_active()) replay_thread.reset(); + audio::output::stop(); transmitter_model.disable(); tx_view.set_transmitting(false); @@ -123,6 +125,8 @@ void SoundBoardView::start_tx(const uint32_t id) { transmitter_model.enable(); tx_view.set_transmitting(true); + + audio::output::start(); } /*void SoundBoardView::show_infos() { @@ -227,6 +231,7 @@ SoundBoardView::SoundBoardView( //&text_title, //&text_duration, //&progressbar, + &field_volume, &page_info, &check_loop, &check_random, @@ -274,7 +279,6 @@ SoundBoardView::SoundBoardView( SoundBoardView::~SoundBoardView() { stop(); - transmitter_model.disable(); baseband::shutdown(); } diff --git a/firmware/application/apps/soundboard_app.hpp b/firmware/application/apps/soundboard_app.hpp index 7a4391514..88dc3c20a 100644 --- a/firmware/application/apps/soundboard_app.hpp +++ b/firmware/application/apps/soundboard_app.hpp @@ -91,7 +91,7 @@ class SoundBoardView : public View { void on_select_entry(); Labels labels{ - //{ { 0, 20 * 8 + 4 }, "Title:", Color::light_grey() }, + {{24 * 8, 180}, "Vol:", Color::light_grey()}, {{0, 180}, "Key:", Color::light_grey()}}; Button button_next_page{ @@ -122,10 +122,13 @@ class SoundBoardView : public View { };*/ OptionsField options_tone_key{ - {32, 180}, + {4 * 8, 180}, 18, {}}; + AudioVolumeField field_volume{ + {28 * 8, 180}}; + Checkbox check_loop{ {0, 25 * 8 + 4}, 4, diff --git a/firmware/baseband/audio_dma.cpp b/firmware/baseband/audio_dma.cpp index 4430a08f2..df12ccfe4 100644 --- a/firmware/baseband/audio_dma.cpp +++ b/firmware/baseband/audio_dma.cpp @@ -123,10 +123,10 @@ constexpr gpdma::channel::Config config_rx() { /* TODO: Clean up terminology around "buffer", "transfer", "samples" */ constexpr size_t buffer_samples_log2n = 7; -constexpr size_t buffer_samples = (1 << buffer_samples_log2n); +constexpr size_t buffer_samples = (1 << buffer_samples_log2n); // 2^7 = 128 byte circular DMA buffer constexpr size_t transfers_per_buffer_log2n = 2; -constexpr size_t transfers_per_buffer = (1 << transfers_per_buffer_log2n); -constexpr size_t transfer_samples = buffer_samples / transfers_per_buffer; +constexpr size_t transfers_per_buffer = (1 << transfers_per_buffer_log2n); // 2^2 = 4 transfer buffers in the circular buffer +constexpr size_t transfer_samples = buffer_samples / transfers_per_buffer; // 128/4 = 32 samples in each transfer buffer constexpr size_t transfers_mask = transfers_per_buffer - 1; constexpr size_t buffer_bytes = buffer_samples * sizeof(sample_t); @@ -144,6 +144,8 @@ static constexpr auto& gpdma_channel_i2s0_rx = gpdma::channels[portapack::i2s0_r static volatile const gpdma::channel::LLI* tx_next_lli = nullptr; static volatile const gpdma::channel::LLI* rx_next_lli = nullptr; +static bool single_tx_buffer = false; + static void tx_transfer_complete() { tx_next_lli = gpdma_channel_i2s0_tx.next_lli(); } @@ -213,11 +215,16 @@ void disable() { gpdma_channel_i2s0_rx.disable(); } +void shrink_tx_buffer() { + single_tx_buffer = true; + lli_tx_loop[0].lli = lli_pointer(&lli_tx_loop[0]); +} + buffer_t tx_empty_buffer() { const auto next_lli = tx_next_lli; if (next_lli) { const size_t next_index = next_lli - &lli_tx_loop[0]; - const size_t free_index = (next_index + transfers_per_buffer - 2) & transfers_mask; + const size_t free_index = (single_tx_buffer) ? 0 : (next_index + transfers_per_buffer - 2) & transfers_mask; return {reinterpret_cast(lli_tx_loop[free_index].srcaddr), transfer_samples}; } else { return {nullptr, 0}; diff --git a/firmware/baseband/audio_dma.hpp b/firmware/baseband/audio_dma.hpp index e4720001f..2416b6cff 100644 --- a/firmware/baseband/audio_dma.hpp +++ b/firmware/baseband/audio_dma.hpp @@ -47,6 +47,7 @@ void init(); void configure(); void enable(); void disable(); +void shrink_tx_buffer(); audio::buffer_t tx_empty_buffer(); audio::buffer_t rx_empty_buffer(); diff --git a/firmware/baseband/proc_audiotx.cpp b/firmware/baseband/proc_audiotx.cpp index 22d237a46..0965aef7e 100644 --- a/firmware/baseband/proc_audiotx.cpp +++ b/firmware/baseband/proc_audiotx.cpp @@ -41,6 +41,12 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer) { } } + // Output to speaker too + uint32_t imod32 = i & (AUDIO_OUTPUT_BUFFER_SIZE - 1); + audio_data[imod32] = ((int16_t)audio_sample - 0x80) * (1.0f / 128.0f); + if (imod32 == (AUDIO_OUTPUT_BUFFER_SIZE - 1)) + audio_output.write(audio_buffer); + sample = tone_gen.process(audio_sample - 0x80); // FM @@ -95,6 +101,8 @@ void AudioTXProcessor::audio_config(const AudioTXConfigMessage& message) { tone_gen.configure(message.tone_key_delta, message.tone_key_mix_weight); progress_interval_samples = message.divider; resample_acc = 0; + audio_output.configure(false); + audio::dma::shrink_tx_buffer(); } void AudioTXProcessor::replay_config(const ReplayConfigMessage& message) { diff --git a/firmware/baseband/proc_audiotx.hpp b/firmware/baseband/proc_audiotx.hpp index d6cb06e5b..d11be3cba 100644 --- a/firmware/baseband/proc_audiotx.hpp +++ b/firmware/baseband/proc_audiotx.hpp @@ -27,6 +27,10 @@ #include "baseband_thread.hpp" #include "tone_gen.hpp" #include "stream_output.hpp" +#include "audio_output.hpp" +#include "audio_dma.hpp" + +#define AUDIO_OUTPUT_BUFFER_SIZE 32 class AudioTXProcessor : public BasebandProcessor { public: @@ -48,6 +52,10 @@ class AudioTXProcessor : public BasebandProcessor { int32_t sample{0}, delta{}; int8_t re{0}, im{0}; + float audio_data[AUDIO_OUTPUT_BUFFER_SIZE]; + buffer_f32_t audio_buffer{audio_data, AUDIO_OUTPUT_BUFFER_SIZE, 48000}; + AudioOutput audio_output{}; + size_t progress_interval_samples = 0, progress_samples = 0; bool configured{false};