MCPcopy Create free account
hub / github.com/BlueAndi/Pixelix / handleFreqBins

Method handleFreqBins

lib/SoundReactivePlugin/src/SoundReactivePlugin.cpp:341–448  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

339}
340
341void SoundReactivePlugin::handleFreqBins(float* freqBins, size_t freqBinLen)
342{
343 float octaveFreqBands[MAX_FREQ_BANDS];
344 uint16_t freqBinIdx = 0U;
345 float peak = 0.0F;
346 float avgDigital = 0.0F;
347 uint8_t bandIdx = 0U;
348
349 convertToOctaveFreqBands(octaveFreqBands, MAX_FREQ_BANDS, freqBins, freqBinLen);
350 avgDigital = calculateAmplitudeAverage(octaveFreqBands, MAX_FREQ_BANDS);
351
352 for (bandIdx = 0U; bandIdx < MAX_FREQ_BANDS; ++bandIdx)
353 {
354 /* If the ampltiude average is lower than the equivalent input noise (from datasheet),
355 * the correction factors will be calculated. The amplitude average is used to detect
356 * silence, which is necessary for this automatic calibration.
357 */
358 if (INMP441_NOISE_FLOOR_DIGITAL > static_cast<int32_t>(avgDigital))
359 {
360 constexpr const float WEIGHT_NEW_VALUE = 0.1F;
361 constexpr const float WEIGHT_OLD_VALUE = 1.0F - WEIGHT_NEW_VALUE;
362 constexpr const float NOISE_FLOOR = static_cast<float>(INMP441_NOISE_FLOOR_DIGITAL);
363
364 /* Calculate with weighted average to avoid jumping. */
365 m_corrFactors[bandIdx] = WEIGHT_OLD_VALUE * m_corrFactors[bandIdx] + WEIGHT_NEW_VALUE * (NOISE_FLOOR / octaveFreqBands[bandIdx]);
366 }
367
368 /* Normalize */
369 octaveFreqBands[bandIdx] *= m_corrFactors[bandIdx];
370
371 /* Calculate the spectrum amplitude in dB SPL
372 * The shown frequency spectrum amplitudes consider now the silent and loud parts better.
373 *
374 * = sensitivity [dB SPL] + 20 * log10(frequency amplitude digital / sensitivity digital)
375 */
376 octaveFreqBands[bandIdx] = INMP441_SENSITIVITY_SPL + 20.0F * log10f(octaveFreqBands[bandIdx] / static_cast<float>(IMMP441_SENSITIVITY_DIGITAL));
377
378 /* The amplitude shall consider only the dynamic range
379 * by removing the equivalent input noise level.
380 */
381 if (INMP441_NOISE_SPL >= octaveFreqBands[bandIdx])
382 {
383 octaveFreqBands[bandIdx] = HEARING_THRESHOLD;
384 }
385 else
386 {
387 octaveFreqBands[bandIdx] -= INMP441_NOISE_SPL;
388 }
389
390 /* Determine peak over all frequency bands for automatic gain control. */
391 if (octaveFreqBands[bandIdx] > peak)
392 {
393 peak = octaveFreqBands[bandIdx];
394 }
395 }
396
397 /* Adapt the dynamic range on the y-axis, but limit it to a minimum,
398 * otherwise the bar's will jump driven by silent tones.

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected