Experts,
I’ve created a basically stock sketch with arduinoFFT, and life is good. But in my effort to recognize any sounds louder than the background, I ran into an interesting problem: When is loud loud enough?
I go through the vReal loop, adding values, calculating the average-even taking out the 2 loudest bins’ values, but this in no way can compensate for additional or fewer noise sources. To illustrate, this is where I am now:
double AlertThreshMultiplier = 2.0;
[...]
for (uint16_t i = 4; i < (samples>>1); i++)
{
// i = bin; abscissa = freq vReal[i] = strength
abscissa = ((i * 1.0 * samplingFrequency) / samples);
if (vReal[i] > FirstHighestValue) {
SecondHighestValue = FirstHighestValue;
FirstHighestValue = vReal[i];
FirstHighestFreq = abscissa;
}
else if (vReal[i] > SecondHighestValue) {
SecondHighestValue = vReal[i];
SecondHighestFreq = abscissa;
}
AllValuesTotal += vReal[i]; // for computing background
AllValuesCount++;
}
[...]
AllValuesTotal = AllValuesTotal - (FirstHighestValue - SecondHighestValue);
AllValuesCount = AllValuesCount - 2; // take out the 2 outliers above
AllValuesAverage = AllValuesTotal / AllValuesCount;
Thresh = AlertThreshMultiplier * AllValuesAverage;
[...]
So I’m trying to compare the FirstHighestValue to the Thresh variable, with this comparison:
if (FirstHighestValue >= (AlertThreshMultiplier * AllValuesAverage) + 10) {
[...]
-So as you can see, I take the count and values of all elements of the vReal array, and do a simple mean average.
-Then I use an arbitrary multiplier (AlertThreshMultiplier) against that average (in this case 2.0).
-Finally, I add 10 to whatever that value is (as an offset), as the low level signals can be VERY low (.01, .001, etc.) and so multiplication products are too small to be valuable.
You see, the environment could change (get louder, quieter), and I don’t want to upload new code every time they might, or have some kind of manual calibration/pot in the thing. I am hoping I can just use a better algorithm to adjust to background noise.
The idea that 2x background level is fine, until you have very high, or very low background levels. Low signals means darn near anything will trigger it and high signals means a sound would need to be unrealistically high to breach the threshold.
Am I better off just making the threshold X above whatever threshold there is (mean average minus 2 highest signals)?
Thoughts?
TIA!