Einfachste Methode zum Erkennen, wo Audio-Hüllkurven beginnen und enden

43

Unten ist ein Signal, das eine Aufzeichnung von jemandem darstellt, der spricht. Darauf aufbauend möchte ich eine Reihe kleinerer Audiosignale erstellen. Die Idee ist, zu erkennen, wann "wichtiger" Sound beginnt und endet, und diese für Marker zu verwenden, um ein neues Audio-Snippet zu erstellen. Mit anderen Worten, ich möchte die Stille als Indikator dafür verwenden, wann ein Audiobaustein gestartet oder gestoppt wurde, und neue Audiopuffer auf dieser Basis erstellen.

So zum Beispiel, wenn eine Person sich selbst sagt

Hi [some silence] My name is Bob [some silence] How are you?

dann möchte ich drei audio clips daraus machen. Einer, der sagt Hi, einer, der sagt My name is Bobund einer, der sagt How are you?.

Meine ursprüngliche Idee ist es, den Audiopuffer ständig zu durchlaufen und zu überprüfen, wo Bereiche mit geringer Amplitude vorhanden sind. Vielleicht könnte ich dies tun, indem ich die ersten zehn Proben nehme, die Werte mittle und wenn das Ergebnis niedrig ist, es als still bezeichne. Ich würde den Puffer durchsehen, indem ich die nächsten zehn Proben überprüfe. Auf diese Weise konnte ich feststellen, wo Umschläge beginnen und enden.

Wenn jemand Ratschläge zu einem guten, aber einfachen Weg hat, wäre das großartig. Für meine Zwecke der Lösung kann recht rudimentär sein.

Ich bin kein Profi bei DSP, verstehe aber einige grundlegende Konzepte. Außerdem würde ich dies programmatisch tun, um über Algorithmen und digitale Samples zu sprechen.

Danke für all die Hilfe!

Bildbeschreibung hier eingeben


EDIT 1

Bisher großartige Antworten! Ich wollte nur klarstellen, dass dies nicht für Live-Audio gedacht ist, und ich werde die Algorithmen selbst in C oder Objective-C schreiben, sodass Lösungen, die Bibliotheken verwenden, eigentlich keine Option sind.

Eric Brotto
quelle
1
Es hört sich so an, als würden Sie versuchen, es mit Stilleperioden als Haltepunkte aufzubrechen. Warum nicht einfach die Leistungsschwelle verwenden, um "Stille" zu bestimmen und eine Schwellenzeit zu haben, um zu bestimmen, ob sie lang genug ist, um eine Pause zu begründen?
Jim Clay
@JimClay Ja, genau das versuche ich zu tun. Ich habe noch nie von Stromschwellen gehört, aber es klingt nach etwas, das ich gebrauchen könnte. Ist es kompliziert Könnten Sie das etwas näher erläutern?
Eric Brotto
@EricBrotto Vielleicht sollten Sie uns etwas darüber erzählen, welche Fähigkeiten Sie in Ihren Bibliotheken haben. Dadurch können wir die eigentliche Methodik besser für Sie massieren.
Spacey
Dieser Ansatz für die Stilleerkennung ist besser - was sollte der andere Haltepegel als 0,05 x = Wavread ('s1.wav') sein? i = 1; während abs (x (i)) <0,05% Schweigerfassung i = i + 1; Ende x (1: i) = []; x (6000: 10000) = 0;
Zeee

Antworten:

26

Dies ist das klassische Problem der Spracherkennung . Das erste, was zu tun wäre, wäre das Konzept von Google. Es ist weit verbreitet in der digitalen Kommunikation und es wurden viele Untersuchungen zu diesem Thema durchgeführt und es gibt gute Veröffentlichungen.

Je mehr Hintergrundgeräusche Sie verarbeiten müssen, desto ausgefeilter muss im Allgemeinen die Methode zur Spracherkennung sein. Wenn Sie Aufnahmen verwenden, die in einem ruhigen Raum aufgenommen wurden, können Sie dies sehr einfach tun (mehr dazu später). Wenn Sie alle möglichen Geräusche haben, während jemand spricht (vorbeifahrende Lastwagen, bellende Hunde, zerschmetternde Teller, angreifende Außerirdische), müssen Sie etwas viel Clevereres verwenden.

Wenn Sie sich die angehängte Wellenform ansehen, ist Ihr Rauschen minimal. Daher schlage ich Folgendes vor:

  1. Signalhüllkurve extrahieren
  2. Wählen Sie eine gute Schwelle
  3. Stellen ermitteln, an denen die Hüllkurvengröße den Schwellenwert überschreitet

Was bedeutet das alles? Eine Hüllkurve eines Signals ist eine Kurve, die seine Größe über die Zeit beschreibt, unabhängig davon, wie sein Frequenzgehalt es zum Schwingen bringt (siehe Abbildung unten).

Bildbeschreibung hier eingeben

Die Hüllkurvenextraktion kann durchgeführt werden, indem ein neues Signal erstellt wird, das Absolutwerte Ihres ursprünglichen Signals enthält, z. B. wird und dann Tiefpassfilterung des Ergebnisses. Das einfachste Tiefpassfilter kann implementiert werden, indem jeder Abtastwert durch einen Durchschnitt seiner N Nachbarn auf beiden Seiten ersetzt wird. Der beste Wert für N kann experimentell ermittelt werden und von mehreren Faktoren abhängen, z. B. von Ihrer Abtastrate.{1,45,6,2,43,2}{1,45,6,2,43,2}

Sie können auf dem Bild sehen, dass Sie nicht viel Rauschen haben, dass Ihre Signalhüllkurve immer über einem bestimmten Schwellenwert (Lautstärkepegel) liegt, und Sie können diese Regionen als Regionen mit Spracherkennung betrachten .

Phonon
quelle
3
Ich hatte dies tatsächlich als eines der Plug-Ins in Good'ol Winamp implementiert. Was Sie beschreiben, ist gut, aber nicht ausreichend. Normalerweise gibt es stimmhafte Töne (Vokale) und stimmlose Töne (Konsonanten). Wenn es nur stimmhafte Geräusche gäbe, würde das, was Sie beschreiben, funktionieren - stimmlose Geräusche sind jedoch sehr energiearm und nicht ganz von allgemeinen Geräuschen zu unterscheiden. Und auch in Studios sind lautlose Bedingungen sehr selten.
Dipan Mehta
Wie erreicht man das in Python?
kRazzy R
26

Was Sie wirklich wollen , im Wesentlichen wie genannt zu tun Voice Activity Detection oder Spracherkennung.

Grundsätzlich besteht jedes reine Sprachsignal (das keine Musik enthält) aus drei Teilen.

  1. Der stimmhafte Klang - der im Wesentlichen durch Vokale verursacht wird
  2. Der stimmlose Klang - der Konsonanten enthält.

Das Merkmal des menschlichen Klangs ist, dass während viel Energie im stimmhaften Klang verbraucht wird, die wirkliche Information in Konsonanten enthalten ist. Außerdem ist stimmhafter Ton normalerweise eine niedrigere Frequenz, während stimmlose Töne höhere Frequenzen sind. [Um genau zu sein, werden alle stimmhaften Töne für eine bestimmte Person, die ihre Tonhöhe ist, mehr oder weniger mit einer konstanten Frequenz in Resonanz gebracht].

Nun, wie bei jedem System gibt es Rauschen. Der stimmhafte Klang ist in der Regel so stark, dass man ihn gut erkennen kann. Wenn Sie eine Filterung mit niedrigeren Frequenzen anwenden, ist es möglich, eine gute Anzahl stimmhafter Klänge zu erfassen. Der stimmlose Klang (mit all den umfangreichen Informationen) geht jedoch verloren.

Kommen wir zu der Frage, wie man es löst:

Der Trick liegt in der Tatsache, dass stimmloser Klang immer noch von einer Resonanzquelle kommt; und von Natur aus über eine bestimmte Frequenz beschränkt. Wobei das Geräusch eher gleichmäßig ist. Eine einfache Maßnahme, die alle drei voneinander unterscheidet, ist "lokale Potenz" oder alternativ, aber äquivalent, die fenstergesteuerte Autokorrelation.

Wenn Sie zu einem Zeitpunkt 100 Abtastungen nehmen und sich selbst automatisch korrelieren, sind die Ergebnisse, wenn sie nur Rauschen enthalten, so gut wie null (dies ist die Eigenschaft von weißem Rauschen), während für Sprachsignale diese Größe aufgrund des Signals beobachtbar ist hat noch bessere struktur. Das hat in der Vergangenheit für mich funktioniert.

VAD war ein aktives Forschungsgebiet, da fast die gesamte Mobilfunkkommunikation Nichtsprachanteile erkennen und aus der Codierung entfernen möchte. Wenn sie jedoch stimmlose Sprache entfernen würden, würde dies die Telefonie unbrauchbar machen.

Der G.729-Standard berechnet die VAD auf der Grundlage von Merkmalen wie: Linienspektralfrequenzen, Vollbandenergie, Niedrigbandenergie (<1 kHz) und Nulldurchgangsrate.

Der GSM-Standard funktioniert wie folgt: Option 1 berechnet das SNR in neun Bändern und wendet einen Schwellenwert auf diese Werte an. Option 2 berechnet verschiedene Parameter: Kanalleistung, Sprachmetrik und Rauschleistung. Anschließend werden die Sprachmetriken mit einem Schwellenwert begrenzt, der sich nach dem geschätzten SNR richtet. (aus Wikipedia)

Für fortgeschrittenere Techniken liste ich einige Referenzen zu diesem Thema auf.

  1. Meistgesuchte Referenz: Jongseo Sohn; Nam Soo Kim; Wonyong Sung; "Eine statistische modellbasierte Sprachaktivitätserkennung" Signal Processing Letters, IEEE, Januar 1999, Band: 6 Ausgabe: 1 Seiten: 1-3

  2. Am relevantesten für Sie: Mark Marzinzik und Birger Kollmeier "Sprachpausenerkennung für die Schätzung des Rauschspektrums durch Nachverfolgung der Dynamik von Leistungshüllkurven" IEEE-TRANSAKTIONEN AUF SPRACHE UND AUDIO-VERARBEITUNG 10, NEIN. 2, FEBRUAR 2002, S. 109

  3. Ramírez, J .; JM Górriz, JC Segura (2007). "Sprachaktivitätserkennung. Grundlagen und Robustheit des Spracherkennungssystems". In M. Grimm und K. Kroschel. Robuste Spracherkennung und Sprachverständnis. S. 1–22. ISBN 978-3-902613-08-0.

  4. Einführung: Jonathan Kola, Carol Espy-Wilson und Tarun Pruthi "Voice Activity Detection"

Dipan Mehta
quelle
Wie erreicht man das in Python?
kRazzy R
9

Ich würde Jim Clay bei seiner Herangehensweise völlig folgen, aber das Aroma mit dem Umschlag leicht variieren:

Wir wissen, dass Sprache hauptsächlich bei 1-2 kHz auftritt. Ihre Datenabtastung beträgt wahrscheinlich 44 kHz (dies hängt von Ihrem Aufnahmegerät ab). Was ich also zuerst tun würde, ist ein gleitender Durchschnitt des quadrierten Signals in Echtzeit über 10 Punkte, um eine Hüllkurve der Signalleistung zu erhalten. Dies führt zu einer Verzögerung bei der Erkennung, sodass Sie diese niedrig halten möchten.

Dann würde ich Ihrem System eine Kalibrierungsphase hinzufügen: Bitten Sie den Benutzer, still zu bleiben, eine Taste zu drücken und das Hintergrundgeräusch etwa 10 Sekunden lang aufzuzeichnen. Nehmen Sie die mittlere oder mittlere Amplitude der Hüllkurve, multiplizieren Sie sie mit 2, um die Sicherheit zu gewährleisten. Dadurch erhalten Sie automatisch die Schwelle, über die Jim gesprochen hat.

Wenn es sich nicht um eine Echtzeitaufnahme handelt, kann es nützlich sein, den gleitenden 0-Phasen-Durchschnitt zu verwenden, um die durch die Verzögerung verursachte Störung zu verringern. Sagen Sie uns, ob es bei Ihnen so funktioniert, wie es ist.

Jean-Yves
quelle
9

Eric,

Wenn Sie wirklich etwas schnelles und schmutziges suchen, müssen Sie als Erstes den Umschlag besorgen, und ich würde dies einfach (in MATLAB) tun, indem Sie:

 envelope = abs(hilbert(yourSignal));

An diesem Punkt würde ich einfach einen Schwellenwert festlegen und "Stimme existiert", wenn Sie über einem bestimmten Schwellenwert liegen.

Dies ist übrigens eine sehr einfache Lösung, die jedoch möglicherweise für Sie funktioniert.

Spacey
quelle
1
+1. Vielleicht könnten Sie die Methode hinter dieser Codezeile näher erläutern? Ich bin mir sicher, dass das OP nicht mit der Hüllkurvenextraktion über die Hilbert-Transformation vertraut ist.
Phonon
@ Mohammad Danke! Aber bitte sehen Sie meine EDIT 1. Ich möchte auf jeden Fall schnell und schmutzig, sondern müssen auch die Algorithmen selbst tun :)
Eric Brotto
@EricBrotto Ah ok, ich kann Ihnen sagen, wie Sie einen Hilbert-Transformator implementieren, aber ich gehe davon aus, dass Sie die Möglichkeit haben, eine FFT in Ihren C / Obj-C-Bibliotheken durchzuführen. Wenn nicht, wird das ein Problem sein ... :-)
Spacey
Wie erreicht man das in Python?
kRazzy R
Sehr geehrte Damen und Herren, können Sie mich auf die Frage hinweisen, wie dieser Hilbert in Python implementiert werden kann?
kRazzy R
6

Ich gehe davon aus, dass es sich um echte, nicht komplexe Signale handelt. Wenn dies nicht der Fall ist, lassen Sie es mich wissen und ich kann die Antwort ändern.

Die Leistung ist definiert als das Quadrat des Signals (dh die mit sich selbst multiplizierten Signalabtastwerte). Sie können die Leistung mit einer bestimmten Schwelle vergleichen, um festzustellen, ob Sprache vorhanden ist oder nicht. Sie müssten wahrscheinlich einige Messungen an Ihren Aufzeichnungen vornehmen, um empirisch eine gute Schwelle zu finden.

Wenn Ihre Aufnahmen "sauber" sind (dh nicht viel Rauschen), würde ich wahrscheinlich so einfach wie möglich vorgehen, indem ich die momentane Leistung (dh eine einzelne Probe) mit der Schwelle vergleiche. Dies bedeutet, dass Sie es nicht einmal quadrieren müssen, wenn Sie es nicht möchten, sondern nur den absoluten Wert benötigen und ihn mit der Quadratwurzel der Leistungsschwelle vergleichen, die vorberechnet werden kann. Wenn Sie feststellen, dass es sich um eine Sprachaufnahme handelt, sollten Sie sicherstellen, dass Sie die gesamte Sprache hören (vielleicht eine Zehntelsekunde?). Fahren Sie so lange fort, bis Sie feststellen, dass über einen längeren Zeitraum keine Proben mehr den Schwellenwert überschreiten. Auch hier müsste die Länge der Periode empirisch ermittelt werden.

Spülen und wiederholen.

Jim Clay
quelle
4

Ich habe eine Aktivitätserkennungsklasse in Java geschrieben. Es ist Teil meiner Open-Source- Java-DSP-Sammlung . Mit dem Testprogramm WavSplitter.java können Sie es mit einer WAV-Datei als Eingabe auschecken.

Christian d'Heureuse
quelle
Denken Sie daran, dass das OP ausdrücklich sagt, dass er die Algorithmen selbst in C schreiben muss.
Sam Maloney
Es ist sehr einfach, solche Algorithmen von Java nach C zu konvertieren.
Christian d'Heureuse
Sir, wie erreicht man das in Python?
kRazzy R