summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2025-01-31 19:46:56 -0500
committerClyne Sullivan <clyne@bitgloo.com>2025-01-31 19:46:56 -0500
commit8f6aa50caa0de4b551d83629a6eed378a0451ec7 (patch)
tree49de05d6b25f128fc084ca6acbf0259aafbfc3a7
parente9f471c4e0a4047bb960b28e4de1447b84a22e4f (diff)
reduce process cycles; fix sample bit-order
-rw-r--r--Core/Src/main.c73
-rw-r--r--Makefile2
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]
##########################################################################################################################
# ------------------------------------------------