Используйте свертку, чтобы найти эталонный аудио образец в непрерывном потоке звука - PullRequest
9 голосов
/ 01 мая 2011

in мой предыдущий вопрос о нахождении эталонного аудиосэмпла в большем аудиосэмпле, было предложено использовать свертку.
Используя DSPUtil , я смогсделать это.Я немного поиграл с ним и попробовал разные комбинации аудио-сэмплов, чтобы увидеть, каков был результат.Чтобы визуализировать данные, я просто поместил необработанный звук в виде чисел в Excel и создал диаграмму с использованием этих чисел.Пик виден , но я не знаю, как это мне помогает.У меня есть следующие проблемы:

  • Я не знаю, как определить начальную позицию матча в исходном аудиосэмпле из местоположения пика.
  • Я не знаюЯ не знаю, как мне применять это с непрерывным потоком звука, чтобы я мог реагировать, как только будет получен образец эталонного звука.
  • Я не понимаю, почему рисунок 2 и рисунок 4 (см. ниже)) сильно отличаются друг от друга, хотя оба представляют собой аудиосэмпл, свернутый с самим собой ...

Любая помощь высоко ценится.

Следующие изображения являются результатом анализа с использованием Excel:

  1. Более длинный аудиосэмпл с опорным звуком (звуковой сигнал) ближе к концу: http://img801.imageshack.us/img801/976/values1.png
  2. Звуковой сигнал свертывается сам с собой: http://img96.imageshack.us/img96/6720/values2i.png
  3. Более длинный аудиосэмпл без звукового сигнала, свернутый со звуковым сигналом: http://img845.imageshack.us/img845/1091/values3.png
  4. Более длинный аудиосэмпл точки 3, свернутый с самим собой: http://img38.imageshack.us/img38/1272/values4.png

ОБНОВЛЕНИЕ и решение:
Благодаря обширной помощи Хана яв состоянии достичь своей цели.
После того, как я развернул свою медленную реализацию без БПФ, я обнаружил alglib , которая обеспечивает быструю реализацию.Есть одно основное предположение к моей проблеме: один из аудиосэмплов полностью содержится в другом.
Итак, следующий код возвращает смещение в сэмплах в большем из двух аудиосэмплов и нормализованное значение взаимной корреляции вэто смещение.1 означает полную корреляцию, 0 означает отсутствие корреляции вообще, а -1 означает полную отрицательную корреляцию:

private void CalcCrossCorrelation(IEnumerable<double> data1, 
                                  IEnumerable<double> 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:
Никаких новых ответов не требуется!Я получил награду, чтобы наградить ее Ханом за его постоянные усилия по этому вопросу!

Ответы [ 2 ]

3 голосов
/ 05 мая 2011

Здесь мы говорим о награде:)

Чтобы найти конкретный опорный сигнал в большем звуковом фрагменте, вам необходимо использовать алгоритм взаимной корреляции.Основные формулы можно найти в этой статье Википедии .

Кросс-корреляция - это процесс, с помощью которого сравниваются 2 сигнала.Это делается путем умножения обоих сигналов и суммирования результатов для всех выборок.Затем один из сигналов сдвигается (обычно на 1 выборку), и расчет повторяется.Если вы попытаетесь визуализировать это для очень простых сигналов, таких как один импульс (например, 1 сэмпл имеет определенное значение, а остальные сэмплы равны нулю), или чисто синусоидальной волны, вы увидите, что результат взаимной корреляции действительномера того, насколько оба сигнала похожи, и задержка между ними.Другая статья, которая может предоставить более глубокое понимание, может быть найдена здесь

Эта статья Пола Бурка также содержит исходный код для простой реализации во временной области.Обратите внимание, что статья написана для общего сигнала.Аудио обладает тем специальным свойством, что долгосрочное среднее значение обычно равно 0. Это означает, что средние значения, используемые в формуле Пола Буркса (mx и my), могут быть опущены.Существуют также быстрые реализации взаимной корреляции на основе FFT (см. ALGLIB ).

(Максимальное) значение корреляции зависит от значений выборки в аудиосигналах.В алгоритме Пола Бурка, однако, максимум масштабируется до 1,0.В случаях, когда один из сигналов полностью содержится в другом сигнале, максимальное значение достигнет 1. В более общем случае максимум будет ниже, и необходимо будет определить пороговое значение, чтобы решить, достаточно ли похожи сигналы.

3 голосов
/ 01 мая 2011

Вместо свертки вы должны использовать корреляцию.Размер пика корреляции показывает, насколько оба сигнала одинаковы, положение пика, их относительное положение во времени или задержка между обоими сигналами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...