в моем предыдущем вопросе о поиске эталонного аудиосэмпла в более крупном аудиосэмпле было предложено использовать свертку.
Используя DSPUtil , я смог это сделать. Я немного поигрался с ним и попробовал различные комбинации аудиосэмплов, чтобы посмотреть, каков результат. Чтобы визуализировать данные, я просто выгружал необработанный звук в виде чисел в Excel и создал диаграмму, используя эти числа. Пик виден , но я действительно не знаю, как это мне помогает. У меня есть следующие проблемы:
ОБНОВЛЕНИЕ и решение:
Благодаря обширной помощи Хана я смог достичь своей цели.
После того, как я свернул свою собственную медленную реализацию без БПФ, я нашел alglib , который обеспечивает быструю реализацию.
У моей проблемы есть одно основное предположение: один из аудиосэмплов полностью содержится в другом.
Итак, следующий код возвращает смещение в сэмплах в большем из двух аудиоэмплов и нормализованное значение взаимной корреляции с этим смещением. 1 означает полную корреляцию, 0 означает отсутствие корреляции и -1 означает полную отрицательную корреляцию:
private void CalcCrossCorrelation(IEnumerable data1,
IEnumerable data2,
out int offset,
out double maximumNormalizedCrossCorrelation)
{
var data1Array = data1.ToArray();
var data2Array = data2.ToArray();
double[] result;
alglib.corrr1d(data1Array, data1Array.Length,
data2Array, data2Array.Length, out result);
var max = double.MinValue;
var index = 0;
var i = 0;
// Find the maximum cross correlation value and its index
foreach (var d in result)
{
if (d > max)
{
index = i;
max = d;
}
++i;
}
// if the index is bigger than the length of the first array, it has to be
// interpreted as a negative index
if (index >= data1Array.Length)
{
index *= -1;
}
var matchingData1 = data1;
var matchingData2 = data2;
var biggerSequenceCount = Math.Max(data1Array.Length, data2Array.Length);
var smallerSequenceCount = Math.Min(data1Array.Length, data2Array.Length);
offset = index;
if (index > 0)
matchingData1 = data1.Skip(offset).Take(smallerSequenceCount).ToList();
else if (index < 0)
{
offset = biggerSequenceCount + smallerSequenceCount + index;
matchingData2 = data2.Skip(offset).Take(smallerSequenceCount).ToList();
matchingData1 = data1.Take(smallerSequenceCount).ToList();
}
var mx = matchingData1.Average();
var my = matchingData2.Average();
var denom1 = Math.Sqrt(matchingData1.Sum(x => (x - mx) * (x - mx)));
var denom2 = Math.Sqrt(matchingData2.Sum(y => (y - my) * (y - my)));
maximumNormalizedCrossCorrelation = max / (denom1 * denom2);
}
BOUNTY:
Никаких новых ответов не требуется! Я назначил награду, чтобы вручить награду Хану за его постоянные усилия с этим вопросом!