From 5fd063a9af27f3486455108ee527133654750107 Mon Sep 17 00:00:00 2001 From: George Norton Date: Sun, 4 Jun 2023 00:47:54 +0100 Subject: [PATCH] Reverse stereo and preamp. --- firmware/code/configuration_manager.c | 58 ++++++++++++++++++++------- firmware/code/configuration_manager.h | 4 +- firmware/code/configuration_types.h | 16 ++++++-- firmware/code/run.c | 26 ++++++++++-- firmware/code/run.h | 8 ++++ 5 files changed, 89 insertions(+), 23 deletions(-) diff --git a/firmware/code/configuration_manager.c b/firmware/code/configuration_manager.c index c6b5cf8..f723721 100644 --- a/firmware/code/configuration_manager.c +++ b/firmware/code/configuration_manager.c @@ -47,12 +47,13 @@ static const default_configuration default_config = { .set_configuration = { SET_CONFIGURATION, sizeof(default_config) }, .filters = { .filter = { FILTER_CONFIGURATION, sizeof(default_config.filters) }, - .f1 = { PEAKING, 38, -19, 0.9 }, - .f2 = { LOWSHELF, 2900, 2, 0.7 }, - .f3 = { PEAKING, 430, 3, 3.5 }, - .f4 = { HIGHSHELF, 8400, 2, 0.7 }, - .f5 = { PEAKING, 4800, 3, 5 } - } + .f1 = { PEAKING, {0}, 38, -19, 0.9 }, + .f2 = { LOWSHELF, {0}, 2900, 2, 0.7 }, + .f3 = { PEAKING, {0}, 430, 3, 3.5 }, + .f4 = { HIGHSHELF, {0}, 8400, 2, 0.7 }, + .f5 = { PEAKING, {0}, 4800, 3, 5 } + }, + .preprocessing = { .header = { PREPROCESSING_CONFIGURATION, sizeof(default_config.preprocessing) }, -0.1f, false, {0} } }; // Grab the last 4k page of flash for our configuration strutures. @@ -96,6 +97,8 @@ bool validate_filter_configuration(filter_configuration_tlv *filters) case BANDPASSPEAK: case NOTCH: case ALLPASS: { + //filter2 *args = (filter2 *)ptr; + //printf("Found Filter %d: %0.2f %0.2f\n", args->type, args->f0, args->Q); if (remaining < sizeof(filter2)) { printf("Error! Not enough data left for filter2 (%d)..\n", remaining); return false; @@ -105,6 +108,8 @@ bool validate_filter_configuration(filter_configuration_tlv *filters) case PEAKING: case LOWSHELF: case HIGHSHELF: { + //filter3 *args = (filter3 *)ptr; + //printf("Found Filter %d: %0.2f %0.2f %0.2f\n", args->type, args->f0, args->db_gain, args->Q); if (remaining < sizeof(filter3)) { printf("Error! Not enough data left for filter3 (%d)..\n", remaining); return false; @@ -155,15 +160,25 @@ void apply_filter_configuration(filter_configuration_tlv *filters) { } bool validate_configuration(tlv_header *config) { - if (config->type != SET_CONFIGURATION) { - printf("Unexpcected Config type: %d\n", config->type); - return false; + uint8_t *ptr = NULL; + switch (config->type) + { + case SET_CONFIGURATION: + ptr = (uint8_t *) config->value; + break; + case FLASH_HEADER: { + ptr = (uint8_t *) ((flash_header_tlv*) config)->tlvs; + break; + } + default: + printf("Unexpected Config type: %d\n", config->type); + return false; } - uint8_t *ptr = (uint8_t *)config->value; const uint8_t *end = (uint8_t *)config + config->length; while (ptr < end) { tlv_header* tlv = (tlv_header*) ptr; if (tlv->length < 4) { + printf("Bad length... %d\n", tlv->length); return false; } switch (tlv->type) { @@ -172,6 +187,14 @@ bool validate_configuration(tlv_header *config) { return false; } break; + case PREPROCESSING_CONFIGURATION: { + preprocessing_configuration_tlv* preprocessing_config = (preprocessing_configuration_tlv*) tlv; + //printf("Preproc %0.2f %d\n", preprocessing_config->preamp, preprocessing_config->reverse_stereo); + if (tlv->length != sizeof(preprocessing_configuration_tlv)) { + printf("Preprocessing size missmatch: %u != %zu\n", tlv->length, sizeof(preprocessing_configuration_tlv)); + return false; + } + break;} default: // Unknown TLVs are not invalid, just ignored. break; @@ -193,17 +216,23 @@ bool apply_configuration(tlv_header *config) { break; } default: - printf("Unexpcected Config type: %d\n", config->type); + printf("Unexpected Config type: %d\n", config->type); return false; } const uint8_t *end = (uint8_t *)config + config->length; - while (ptr < end) { + while ((ptr + 4) < end) { tlv_header* tlv = (tlv_header*) ptr; switch (tlv->type) { case FILTER_CONFIGURATION: apply_filter_configuration((filter_configuration_tlv*) tlv); break; + case PREPROCESSING_CONFIGURATION: { + preprocessing_configuration_tlv* preprocessing_config = (preprocessing_configuration_tlv*) tlv; + preprocessing.preamp = fix16_from_dbl(1.0 + preprocessing_config->preamp); + preprocessing.reverse_stereo = preprocessing_config->reverse_stereo; + break; + } default: break; } @@ -248,7 +277,8 @@ bool process_cmd(tlv_header* cmd) { switch (cmd->type) { case SET_CONFIGURATION: if (validate_configuration(cmd)) { - inactive_working_configuration = inactive_working_configuration ? 0 : 1; + inactive_working_configuration = (inactive_working_configuration ? 0 : 1); + ((tlv_header*) working_configuration[inactive_working_configuration])->length = 0; reload_config = true; return true; } @@ -277,7 +307,7 @@ void config_out_packet(struct usb_endpoint *ep) { const uint16_t transfer_length = ((tlv_header*) working_configuration[inactive_working_configuration])->length; //printf("config_length %d %d\n", transfer_length, write_offset); - if (write_offset >= transfer_length) { + if (transfer_length && write_offset >= transfer_length) { // Command complete, fill the result buffer tlv_header* result = ((tlv_header*) result_buffer); write_offset = 0; diff --git a/firmware/code/configuration_manager.h b/firmware/code/configuration_manager.h index 98825cb..cb5bfde 100644 --- a/firmware/code/configuration_manager.h +++ b/firmware/code/configuration_manager.h @@ -32,8 +32,8 @@ struct usb_endpoint; #define INIT_FILTER3(T) { \ filter3 *args = (filter3 *)ptr; \ - bqf_##T##_config(SAMPLING_FREQ, args->f0, args->dBgain, args->Q, &bqf_filters_left[filter_stages]); \ - bqf_##T##_config(SAMPLING_FREQ, args->f0, args->dBgain, args->Q, &bqf_filters_right[filter_stages]); \ + bqf_##T##_config(SAMPLING_FREQ, args->f0, args->db_gain, args->Q, &bqf_filters_left[filter_stages]); \ + bqf_##T##_config(SAMPLING_FREQ, args->f0, args->db_gain, args->Q, &bqf_filters_right[filter_stages]); \ ptr += sizeof(filter3); \ break; \ } diff --git a/firmware/code/configuration_types.h b/firmware/code/configuration_types.h index 1b2de14..d1c6438 100644 --- a/firmware/code/configuration_types.h +++ b/firmware/code/configuration_types.h @@ -49,15 +49,17 @@ typedef struct __attribute__((__packed__)) _tlv_header { } tlv_header; typedef struct __attribute__((__packed__)) _filter2 { - uint32_t type; + uint8_t type; + uint8_t reserved[3]; double f0; double Q; } filter2; typedef struct __attribute__((__packed__)) _filter3 { - uint32_t type; + uint8_t type; + uint8_t reserved[3]; double f0; - double dBgain; + double db_gain; double Q; } filter3; @@ -80,6 +82,13 @@ typedef struct __attribute__((__packed__)) _flash_header_tlv { const uint8_t tlvs[]; } flash_header_tlv; +typedef struct __attribute__((__packed__)) _preprocessing_configuration_tlv { + tlv_header header; + double preamp; + uint8_t reverse_stereo; + uint8_t reserved[3]; +} preprocessing_configuration_tlv; + typedef struct __attribute__((__packed__)) _filter_configuration_tlv { tlv_header header; const uint8_t filters[]; @@ -101,6 +110,7 @@ typedef struct __attribute__((__packed__)) _default_configuration { filter3 f4; filter3 f5; } filters; + preprocessing_configuration_tlv preprocessing; } default_configuration; #endif // __CONFIGURATION_TYPES_H__ \ No newline at end of file diff --git a/firmware/code/run.c b/firmware/code/run.c index 5bee802..38226e2 100644 --- a/firmware/code/run.c +++ b/firmware/code/run.c @@ -64,6 +64,11 @@ static struct { .freq = 48000, }; +preprocessing_config preprocessing = { + .preamp = fix16_one, + .reverse_stereo = false +}; + static char spi_serial_number[17] = ""; enum vendor_cmds { @@ -103,8 +108,16 @@ static void _as_audio_packet(struct usb_endpoint *ep) { int32_t *out = (int32_t *) userbuf; int samples = usb_buffer->data_len / 2; - for (int i = 0; i < samples; i++) - out[i] = in[i]; + if (preprocessing.reverse_stereo) { + for (int i = 0; i < samples; i+=2) { + out[i] = in[i+1]; + out[i+1] = in[i]; + } + } + else { + for (int i = 0; i < samples; i++) + out[i] = in[i]; + } multicore_fifo_push_blocking(CORE0_READY); multicore_fifo_push_blocking(samples); @@ -112,7 +125,7 @@ static void _as_audio_packet(struct usb_endpoint *ep) { for (int j = 0; j < filter_stages; j++) { // Left channel filter for (int i = 0; i < samples; i += 2) { - fix16_t x_f16 = fix16_from_int((int16_t) out[i]); + fix16_t x_f16 = fix16_mul(fix16_from_int((int16_t) out[i]), preprocessing.preamp); x_f16 = bqf_transform(x_f16, &bqf_filters_left[j], &bqf_filters_mem_left[j]); @@ -168,7 +181,7 @@ void core1_entry() { for (int j = 0; j < filter_stages; j++) { for (int i = 1; i < limit; i += 2) { - fix16_t x_f16 = fix16_from_int((int16_t) out[i]); + fix16_t x_f16 = fix16_mul(fix16_from_int((int16_t) out[i]), preprocessing.preamp); x_f16 = bqf_transform(x_f16, &bqf_filters_right[j], &bqf_filters_mem_right[j]); @@ -198,6 +211,11 @@ void setup() { sleep_ms(100); stdio_init_all(); + for (int i=0; i