Skip to content

Commit

Permalink
Rollback changes we dont need.
Browse files Browse the repository at this point in the history
  • Loading branch information
george-norton committed Aug 21, 2023
1 parent fdcb969 commit 8ff376c
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 49 deletions.
6 changes: 3 additions & 3 deletions firmware/code/configuration_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ static const default_configuration default_config = {
.filters = {
.filter = { FILTER_CONFIGURATION, sizeof(default_config.filters) },
.f1 = { PEAKING, {0}, 38.5, -21.0, 1.4 },
.f2 = { LOWSHELF, {0}, 60, -6.7, 0.5 },
.f3 = { PEAKING, {0}, 105, 5.5, 0.71 },
.f2 = { PEAKING, {0}, 60, -6.7, 0.5 },
.f3 = { LOWSHELF, {0}, 105, 5.5, 0.71 },
.f4 = { PEAKING, {0}, 280, -3.5, 1.1 },
.f5 = { PEAKING, {0}, 350, -1.6, 6.0 },
.f6 = { PEAKING, {0}, 425, 7.8, 1.3 },
Expand All @@ -68,7 +68,7 @@ static const default_configuration default_config = {
.f14 = { PEAKING, {0}, 6200, -15.0, 3.0 },
.f15 = { HIGHSHELF, {0}, 12000, -6.0, 0.71 }
},
.preprocessing = { .header = { PREPROCESSING_CONFIGURATION, sizeof(default_config.preprocessing) }, -0.16f, true, {0} }
.preprocessing = { .header = { PREPROCESSING_CONFIGURATION, sizeof(default_config.preprocessing) }, -0.06f, true, {0} }
};

// Grab the last 4k page of flash for our configuration strutures.
Expand Down
14 changes: 7 additions & 7 deletions firmware/code/i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void i2s_write_init(i2s_obj_t *self) {
self->prog_offset + self->pio_program->length - 1);
pio_sm_set_config(self->pio, self->sm, &config);

uint32_t *rbs = malloc(sizeof(uint8_t) * RINGBUF_LEN_IN_BYTES);
uint8_t *rbs = malloc(sizeof(uint8_t) * RINGBUF_LEN_IN_BYTES);
ringbuf_init(&self->ring_buffer, rbs, RINGBUF_LEN_IN_BYTES);

irq_set_exclusive_handler(DMA_IRQ_1, dma_irq_write_handler);
Expand Down Expand Up @@ -169,27 +169,27 @@ uint8_t *dma_get_buffer(i2s_obj_t *i2s_obj, uint channel) {
void feed_dma(i2s_obj_t *self, uint8_t *dma_buffer_p) {
// when data exists, copy samples from ring buffer
if (ringbuf_available_data(&self->ring_buffer) >= SIZEOF_HALF_DMA_BUFFER_IN_BYTES) {
for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i+=4)
ringbuf_pop(&self->ring_buffer, (uint32_t*)&dma_buffer_p[i]);
for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i++)
ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i]);
} else {
// underflow. clear buffer to transmit "silence" on the I2S bus
memset(dma_buffer_p, 0, SIZEOF_HALF_DMA_BUFFER_IN_BYTES);
}
}

uint i2s_stream_write(i2s_obj_t *self, const uint32_t *buf_out, uint size) {
uint i2s_stream_write(i2s_obj_t *self, const uint8_t *buf_out, uint size) {
if (size == 0) {
//printf("ERROR: buffer can't be length zero");
exit(1);
}

uint32_t num_words_written = copy_userbuf_to_ringbuf(self, buf_out, size);
return num_words_written;
uint32_t num_bytes_written = copy_userbuf_to_ringbuf(self, buf_out, size);
return num_bytes_written;
}

// TODO maybe we can skip every fourth byte, if we're doing this in 24-bit...
// could save on some processing power
uint32_t copy_userbuf_to_ringbuf(i2s_obj_t *self, const uint32_t *buf_out, uint size) {
uint32_t copy_userbuf_to_ringbuf(i2s_obj_t *self, const uint8_t *buf_out, uint size) {
uint32_t a_index = 0;

while (a_index < size) {
Expand Down
6 changes: 3 additions & 3 deletions firmware/code/i2s.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ typedef struct _i2s_obj_t {
extern i2s_obj_t i2s_write_obj;

void i2s_write_init(i2s_obj_t *);
uint i2s_stream_write(i2s_obj_t *, const uint32_t *, uint);
uint i2s_stream_write(i2s_obj_t *, const uint8_t *, uint);

void dma_irq_handler(uint8_t);
void dma_irq_write_handler(void);
Expand All @@ -68,6 +68,6 @@ void dma_configure(i2s_obj_t *);
uint8_t *dma_get_buffer(i2s_obj_t *, uint);
void feed_dma(i2s_obj_t *, uint8_t *);

uint32_t copy_userbuf_to_ringbuf(i2s_obj_t *, const uint32_t *, uint);
uint32_t copy_userbuf_to_ringbuf(i2s_obj_t *, const uint8_t *, uint);

#endif
#endif
8 changes: 4 additions & 4 deletions firmware/code/ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
// - Sequential atomic operations
// One byte of capacity is used to detect buffer empty/full

void ringbuf_init(ring_buf_t *rbuf, uint32_t *buffer, size_t size) {
void ringbuf_init(ring_buf_t *rbuf, uint8_t *buffer, size_t size) {
rbuf->buffer = buffer;
rbuf->size = size;
rbuf->head = 0;
rbuf->tail = 0;
}

bool ringbuf_push(ring_buf_t *rbuf, uint32_t data) {
bool ringbuf_push(ring_buf_t *rbuf, uint8_t data) {
size_t next_tail = (rbuf->tail + 1) % rbuf->size;

if (next_tail != rbuf->head) {
Expand All @@ -53,7 +53,7 @@ bool ringbuf_push(ring_buf_t *rbuf, uint32_t data) {
return false;
}

bool ringbuf_pop(ring_buf_t *rbuf, uint32_t *data) {
bool ringbuf_pop(ring_buf_t *rbuf, uint8_t *data) {
if (rbuf->head == rbuf->tail) {
// empty
return false;
Expand All @@ -78,4 +78,4 @@ size_t ringbuf_available_data(ring_buf_t *rbuf) {

size_t ringbuf_available_space(ring_buf_t *rbuf) {
return rbuf->size - ringbuf_available_data(rbuf) - 1;
}
}
10 changes: 5 additions & 5 deletions firmware/code/ringbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@
#include "pico/stdlib.h"

typedef struct _ring_buf_t {
uint32_t *buffer;
uint8_t *buffer;
size_t head;
size_t tail;
size_t size;
} ring_buf_t;

void ringbuf_init(ring_buf_t *, uint32_t *, size_t);
bool ringbuf_push(ring_buf_t *, uint32_t );
bool ringbuf_pop(ring_buf_t *, uint32_t *);
void ringbuf_init(ring_buf_t *, uint8_t *, size_t);
bool ringbuf_push(ring_buf_t *, uint8_t );
bool ringbuf_pop(ring_buf_t *, uint8_t *);
bool ringbuf_is_empty(ring_buf_t *);
bool ringbuf_is_full(ring_buf_t *);
size_t ringbuf_available_data(ring_buf_t *);
size_t ringbuf_available_space(ring_buf_t *);

#endif
#endif
81 changes: 54 additions & 27 deletions firmware/code/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,63 +124,90 @@ static void __no_inline_not_in_flash_func(_as_audio_packet)(struct usb_endpoint
int32_t *out = (int32_t *) userbuf;
int samples = usb_buffer->data_len / 2;

const fix3_28_t preamp = preprocessing.preamp;
for (int i = 0; i < samples; i ++) {
out[i] = fix16_mul(norm_fix3_28_from_s16sample(in[i]), preamp);
}

// keep on truckin'
usb_grow_transfer(ep->current_transfer, 1);
usb_packet_done(ep);

multicore_fifo_push_blocking(samples);
if (preprocessing.reverse_stereo) {
multicore_fifo_push_blocking((uintptr_t) (out - 1));
out ++;
for (int i = 0; i < samples; i+=2) {
out[i] = in[i+1];
out[i+1] = in[i];
}
}
else {
multicore_fifo_push_blocking((uintptr_t) out);
for (int i = 0; i < samples; i++)
out[i] = in[i];
}

// Make sure core 1 is ready for us.
multicore_fifo_pop_blocking();
multicore_fifo_push_blocking(CORE0_READY);
multicore_fifo_push_blocking(samples);

for (int i = 0; i < samples; i += 2) {
for (int j = 0; j < filter_stages; j++) {
out[i] = bqf_transform(out[i], &bqf_filters_left[j], &bqf_filters_mem_left[j]);
for (int j = 0; j < filter_stages; j++) {
// Left channel filter
for (int i = 0; i < samples; i += 2) {
fix3_28_t x_f16 = fix16_mul(norm_fix3_28_from_s16sample((int16_t) out[i]), preprocessing.preamp);

x_f16 = bqf_transform(x_f16, &bqf_filters_left[j],
&bqf_filters_mem_left[j]);

out[i] = (int32_t) norm_fix3_28_to_s16sample(x_f16);
}
out[i] = (int32_t) norm_fix3_28_to_s16sample(out[i]);
}

// Signal to core 1 that we have processed our samples, so it can write to I2S
// Block until core 1 has finished transforming the data
uint32_t ready = multicore_fifo_pop_blocking();
multicore_fifo_push_blocking(CORE0_READY);

// Update the volume if required. We do this from core1 as
// core0 is more heavily loaded, doing this from core0 can
// lead to audio crackling.
update_volume();

// Update filters if required
apply_config_changes();

// keep on truckin'
usb_grow_transfer(ep->current_transfer, 1);
usb_packet_done(ep);
}

void __no_inline_not_in_flash_func(core1_entry)() {
uint32_t *userbuf = (uint32_t *) multicore_fifo_pop_blocking();
uint8_t *userbuf = (uint8_t *) multicore_fifo_pop_blocking();
int32_t *out = (int32_t *) userbuf;

// Signal that the thread has started
multicore_fifo_push_blocking(CORE1_READY);

while (true) {
// Signal to core 0 that we are ready to accept new data
multicore_fifo_push_blocking(CORE1_READY);

// Block until the userbuf is filled with data
uint32_t ready = multicore_fifo_pop_blocking();
while (ready != CORE0_READY)
ready = multicore_fifo_pop_blocking();

const uint32_t samples = multicore_fifo_pop_blocking();
int32_t *out = (int32_t *) multicore_fifo_pop_blocking();

for (int i = 1; i < samples; i += 2) {
for (int j = 0; j < filter_stages; j++) {
out[i] = bqf_transform(out[i], &bqf_filters_right[j], &bqf_filters_mem_right[j]);
for (int j = 0; j < filter_stages; j++) {
for (int i = 1; i < samples; i += 2) {
fix3_28_t x_f16 = fix16_mul(norm_fix3_28_from_s16sample((int16_t) out[i]), preprocessing.preamp);

x_f16 = bqf_transform(x_f16, &bqf_filters_right[j],
&bqf_filters_mem_right[j]);

out[i] = (int16_t) norm_fix3_28_to_s16sample(x_f16);
}
out[i] = (int32_t) norm_fix3_28_to_s16sample(out[i]);
}

// Signal to core 0 that the data has all been transformed
multicore_fifo_push_blocking(CORE1_READY);

// Wait for Core 0 to finish running its filtering before we apply config updates
multicore_fifo_pop_blocking();
i2s_stream_write(&i2s_write_obj, userbuf, samples);

i2s_stream_write(&i2s_write_obj, userbuf, samples * 4);
}
}

static const audio_device_config ad_conf;

void setup() {
set_sys_clock_khz(SYSTEM_FREQ / 1000, true);
sleep_ms(100);
Expand Down

0 comments on commit 8ff376c

Please sign in to comment.