Eine andere Möglichkeit, ein Signal in ein Spektrum zu zerlegen

Hallo allerseits, hier möchte ich über den Audiosignal-Analysealgorithmus sprechen, mit dem Sie das Signal in einzelne Wellen zerlegen können. Natürlich gibt es keine 100% ige Genauigkeit, aber das Ergebnis ist meiner Meinung nach ziemlich gut.

Bild

Die Arbeit an jeder Musik ist am besten zu sehen:


Und Links zu anderen Beispielen verschiedener Genres. Metaldeth-Tornado der Seelen:


Außer Kontakt:


Für die Zerlegung müssen Sie also die folgenden Schritte ausführen:

- Vom ursprünglichen Signal benötigen Sie 8 Zwischensignale;
- Aus diesen Zwischensignalen und dem ursprünglichen Signal müssen 8 Signale erhalten werden - Schichten, die in separate Wellen zerlegt werden können;
- Um zu berechnen, wie viele Wellen in jeder Schicht und wie groß ihre Amplitude ist.

Nun mehr zu jeder Stufe: Um ein Zwischensignal zu erhalten, müssen Sie die Ableitung des ursprünglichen Signals nehmen. Im Wesentlichen ist dies eine Ableitung einer diskreten Funktion. Um es für jeden Moment des ursprünglichen Signals zu finden, müssen Sie 1 Parameter einstellen: den Zeitraum, für den sich diese Ableitung befindet. Der Ableitungswert ist der Steigungskoeffizient in einem gegebenen Intervall, der beispielsweise durch die Methode der kleinsten Quadrate ermittelt werden kann.

Es müssen 8 Zwischensignale mit 8 verschiedenen Perioden berechnet werden. Der einfachste Satz von Perioden: 4, 8, 16, 32, 64, 128, 256, 512. Wenn eine Periode angegeben wird, wird für jede Signalabtastung die Ableitung unter Verwendung der Formel der kleinsten Quadrate berechnet. Es ist wie ein gleitender Durchschnitt, aber hier ist es kein gleitender Durchschnitt, sondern eine gleitende Ableitung des aktuellen Intervalls.

Somit werden 8 abgeleitete Signale und 1 Quelle erhalten. Jetzt muss jedes der 8 abgeleiteten Signale integriert werden. In diesem Fall bedeutet dies, dass jede nachfolgende Stichprobe gleich der Summe aller vorherigen Stichproben ist. Danach werden 8 Zwischenschichten erhalten.

Der nächste Schritt besteht darin, Schichten zu erhalten, die in separate Wellen zerlegt werden können. Jetzt müssen Sie also 8 Schichten erhalten. Ebenen werden wie folgt berechnet:

Schicht 0 = Zwischen-0-Out-Signal
Schicht1 = Zwischenstufe1 - Zwischenstufe0
Schicht2 = Zwischenstufe2-Zwischenstufe1
Schicht3 = Zwischenstufe3 - Zwischenstufe2
Schicht4 = Zwischenstufe 4-Zwischenstufe3
Schicht5 = Zwischenstufe5-Zwischenstufe4
Schicht6 = Zwischenstufe6-Zwischenstufe5
Schicht7 = Zwischenstufe 7-Zwischenstufe6
Schicht8 = Zwischenstufe7

Die letzte Schicht ist kein Unterschied, sondern einfach gleich dem letzten Zwischensignal.

Sie können anders versuchen, nämlich nachfolgende Zwischensignale aus vorherigen Zwischensignalen zu berechnen. Im aktuellen Programm wird jedoch 1 Option verwendet.

Um Ebenen in separate Wellen zu analysieren, müssen Sie nur noch die Bereiche berechnen, in denen die Werte zunehmen und in denen sie abnehmen. Tatsächlich ist die Dauer der Abschnitte ihre Wellenlänge. Abschnitte des Signals, in denen die Signalwerte konstant sind, müssen Sie nur überspringen. Um die Amplitude des Signals im Spektrum in einem bestimmten Intervall zu ermitteln, müssen Sie alle Wellenamplituden multipliziert mit ihrer Länge addieren.

Bild

Der Code, der das Zwischensignal berechnet, sieht folgendermaßen aus:

Hier ist die Wellengröße die Anzahl der Samples
signal [] - Array mit dem ursprünglichen Signal
SY = 0, SX = 0, SXX = 0, SXY = 0, Ky = 0 - Variablen vom Typ float
Schritt 2 = SCHRITT / 2, wobei SCHRITT die Periode ist (4,8,16,32,64,128,256,512)

for(int i=Step2;i<wavesize-Step2;i++){ SY=0,SX=0,SXX=0,SXY=0,Ky=0; for(int j=i-Step2,fromZ=0;j<i+Step2;j++,fromZ++){ SX+=fromZ; SY+=signal[j]; SXX+=fromZ*fromZ; SXY+=fromZ*signal[j]; } Ky=float((STEP)*SXY-SX*SY)/float((STEP)*SXX-SX*SX); OutSignal[i]=OutSignal[i-1]+Ky; } 

Um ein Signal von einem anderen zu subtrahieren, subtrahieren Sie einfach jedes Sample von jedem.
Zum Beispiel für 0 Ebene:

 for(int i=0;i<wavesize-1;i++) layer0[i]=OutSignal0[i]-Signal[i]; 

Wenn Sie alle Ebenen addieren und die letzte mit dem entgegengesetzten Vorzeichen nehmen, erhalten Sie das ursprüngliche Signal. Wenn Sie also eine beliebige Ebene multiplizieren, können Sie einen Frequenzfilter erstellen. Die nächste Frage ist, wie die Amplituden bestimmter Harmonischer berechnet werden. Tatsache ist, dass in einem konstanten Intervall, zum Beispiel = 4000 Abtastwerte, viele kurze und relativ wenige lange Wellen auftreten können.

Sie können natürlich die durchschnittlichen Amplituden für jede Schicht finden und hinzufügen. Diese Methode ist jedoch nicht sehr gut, da es nur sehr wenige lange Wellen gibt und ihre Amplitude normalerweise sehr groß ist und eine starke Ungleichmäßigkeit der Amplitude gegenüber niedrigen Frequenzen erhalten wird.

In einem Programm, das Farbmusik über Links anzeigt, wird die Amplitude jeder Harmonischen berechnet als: die Amplitude der Welle * ihre Länge. Trotzdem treten Ungleichmäßigkeiten auf, die jedoch nicht so stark sind wie bei der Mittelwertbildung.

Im Allgemeinen glaube ich nicht, dass eine Person Schall als Zerlegung in ein Spektrum wahrnimmt, sondern dass Schall aus Klangbildern besteht, die aus Wellen unterschiedlicher Länge bestehen. Dementsprechend ist die Lautstärke eines Tons eher die durchschnittliche Lautstärke aller Wellen, aus denen der Ton besteht. Es ist jedoch noch nicht klar, aus welchen Parametern das Klangbild besteht, möglicherweise die Durchschnittsfrequenz, die Standardabweichung oder etwas anderes.

Source: https://habr.com/ru/post/de410357/


All Articles