Identifizieren Sie, wo das Singen in einer reinen Sprachaufnahme beginnt

14

Ich habe eine kleine Karaoke-App, in der ein Benutzer 4 Zeilen eines Songs mit einem Abstand von einer Sekunde zwischen den Zeilen singt. Es gibt keine Hintergrundmusik, daher ist es nur Stimme, was das Problem hoffentlich leichter zu lösen macht.

Ich bin auf der Suche nach der robustesten Methode, um genau zu erkennen, wo der Benutzer in meiner Aufnahme Zeile 1 beginnt und endet, Zeile 2 beginnt und endet usw.

Ich habe einen simplen Algorithmus zusammengestellt, der funktioniert, wenn die Aufnahme nur sehr wenig Hintergrundgeräusche enthält (etwa wann passiert das?), Der jedoch bei geringstem Rauschen in Stücke fällt.

Kann mich jemand auf etwas Robusteres hinweisen?

Mike Hogan
quelle
Meine Antwort könnte Ihnen helfen - dsp.stackexchange.com/a/1543/440
Dipan Mehta
In einigen Aufnahmen ist die Stimme das einzige Instrument, das in beiden Kanälen mit der gleichen Amplitude gespielt wird. Sie können diese Informationen verwenden, um die Stimme aus einer Stereoaufnahme zu extrahieren.
Jader Dias

Antworten:

4

Wenn das Hintergrundrauschen weißlich ist, können Sie die spektrale Ebenheit messen und als Sprache betrachten, wenn die Amplitude über einem bestimmten Schwellenwert liegt und die spektrale Ebenheit unter einem bestimmten Schwellenwert liegt.

Im Grunde genommen nehmen Sie einfach eine FFT eines Teils des Signals und dividieren dann das geometrische Mittel der Größe des Spektrums durch das arithmetische Mittel.

Sie können auch ein Bandpassfilter verwenden, um nur die Frequenzbereiche hervorzuheben, in denen sich die menschliche Stimme normalerweise befindet (so einfach wie das Einstellen der unerwünschten Bereiche der FFT auf 0 vor dem Messen der spektralen Ebenheit).

Endolith
quelle
Macht es Ihrer Erfahrung nach einen großen Unterschied, wenn Sie die Größe im Quadrat gegen die Größe messen, bevor Sie die spektrale Ebenheit messen?
Spacey
@Mohammad: Ich habe keine Erfahrung damit. :) Ich habe eine vorherige Frage gestellt, weil ich die Spezifikation nicht verstanden habe und immer noch nicht sicher bin, welcher Weg richtig ist. Ich denke jedoch nicht, dass die Quadratur einen praktischen Unterschied macht. Wenn Sie nur auslösen, wenn es einen Schwellenwert überschreitet, sollte es gleich reagieren, ob quadriert oder nicht (vorausgesetzt, Sie passen den Schwellenwert an), sodass der reine Betrag rechnerisch günstiger ist.
Endolith
@ Endolith, das ist ein langer Weg: Weißt du, wie man diesen Ansatz in matlab umsetzt? Ich möchte alle hier erwähnten Ansätze in Matlab (Oktave) testen, um zu sehen, welche am besten ist.
Mike Hogan
@ MikeHogan: Nein, ich habe Matlab schon lange nicht mehr benutzt. : / Auch das würde echte Arbeit erfordern. :) Ich habe nichts vorab geschrieben. Teilen Sie das Signal in kleine Stücke auf, führen Sie die FFT jedes einzelnen durch und dividieren Sie für jede FFT das geometrische Mittel der Größe durch das arithmetische Mittel der Größe. Höhere Zahlen sind laut, niedrigere Zahlen sind tonal.
Endolith
3

Ich habe in der Vergangenheit Spektralfluss verwendet und es scheint gut zu funktionieren. Die Grundidee ist, ein Spektrogramm Ihres Signals über die Bänder zu erstellen, die Sie interessieren. Nehmen wir an , dass Ihre Frequenz auf der y-Achse ist, und die Zeit ist auf der x-Achse, wie so .

Dies bedeutet, dass Ihr Spektrogramm eine Matrix ist. Jede Spalte repräsentiert den absoluten Wert der FFT eines Schnappschusses Ihres Signals, und jede Zeile repräsentiert, wie sich die Energie eines Bandes mit der Zeit ändert.

Nehmen Sie nun einfach den Unterschied der Spalten. Nehmen Sie also eine Spalte und subtrahieren Sie die vorhergehende Spalte von sich selbst und tun Sie dies für alle Spalten. (Offensichtlich die Startspalten alleine lassen). Dann summiere über alle Bands. Das heißt, summieren Sie einfach alle Zeilen zusammen.

Am Ende erhalten Sie ein 1-D-Signal, das Ihren Signaleintritt codiert . Hier erfahren Sie, wo Ihre Stimme beginnt.

BEARBEITEN:

Wenn Sie nun das Gegenteil feststellen möchten (d. H., Wenn ein Signal keine Aktivität mehr aufweist), erhalten Sie diese Informationen durch den Spektralfluss. Wo immer Sie einen Beginn haben, werden Sie einen positiven Peak haben, und wo immer Sie einen 'Deset' haben (mangels eines besseren Wortes), werden Sie einen negativen Peak haben.

Ich würde einfach den ersten positiven Peak und den letzten negativen Peak nehmen, um die Gesamtstart- und -stoppzeiten meines Signals zu markieren.

Spacey
quelle
Mohammad, was meinst du mit "row"?
Mike Hogan
@ MikeHogan Bitte sehen Sie meine Änderungen, schrieb ich die Antwort neu.
Spacey
Wäre das nicht ein Anzeichen für irgendetwas? Trommelschläge oder andere impulsive Geräusche würden ebenfalls erkannt. Es wird nicht zwischen Tönen und lauten Geräuschen unterschieden.
Endolith
@endolith Du sprichst einen guten Punkt an - aber ich glaube, dass es immer noch funktionieren könnte. Nach meiner Überlegung befinden Sie sich in diesem Szenario entweder im Sprach- und Musikstatus oder nur im Musikstatus. Wenn Sie also den Spektralfluss berechnen, berechnen Sie wirklich nur das Delta zwischen Stimme + Musik und nur Musik. (Natürlich müsste ich es viel genauer analysieren, aber so denke ich jetzt) ​​:-P
Spacey
1
@endolith Ich habe gerade noch einmal gelesen und das OP sagt, dass es nur Stimme gibt (anscheinend ist es eine einfache App), also wäre es in diesem Fall nur Stimme gegen nichts.
Spacey
2

Aus meiner Erfahrung heraus würde ich versuchen, Mel-Frequenz-Cepstrum-Koeffizienten (MFCCs) zu untersuchen . MFCCs sind relativ einfach zu implementieren, wenn eine FFT verfügbar ist und sie werden häufig bei der Sprachverarbeitung verwendet.

Mit MFCCs sollten Sie in der Lage sein, tatsächliche Sprachdaten von Rauschen zu unterscheiden.

Endolith
quelle
@endolith, dieser Link ist mir ein Rätsel! Kennen Sie eine Open Source-Implementierung, die ich mir ansehen kann, oder ein detaillierteres Rezept, wie sie funktioniert?
Mike Hogan
2

" Spektraler Fluss " (auch als "Spektraldifferenz" bezeichnet) ist ein verbreitetes Verfahren zur "Onset-Detektion". Grundsätzlich nehmen Sie sequentielle FFTs des Signals und summieren die Größen der Differenzen der FFT-Buckets von einem Sample zum nächsten. "Beginn" wird im Allgemeinen durch einen erheblichen "Sprung" in diesem Wert dargestellt.

Google "Onset Detection" für andere Ideen.

Daniel R Hicks
quelle
2

Die alleinige Verwendung des Spektralflusses kann bei bestimmten Geräuschen zu Fehlalarmen führen und eine singende Stimme erkennen.

Das Singen impliziert normalerweise einen Signalinhalt, der eine Tonhöhe enthält, sodass Sie einen Tonhöhenerkenner oder -schätzer (Cepstrum usw.) verwenden können. Sie können den Anteil der Energie, der als gestimmt erkannt wird, im Verhältnis zur Gesamtsignalenergie überprüfen und feststellen, dass die geschätzte Tonhöhe innerhalb des Bereichs der menschlichen Stimme liegt. Dies würde die Falsch-Positiv-Rate sowohl für ungehörte Geräusche als auch für Musiktöne außerhalb des normalen Stimmbereichs verringern.

hotpaw2
quelle