Added Audio Out to Soundboard app (#1748)

This commit is contained in:
Mark Thompson 2024-01-09 13:50:45 -06:00 committed by GitHub
parent 0e6f303eec
commit 485f57d86b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 7 deletions

View file

@ -26,6 +26,7 @@
#include "string_format.hpp" #include "string_format.hpp"
#include "tonesets.hpp" #include "tonesets.hpp"
#include "ui_tone_key.hpp" #include "ui_tone_key.hpp"
#include "audio.hpp"
using namespace tonekey; using namespace tonekey;
using namespace portapack; using namespace portapack;
@ -40,6 +41,7 @@ void SoundBoardView::stop() {
if (is_active()) if (is_active())
replay_thread.reset(); replay_thread.reset();
audio::output::stop();
transmitter_model.disable(); transmitter_model.disable();
tx_view.set_transmitting(false); tx_view.set_transmitting(false);
@ -123,6 +125,8 @@ void SoundBoardView::start_tx(const uint32_t id) {
transmitter_model.enable(); transmitter_model.enable();
tx_view.set_transmitting(true); tx_view.set_transmitting(true);
audio::output::start();
} }
/*void SoundBoardView::show_infos() { /*void SoundBoardView::show_infos() {
@ -227,6 +231,7 @@ SoundBoardView::SoundBoardView(
//&text_title, //&text_title,
//&text_duration, //&text_duration,
//&progressbar, //&progressbar,
&field_volume,
&page_info, &page_info,
&check_loop, &check_loop,
&check_random, &check_random,
@ -274,7 +279,6 @@ SoundBoardView::SoundBoardView(
SoundBoardView::~SoundBoardView() { SoundBoardView::~SoundBoardView() {
stop(); stop();
transmitter_model.disable();
baseband::shutdown(); baseband::shutdown();
} }

View file

@ -91,7 +91,7 @@ class SoundBoardView : public View {
void on_select_entry(); void on_select_entry();
Labels labels{ Labels labels{
//{ { 0, 20 * 8 + 4 }, "Title:", Color::light_grey() }, {{24 * 8, 180}, "Vol:", Color::light_grey()},
{{0, 180}, "Key:", Color::light_grey()}}; {{0, 180}, "Key:", Color::light_grey()}};
Button button_next_page{ Button button_next_page{
@ -122,10 +122,13 @@ class SoundBoardView : public View {
};*/ };*/
OptionsField options_tone_key{ OptionsField options_tone_key{
{32, 180}, {4 * 8, 180},
18, 18,
{}}; {}};
AudioVolumeField field_volume{
{28 * 8, 180}};
Checkbox check_loop{ Checkbox check_loop{
{0, 25 * 8 + 4}, {0, 25 * 8 + 4},
4, 4,

View file

@ -123,10 +123,10 @@ constexpr gpdma::channel::Config config_rx() {
/* TODO: Clean up terminology around "buffer", "transfer", "samples" */ /* TODO: Clean up terminology around "buffer", "transfer", "samples" */
constexpr size_t buffer_samples_log2n = 7; 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_log2n = 2;
constexpr size_t transfers_per_buffer = (1 << transfers_per_buffer_log2n); 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; 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 transfers_mask = transfers_per_buffer - 1;
constexpr size_t buffer_bytes = buffer_samples * sizeof(sample_t); 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* tx_next_lli = nullptr;
static volatile const gpdma::channel::LLI* rx_next_lli = nullptr; static volatile const gpdma::channel::LLI* rx_next_lli = nullptr;
static bool single_tx_buffer = false;
static void tx_transfer_complete() { static void tx_transfer_complete() {
tx_next_lli = gpdma_channel_i2s0_tx.next_lli(); tx_next_lli = gpdma_channel_i2s0_tx.next_lli();
} }
@ -213,11 +215,16 @@ void disable() {
gpdma_channel_i2s0_rx.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() { buffer_t tx_empty_buffer() {
const auto next_lli = tx_next_lli; const auto next_lli = tx_next_lli;
if (next_lli) { if (next_lli) {
const size_t next_index = next_lli - &lli_tx_loop[0]; 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<sample_t*>(lli_tx_loop[free_index].srcaddr), transfer_samples}; return {reinterpret_cast<sample_t*>(lli_tx_loop[free_index].srcaddr), transfer_samples};
} else { } else {
return {nullptr, 0}; return {nullptr, 0};

View file

@ -47,6 +47,7 @@ void init();
void configure(); void configure();
void enable(); void enable();
void disable(); void disable();
void shrink_tx_buffer();
audio::buffer_t tx_empty_buffer(); audio::buffer_t tx_empty_buffer();
audio::buffer_t rx_empty_buffer(); audio::buffer_t rx_empty_buffer();

View file

@ -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); sample = tone_gen.process(audio_sample - 0x80);
// FM // FM
@ -95,6 +101,8 @@ void AudioTXProcessor::audio_config(const AudioTXConfigMessage& message) {
tone_gen.configure(message.tone_key_delta, message.tone_key_mix_weight); tone_gen.configure(message.tone_key_delta, message.tone_key_mix_weight);
progress_interval_samples = message.divider; progress_interval_samples = message.divider;
resample_acc = 0; resample_acc = 0;
audio_output.configure(false);
audio::dma::shrink_tx_buffer();
} }
void AudioTXProcessor::replay_config(const ReplayConfigMessage& message) { void AudioTXProcessor::replay_config(const ReplayConfigMessage& message) {

View file

@ -27,6 +27,10 @@
#include "baseband_thread.hpp" #include "baseband_thread.hpp"
#include "tone_gen.hpp" #include "tone_gen.hpp"
#include "stream_output.hpp" #include "stream_output.hpp"
#include "audio_output.hpp"
#include "audio_dma.hpp"
#define AUDIO_OUTPUT_BUFFER_SIZE 32
class AudioTXProcessor : public BasebandProcessor { class AudioTXProcessor : public BasebandProcessor {
public: public:
@ -48,6 +52,10 @@ class AudioTXProcessor : public BasebandProcessor {
int32_t sample{0}, delta{}; int32_t sample{0}, delta{};
int8_t re{0}, im{0}; 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; size_t progress_interval_samples = 0, progress_samples = 0;
bool configured{false}; bool configured{false};