| 339 | } |
| 340 | |
| 341 | void 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. |
nothing calls this directly
no outgoing calls
no test coverage detected