Skip to content

Commit

Permalink
Merge pull request #837 from Daft-Freak/pico-audio-improvements
Browse files Browse the repository at this point in the history
Pico audio improvements
  • Loading branch information
Gadgetoid authored Sep 28, 2023
2 parents 2f6b9ad + 1b5d026 commit 657ef83
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 16 deletions.
34 changes: 26 additions & 8 deletions 32blit-pico/audio_i2s.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

static audio_buffer_pool *audio_pool = nullptr;

static struct audio_buffer *cur_buffer = nullptr;

void init_audio() {
static audio_format_t audio_format = {
.sample_freq = AUDIO_SAMPLE_FREQ,
Expand All @@ -24,7 +26,7 @@ void init_audio() {
.sample_stride = 2
};

struct audio_buffer_pool *producer_pool = audio_new_producer_pool(&producer_format, 4, 441);
struct audio_buffer_pool *producer_pool = audio_new_producer_pool(&producer_format, 4, 256);
const struct audio_format *output_format;

uint8_t dma_channel = dma_claim_unused_channel(true);
Expand Down Expand Up @@ -54,18 +56,34 @@ void init_audio() {
}

void update_audio(uint32_t time) {
// audio
struct audio_buffer *buffer = take_audio_buffer(audio_pool, false);
if(buffer) {
auto samples = (int16_t *) buffer->buffer->bytes;
// attempt to get new buffer
if(!cur_buffer) {
cur_buffer = take_audio_buffer(audio_pool, false);
if(cur_buffer)
cur_buffer->sample_count = 0;
}

if(cur_buffer) {
auto samples = ((int16_t *)cur_buffer->buffer->bytes) + cur_buffer->sample_count;

auto max_samples = cur_buffer->max_sample_count - cur_buffer->sample_count;

for(uint32_t i = 0; i < buffer->max_sample_count; i += 2) {
#ifdef AUDIO_MAX_SAMPLE_UPDATE
if(max_samples > AUDIO_MAX_SAMPLE_UPDATE)
max_samples = AUDIO_MAX_SAMPLE_UPDATE;
#endif

for(uint32_t i = 0; i < max_samples; i += 2) {
int val = (int)blit::get_audio_frame() - 0x8000;
*samples++ = val;
*samples++ = val;
}

buffer->sample_count = buffer->max_sample_count;
give_audio_buffer(audio_pool, buffer);
cur_buffer->sample_count += max_samples;

if(cur_buffer->sample_count == cur_buffer->max_sample_count) {
give_audio_buffer(audio_pool, cur_buffer);
cur_buffer = nullptr;
}
}
}
27 changes: 20 additions & 7 deletions 32blit-pico/audio_pwm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

static audio_buffer_pool *audio_pool = nullptr;

static struct audio_buffer *cur_buffer = nullptr;

void init_audio() {
static audio_format_t audio_format = {
.sample_freq = AUDIO_SAMPLE_FREQ,
Expand Down Expand Up @@ -62,17 +64,28 @@ void init_audio() {
}

void update_audio(uint32_t time) {
// audio
struct audio_buffer *buffer = take_audio_buffer(audio_pool, false);
if(buffer) {
auto samples = (int16_t *) buffer->buffer->bytes;
// attempt to get new buffer
if(!cur_buffer) {
cur_buffer = take_audio_buffer(audio_pool, false);
if(cur_buffer)
cur_buffer->sample_count = 0;
}

if(cur_buffer) {
auto samples = ((int16_t *)cur_buffer->buffer->bytes) + cur_buffer->sample_count;

for(uint32_t i = 0; i < buffer->max_sample_count; i++) {
auto max_samples = cur_buffer->max_sample_count - cur_buffer->sample_count;

for(uint32_t i = 0; i < max_samples; i++) {
int val = (int)blit::get_audio_frame() - 0x8000;
*samples++ = val;
}

buffer->sample_count = buffer->max_sample_count;
give_audio_buffer(audio_pool, buffer);
cur_buffer->sample_count += max_samples;

if(cur_buffer->sample_count == cur_buffer->max_sample_count) {
give_audio_buffer(audio_pool, cur_buffer);
cur_buffer = nullptr;
}
}
}
2 changes: 2 additions & 0 deletions 32blit-pico/board/vgaboard/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#define ALLOW_HIRES 0 // disable by default, mode switching isn't supported
#endif

#define AUDIO_MAX_SAMPLE_UPDATE 64

// spi
#define SD_SCK 5
#define SD_MOSI 18
Expand Down
22 changes: 21 additions & 1 deletion 32blit-pico/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "hardware/structs/rosc.h"
#include "hardware/vreg.h"
#include "hardware/timer.h"
#include "pico/binary_info.h"
#include "pico/multicore.h"
#include "pico/rand.h"
Expand Down Expand Up @@ -104,18 +105,30 @@ void update(uint32_t);

bool core1_started = false;

#ifdef ENABLE_CORE1
void core1_main() {
core1_started = true;
multicore_lockout_victim_init();

init_display_core1();
init_audio();

while(true) {
update_display_core1();
update_audio(::now());
sleep_us(1);
}
}

#else
static void alarm_callback(uint alarm_num) {
update_audio(::now());

timer_hw->intr = 1 << alarm_num;
hardware_alarm_set_target(alarm_num, make_timeout_time_ms(5));
}
#endif

int main() {
#if OVERCLOCK_250
// Apply a modest overvolt, default is 1.10v.
Expand Down Expand Up @@ -185,10 +198,18 @@ int main() {
init_input();
init_fs();
init_usb();
#if !defined(ENABLE_CORE1)
init_audio();
#endif

#if defined(ENABLE_CORE1)
multicore_launch_core1(core1_main);
#else
// fallback audio timer if core1 is unavailable / not enabled
int alarm_num = hardware_alarm_claim_unused(true);
hardware_alarm_set_callback(alarm_num, alarm_callback);
hardware_alarm_set_target(alarm_num, make_timeout_time_ms(5));
irq_set_priority(TIMER_IRQ_0 + alarm_num, PICO_LOWEST_IRQ_PRIORITY);
#endif

blit::set_screen_mode(ScreenMode::lores);
Expand All @@ -204,7 +225,6 @@ int main() {
update_display(now);
update_input();
int ms_to_next_update = tick(::now());
update_audio(now);
update_led();
update_usb();
update_multiplayer();
Expand Down

0 comments on commit 657ef83

Please sign in to comment.