]> code.bitgloo.com Git - clyne/u0-decibels.git/commitdiff
reduce process cycles; fix sample bit-order
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 1 Feb 2025 00:46:56 +0000 (19:46 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 1 Feb 2025 00:46:56 +0000 (19:46 -0500)
Core/Src/main.c
Makefile

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