Это всего лишь статистика.Возможно, вы захотите собрать, по крайней мере, 50 кадров (1 секунда) данных перед тем, как они действительно будут работать (возможно, пусть пользователь решит, удерживая и отпуская кнопку).Тогда вы, вероятно, захотите определить, где обычно находится уровень децибел.Я могу придумать 3 способа сделать это.
private void Graph_QuantumStarted(AudioGraph sender, object args)
{
...
double decibels = dataInFloats.Aggregate<float, double>(0f, (current, sample) => current + Math.Abs(sample)); // I dislike the fact that the decibels variable is initially inaccurate, but it's your codebase.
decibels = 20 * Math.Log10(decibels / dataInFloats.Length);
if (scanning) // class variable (bool), you can set it from the UI thread like this
{
_decibelList.Add(decibels); // I assume you made this a class variable
}
else if (decibels == Double.NaN)
{
// Code by case below
}
else if (decibels > _sensitivity) //_sensitivity is a class variable(double), initialized to Double.NaN
{
LoudNoise?.Invoke(this, true); // Calling events is a wee bit expensive, you probably want to handle the sensitivity before Invoking it, I'm also going to do it like that to make this demo simpler
}
}
- Если вы можете контролировать, убедитесь, что нет достаточно громкого всплеска, и вы хотите, чтобы он сработал, вы можете просто взять максимальное значение всех этих кадров и сказать, что оно превышает чувствительность
maxDecibels + Math.Abs(maxDecibels* 0.2)
(децибелы могут быть отрицательными, следовательно, Abs).
double maxDecibels = _decibelList.OrderByDescending(x => x)[0];
_sensitivity = maxDecibels + Math.Abs(maxDecibels* 0.2);
Если вы не можете контролировать время всплеска, вы можете собрать эти кадры, отсортировать их и получить их [24] (из вашего списка 100 предметов) и сказать, что это чувствительность.
sensitivity = _decibelList.OrderByDescending(x => x)[24]; // If you do a variable time you can just take Count/4 - 1 as the index
(я думаю, что это лучше, но я действительно не знаю статистики) Пройдите по списку децибел фрейма и отследите среднюю разницу в значении и индекс того, что изменило его больше всего.После этого найдите максимальное значение после этого индекса и скажите, что 75% изменений - это чувствительность.(Не используйте LinkedList для этого)
int greatestChange, changeIndex = 0;
double p = Double.NaN; // Previous
for (int i = 0; i < _decibelList.Count(); i++)
{
if (p != Double.Nan)
{
change = Math.Abs(_decibelList[i] - p);
if (Math.Abs(change > greatestChange)
{
greatestChange = change;
changeIndex = i;
}
}
p = _decibelList[i];
}
int i = changeIndex;
p = Double.NaN; // reused
double c= Double.NaN; // Current
do
{
p = c != Double.NaN ? c : _decibelList[i];
c = _decibelList[++i];
} while (c < p);
_sensitivity = ((3 * c) + _decibelList[changeIndex]) / 4;
Примечание: Вы можете (отчасти) устранить необходимость сортировки, имея LinkedList и вставляя в подходящее место