From 8f6aa50caa0de4b551d83629a6eed378a0451ec7 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 31 Jan 2025 19:46:56 -0500 Subject: [PATCH] reduce process cycles; fix sample bit-order --- Core/Src/main.c | 73 +++++++++++++++++++++++++++---------------------- Makefile | 2 +- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/Core/Src/main.c b/Core/Src/main.c index 67e6ab8..7c41e3f 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -27,19 +27,17 @@ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ -typedef struct { - int32_t value : 18; -} sample_t; +typedef uint32_t sample_t; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ -#define SAMPLE_COUNT (256) // Sample count per half-transfer +#define SAMPLE_COUNT (256) // (Stereo!) Sample count per half-transfer #define SAMPLES_PER_REPORT (48000) // Report every second given our 48 kHz rate #define MIC_OFFSET_DB ( 0.f) // Linear offset #define MIC_SENSITIVITY (-26.f) // dBFS value expected at MIC_REF_DB #define MIC_REF_DB ( 94.f) // dB where sensitivity is specified -#define MIC_BITS (18) +#define MIC_BITS (18u) /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ @@ -104,7 +102,7 @@ int main(void) /* USER CODE BEGIN 1 */ ln10 = qfp_fln(10.f); - MIC_REF_AMPL = qfp_fmul(qfp_int2float((1 << (MIC_BITS - 1)) - 1), + MIC_REF_AMPL = qfp_fmul(qfp_int2float((1u << (MIC_BITS - 1)) - 1), qfp_fpow(10.f, MIC_SENSITIVITY / 20.f)); /* USER CODE END 1 */ @@ -443,53 +441,64 @@ error : return errorcode; } -void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)hdma->Parent; - (void)hspi; -} - -static float process(float in_div4) +static inline float process(float in_div4) { - static float z1 = 0, z2 = 0, z3 = 0, z5 = 0; + static float z[4] = {0.f, 0.f, 0.f, 0.f}; - float out1 = qfp_fadd(in_div4, z1); - z1 = qfp_fadd(qfp_fmul(1.062f, out1), z2); - z2 = qfp_fsub(qfp_fmul(-0.14f, out1), in_div4); + float out1 = qfp_fadd(in_div4, z[0]); + z[0] = qfp_fadd(qfp_fmul(out1, 1.062f), z[1]); + z[1] = qfp_fsub(qfp_fmul(out1, -0.14f), in_div4); - float out2 = qfp_fadd(out1, z3); - z3 = out1; + float out2 = qfp_fadd(out1, z[2]); + z[2] = out1; - float out3 = qfp_fadd(out2, z5); - z5 = qfp_fsub(qfp_fmul(0.985f, out3), out2); + float out3 = qfp_fadd(out2, z[3]); + z[3] = qfp_fsub(qfp_fmul(out3, 0.985f), out2); return out3; } -void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) +static void processSampleBlock(sample_t *sample) { HAL_GPIO_WritePin(IDLE_GPIO_Port, IDLE_Pin, GPIO_PIN_RESET); - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)hdma->Parent; - (void)hspi; + // SAMPLE_COUNT is number of samples in this block + // Divide by 2 for left channel only + // Divide by 8 for stride to reduce compute time +#define STRIDE (2 * 8) + + for (int i = 0; i < SAMPLE_COUNT; i += STRIDE) { + // 18-bit sample comes in as big-endian with right padding. + // 1. Convert to little-endian: + int samp; + asm("rev %0, %1" : "=r" (samp) : "r" (sample[i])); + // 2. Arithmetic shift right to remove padding, +2 to make "in_div4" + float f = process(qfp_int2float(samp >> (32 - MIC_BITS + 2))); - sample_t *sample = (sample_t *)I2S_Receive_Buffer; - for (int i = 0; i < SAMPLE_COUNT / 8; i++) { - float f = process(qfp_int2float(sample[i].value / 4)); - DB_Sum_Squares = qfp_fadd(DB_Sum_Squares, qfp_fmul(f, f)); + DB_Sum_Squares = qfp_fadd(qfp_fmul(f, f), DB_Sum_Squares); } - DB_Count += SAMPLE_COUNT * 2; // Pretend we sampled the entire I2S buffer + DB_Count += SAMPLE_COUNT / STRIDE; - if (DB_Count > SAMPLES_PER_REPORT) { + if (DB_Count >= SAMPLES_PER_REPORT / STRIDE * 2) { float rms = qfp_fsqrt(qfp_fdiv(DB_Sum_Squares, qfp_uint2float(DB_Count))); - float db = qfp_fadd(MIC_OFFSET_DB + MIC_REF_DB, qfp_fmul(20.f, - qfp_flog10(qfp_fdiv(rms, MIC_REF_AMPL)))); + float db = qfp_fadd(qfp_fmul(qfp_flog10(qfp_fdiv(rms, MIC_REF_AMPL)), 20.f), + MIC_OFFSET_DB + MIC_REF_DB); DB_Sum_Squares = 0.f; DB_Count = 0; printf("%d dB\r\n", qfp_float2int(db)); } } + +void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + processSampleBlock((sample_t *)I2S_Receive_Buffer + SAMPLE_COUNT); +} + +void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + processSampleBlock((sample_t *)I2S_Receive_Buffer); +} /* USER CODE END 4 */ /** diff --git a/Makefile b/Makefile index ab0211a..b26e4da 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [4.5.0-RC5] date: [Thu Jan 30 17:24:56 EST 2025] +# File automatically-generated by tool: [projectgenerator] version: [4.5.0-RC5] date: [Fri Jan 31 17:56:51 EST 2025] ########################################################################################################################## # ------------------------------------------------