Question

ma précédente question sur une conclusion échantillon de référence audio dans un échantillon plus grand audio, il a été proposé, que je devrais utiliser convolution.
J'ai pu le faire en utilisant DSPUtil ,. J'ai joué un peu avec elle et a essayé différentes combinaisons d'échantillons audio, pour voir ce que le résultat a été. Pour visualiser les données, je viens de l'audio brut jetai sous forme de nombres à Excel et créé un graphique à l'aide des chiffres. Un pic est visible, mais je ne sais pas vraiment comment cela me aide. Je ces problèmes:

  • Je ne sais pas, comment déduire la position de départ du match dans l'échantillon audio d'origine de l'emplacement du pic.
  • Je ne sais pas comment j'appliquer cela avec un flux continu d'audio, afin que je puisse réagir, dès que l'échantillon audio de référence se produit.
  • Je ne comprends pas, pourquoi l'image 2 et de l'image 4 (voir ci-dessous) diffèrent tellement, bien que, représentent tous deux un échantillon audio convoluée avec lui-même ...

Toute aide est très appréciée.

Les images suivantes sont le résultat de l'analyse en utilisant Excel:

  1. Un échantillon audio plus avec le signal audio de référence (un bip) près de l'extrémité:
  2. Le bip convoluée avec lui-même:
  3. Un échantillon audio plus sans bip bip convoluée avec le:
  4. L'échantillon audio plus du point 3 convoluée avec lui-même:

Mise à jour et de la solution: Merci à l'aide étendue de Han, j'ai pu atteindre mon objectif.
Après avoir roulé ma propre mise en œuvre lente sans FFT, j'ai trouvé alglib qui fournit une mise en œuvre rapide. Il y a une hypothèse de base à mon problème. L'un des échantillons audio est contenu complètement dans l'autre
Ainsi, les rendements de code suivant le décalage des échantillons dans le plus grand des deux échantillons audio et la valeur de corrélation croisée normalisée à ce décalage. 1 moyens de corrélation complète, 0 signifie aucune corrélation et -1 moyens de corrélation complète négatif:

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: Pas de nouvelles réponses nécessaires! J'ai commencé à la générosité de l'attribuer à Han pour son effort continu avec cette question!

Était-ce utile?

La solution

Ici, nous allons pour la générosité:)

Pour un signal de référence particulier dans un fragment audio plus volumineux, vous devez utiliser un algorithme de corrélation croisée. Les formules de base se trouvent dans cette Wikipedia article .

Cross-corrélation est un processus par lequel 2 signaux sont comparés. Cela se fait en multipliant les signaux et en additionnant les résultats pour tous les échantillons. Ensuite, l'un des signaux est décalée (généralement par 1 échantillon), et le calcul est répété. Si vous essayez de visualiser ce pour des signaux très simples comme une seule impulsion (par exemple 1 échantillon a une certaine valeur alors que les échantillons restants sont nuls), ou une onde pure sinusoïdale, vous verrez que le résultat de la corrélation croisée est en effet une mesure pour combien les deux signaux sont identiques et le délai entre eux. Un autre article qui soit plus représentatif se trouve .

article de Paul Bourke contient également le code source pour une mise en œuvre dans le domaine temporel simple. Notez que l'article est écrit pour un signal général. Audio a la propriété spéciale que la moyenne à long terme est usualy 0. Cela signifie que les moyennes utilisées dans la formule Paul Bourke (mx et ma) peuvent être laissés. Il y a aussi des mises en œuvre rapides de la corrélation croisée en fonction de la FFT (voir ALGLIB ).

Le (maximum) la valeur de la corrélation dépend des valeurs d'échantillons dans les signaux audio. Dans l'algorithme de Paul Bourke mais le maximum est mis à l'échelle à 1,0. Dans les cas où l'un des signaux est entièrement contenu dans un autre signal, la valeur maximale atteindra 1. Dans le cas le plus général, le maximum est inférieur et une valeur de seuil devra être déterminé à décider si les signaux sont suffisamment semblables.

Autres conseils

Au lieu d'une convolution vous devez utiliser une corrélation. La taille du pic de corrélation vous indique à quel point les deux signaux sont semblables, la position du pic de leur position relative dans le temps, ou le retard entre les deux signaux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top