Frage

Ich habe die Aufgabe, eine .NET-Client-App zu erstellen, um Stille in WAV-Dateien zu erkennen.

Ist dies mit den integrierten Windows-APIs möglich?Oder gibt es alternativ gute Bibliotheken, die dabei helfen?

War es hilfreich?

Lösung

Die Audioanalyse ist eine schwierige Sache, die viel komplexe Mathematik erfordert (denken Sie an Fourier-Transformationen).Die Frage, die Sie stellen müssen, lautet: „Was ist Stille?“Wenn der Ton, den Sie bearbeiten möchten, von einer analogen Quelle aufgenommen wurde, ist die Wahrscheinlichkeit groß, dass keine Stille herrscht ...Dabei handelt es sich lediglich um Bereiche mit leisem Rauschen (Leitungsbrummen, Hintergrundgeräusche usw.).

Alles in allem würde ein Algorithmus, der funktionieren sollte, darin bestehen, einen minimalen Lautstärke- (Amplituden-)Schwellenwert und eine Mindestdauer zu bestimmen (z. B. <10 dBA für mehr als 2 Sekunden) und dann einfach eine Lautstärkeanalyse der Wellenform durchzuführen und nach Bereichen zu suchen, die diese Kriterien erfüllen (mit vielleicht einigen Filtern für Millisekundenspitzen).Ich habe das noch nie in C# geschrieben, aber das hier CodeProject-Artikel sieht interessant aus;Es beschreibt C#-Code zum Zeichnen einer Wellenform ...Das ist die gleiche Art von Code, der für andere Amplitudenanalysen verwendet werden könnte.

Andere Tipps

http://www.codeproject.com/Articles/19590/WAVE-File-Processor-in-C

Es enthält den gesamten Code, der zum Entfernen von Stille und zum Mischen von Wave-Dateien erforderlich ist.

Genießen.

Wenn Sie die durchschnittliche Leistung eines Schiebefensters effizient berechnen möchten:Quadrieren Sie jede Stichprobe und addieren Sie sie dann zu einer laufenden Summe.Subtrahieren Sie den quadrierten Wert von N vorherigen Stichproben.Fahren Sie dann mit dem nächsten Schritt fort.Dies ist die einfachste Form von a CIC Filter. Satz von Parseval sagt uns, dass diese Leistungsberechnung sowohl auf den Zeit- als auch auf den Frequenzbereich anwendbar ist.

Vielleicht möchten Sie auch etwas hinzufügen Hysterese an das System, um ein schnelles Ein- und Ausschalten zu vermeiden, wenn der Leistungspegel um den Schwellenwert herum schwankt.

Ich benutze NAudio, und ich wollte die Stille in Audiodateien erkennen, damit ich sie entweder melden oder abschneiden kann.

Nach vielen Recherchen bin ich auf diese grundlegende Implementierung gekommen.Also habe ich eine Erweiterungsmethode für geschrieben AudioFileReader Klasse, die die Stilledauer am Anfang/Ende der Datei oder ab einer bestimmten Position zurückgibt.

Hier:

static class AudioFileReaderExt
{
    public enum SilenceLocation { Start, End }

    private static bool IsSilence(float amplitude, sbyte threshold)
    {
        double dB = 20 * Math.Log10(Math.Abs(amplitude));
        return dB < threshold;
    }
    public static TimeSpan GetSilenceDuration(this AudioFileReader reader,
                                              SilenceLocation location,
                                              sbyte silenceThreshold = -40)
    {
        int counter = 0;
        bool volumeFound = false;
        bool eof = false;
        long oldPosition = reader.Position;

        var buffer = new float[reader.WaveFormat.SampleRate * 4];
        while (!volumeFound && !eof)
        {
            int samplesRead = reader.Read(buffer, 0, buffer.Length);
            if (samplesRead == 0)
                eof = true;

            for (int n = 0; n < samplesRead; n++)
            {
                if (IsSilence(buffer[n], silenceThreshold))
                {
                    counter++;
                }
                else
                {
                    if (location == SilenceLocation.Start)
                    {
                        volumeFound = true;
                        break;
                    }
                    else if (location == SilenceLocation.End)
                    {
                        counter = 0;
                    }
                }
            }
        }

        // reset position
        reader.Position = oldPosition;

        double silenceSamples = (double)counter / reader.WaveFormat.Channels;
        double silenceDuration = (silenceSamples / reader.WaveFormat.SampleRate) * 1000;
        return TimeSpan.FromMilliseconds(silenceDuration);
    }
}

Dies akzeptiert fast jedes Audiodateiformat nicht nur WAV.

Verwendung:

using (AudioFileReader reader = new AudioFileReader(filePath))
{
    TimeSpan duration = reader.GetSilenceDuration(AudioFileReaderExt.SilenceLocation.Start);
    Console.WriteLine(duration.TotalMilliseconds);
}

Verweise:

Ich glaube nicht, dass Sie integrierte APIs zur Erkennung von Stille finden werden.Aber Sie können immer die gute alte Mathematik/diskrete Signalverarbeitung nutzen, um die Lautstärke herauszufinden.Hier ein kleines Beispiel: http://msdn.microsoft.com/en-us/magazine/cc163341.aspx

Verwenden Sox.Es kann führende und nachgestellte Pausen entfernen, aber Sie müssen es als Exe aus Ihrer App aufrufen.

Siehe Code unten von Erkennen von Audiostille in WAV-Dateien mit C#

private static void SkipSilent(string fileName, short silentLevel)
{
    WaveReader wr = new WaveReader(File.OpenRead(fileName));
    IntPtr format = wr.ReadFormat();
    WaveWriter ww = new WaveWriter(File.Create(fileName + ".wav"), 
        AudioCompressionManager.FormatBytes(format));
    int i = 0;
    while (true)
    {
        byte[] data = wr.ReadData(i, 1);
        if (data.Length == 0)
        {
            break;
        }
        if (!AudioCompressionManager.CheckSilent(format, data, silentLevel))
        {
            ww.WriteData(data);
        }
    }
    ww.Close();
    wr.Close();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top