aboutsummaryrefslogtreecommitdiffstats
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp90
1 files changed, 57 insertions, 33 deletions
diff --git a/main.cpp b/main.cpp
index 298c3f8..de9e093 100644
--- a/main.cpp
+++ b/main.cpp
@@ -34,7 +34,7 @@ static constexpr auto MIC_BITS = 18u;
static constexpr auto SAMPLE_RATE = 48000u;
static constexpr unsigned I2S_BUFSIZ = 1024;
-static constexpr unsigned I2S_STRIDE = 16;
+static constexpr unsigned I2S_USESIZ = 16;
// Calculate reference amplitude value at compile time
static const auto MIC_REF_AMPL = sos_t((1 << (MIC_BITS - 1)) - 1) *
@@ -45,6 +45,7 @@ static std::array<uint32_t, I2S_BUFSIZ> i2sBuffer;
static sos_t Leq_sum_sqr (0.f);
static unsigned Leq_samples = 0;
+static void blinkDb(int db);
static void i2sCallback(I2SDriver *i2s);
static constexpr unsigned I2SPRval = 16'000'000 / SAMPLE_RATE / 32 / 2;
@@ -64,45 +65,66 @@ int main(void)
{
halInit();
osalSysEnable();
- osalThreadSleepMilliseconds(2000);
-
- palSetPadMode(GPIOB, 7, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOF, 2, PAL_MODE_UNCONNECTED);
- palSetLineMode(LINE_I2S_SD, PAL_MODE_ALTERNATE(0));
- palSetLineMode(LINE_I2S_WS, PAL_MODE_ALTERNATE(0));
- palSetLineMode(LINE_I2S_CK, PAL_MODE_ALTERNATE(0));
- palSetLineMode(LINE_USART2_TX, PAL_MODE_ALTERNATE(1));
-
- sdStart(&SD2, NULL);
- sdWrite(&SD2, (uint8_t *)"Noisemeter\n", 11);
- osalThreadSleepMilliseconds(2);
+ i2sReady.store(true);
i2sStart(&I2SD1, &i2sConfig);
i2sStartExchange(&I2SD1);
+ // Microphone warmup time
+ osalThreadSleepMilliseconds(140);
+ // Reach filter delay steady state
+ i2sReady.store(false);
+ osalThreadSleepMilliseconds(120);
+ // Discard initial readings
+ Leq_sum_sqr = 0.f;
+ Leq_samples = 0;
- uint8_t strbuf[7] = { 0, 0, 0, 'd', 'B', '\n', '\0' };
for (;;) {
i2sReady.store(false);
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
+ //palClearLine(LINE_TP1);
__WFI();
+ //palSetLine(LINE_TP1);
- palSetPad(GPIOB, 7);
- const sos_t Leq_RMS = qfp_fsqrt(Leq_sum_sqr / qfp_uint2float(Leq_samples));
+ const auto sum_sqr = std::exchange(Leq_sum_sqr, sos_t(0.f));
+ const auto count = std::exchange(Leq_samples, 0);
+ const sos_t Leq_RMS = qfp_fsqrt(sum_sqr / qfp_uint2float(count));
const sos_t Leq_dB = MIC_OFFSET_DB + MIC_REF_DB + sos_t(20.f) *
qfp_flog10(Leq_RMS / MIC_REF_AMPL);
- Leq_sum_sqr = sos_t(0.f);
- Leq_samples = 0;
-
- auto n = std::clamp(qfp_float2int(Leq_dB), 0, 999);
- strbuf[2] = n % 10 + '0'; n /= 10;
- strbuf[1] = n % 10 + '0'; n /= 10;
- strbuf[0] = n ? n + '0' : ' ';
- sdWrite(&SD2, strbuf, sizeof(strbuf));
- osalThreadSleepMilliseconds(2);
- palClearPad(GPIOB, 7);
+ const auto n = std::clamp(qfp_float2int(Leq_dB), 0, 999);
+ blinkDb(n);
}
}
+void blinkDb(int db)
+{
+ auto line = LINE_LED0;
+
+ if (db < 45)
+ line = LINE_LED0;
+ else if (db < 55)
+ line = LINE_LED1;
+ else if (db < 65)
+ line = LINE_LED2;
+ else if (db < 75)
+ line = LINE_LED3;
+ else if (db < 82)
+ line = LINE_LED4;
+ else if (db < 87)
+ line = LINE_LED5;
+ else if (db < 92)
+ line = LINE_LED6;
+ else if (db < 97)
+ line = LINE_LED7;
+ else if (db < 102)
+ line = LINE_LED8;
+ else
+ line = LINE_LED9;
+
+ palClearLine(line);
+ osalThreadSleepMilliseconds(100);
+ palSetLine(line);
+}
+
__attribute__((section(".data")))
int32_t fixsample(uint32_t s) {
return (int32_t)(((s & 0xFFFF) << 16) | (s >> 16)) >> (32 - MIC_BITS);
@@ -114,27 +136,29 @@ void i2sCallback(I2SDriver *i2s)
if (i2sReady.load())
return;
- palSetPad(GPIOB, 7);
+ //palSetLine(LINE_TP1);
+
const auto halfsize = i2sBuffer.size() / 2;
const auto source = i2sBuffer.data() + (i2sIsBufferComplete(i2s) ? halfsize : 0);
auto samples = reinterpret_cast<sos_t *>(source);
std::ranges::copy(
- std::views::counted(source, halfsize / I2S_STRIDE)
+ std::views::counted(source, I2S_USESIZ * 2)
| std::ranges::views::stride(2)
| std::views::transform([](uint32_t s) { return sos_t(qfp_int2float_asm(fixsample(s))); }),
samples);
- auto samps = std::views::counted(samples, halfsize / (2 * I2S_STRIDE));
+ auto samps = std::views::counted(samples, I2S_USESIZ);
// Accumulate Leq sum
MIC_EQUALIZER.filter(samps);
Leq_sum_sqr += WEIGHTING.filter_sum_sqr(samps);
- Leq_samples += samps.size();
+ Leq_samples += halfsize / 2;
- // Wakeup main thread for dB calculation every second
- if (Leq_samples >= SAMPLE_RATE / I2S_STRIDE) {
+ // Wakeup main thread for dB calculation every half second
+ if (Leq_samples >= SAMPLE_RATE / 2) {
i2sReady.store(true);
SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
}
- palClearPad(GPIOB, 7);
+
+ //palClearLine(LINE_TP1);
}