Обнаружение звука тишины в файлах WAV с использованием C # - PullRequest
28 голосов
/ 21 августа 2008

Мне поручено создать клиентское приложение .NET для обнаружения тишины в файлах WAV.

Возможно ли это с помощью встроенных API-интерфейсов Windows? Или, альтернативно, есть какие-нибудь хорошие библиотеки, чтобы помочь с этим?

Ответы [ 7 ]

14 голосов
/ 21 августа 2008

Аудиоанализ - это сложная вещь, требующая много сложной математики (подумайте о преобразованиях Фурье). Вопрос, который вы должны задать, это «что такое тишина». Если звук, который вы пытаетесь редактировать, получен из аналогового источника, есть вероятность, что тишины нет ... они будут только областями с мягким шумом (гул линии, фоновый шум и т. Д.).

Все это говорит о том, что алгоритм, который должен работать, заключается в определении минимального порога громкости (амплитуды) и продолжительности (скажем, <10 дБА в течение более 2 секунд), а затем просто выполняется анализ объема формы сигнала в поисках областей, соответствовать этому критерию (возможно, с некоторыми фильтрами для пиков в миллисекундах). Я никогда не писал этого на C #, но эта <a href="http://www.codeproject.com/Articles/20025/Sound-visualizer-in-C" rel="noreferrer"> статья CodeProject выглядит интересно; он описывает код C # для рисования формы сигнала ... это тот же самый код, который можно использовать для другого анализа амплитуды.

10 голосов
/ 21 августа 2008

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

Здесь есть весь код, необходимый для удаления тишины и смешивания волновых файлов.

Наслаждайтесь.

9 голосов
/ 28 августа 2008

Если вы хотите эффективно рассчитать среднюю мощность по скользящему окну: возведите в квадрат каждую выборку, а затем добавьте ее к промежуточной сумме. Вычтите значение квадрата из N выборок предыдущего. Затем перейдите к следующему шагу. Это самая простая форма фильтра CIC . Теорема Парсеваля говорит нам, что этот расчет мощности применим как к временной, так и к частотной областям.

Также вы можете добавить Гистерезис в систему, чтобы избежать быстрого включения и выключения, когда уровень мощности превышает пороговый уровень.

2 голосов
/ 03 сентября 2017

Я использую NAudio , и я хотел обнаружить тишину в аудиофайлах, чтобы я мог либо сообщить, либо усечь.

После долгих исследований я придумал эту базовую реализацию. Итак, я написал метод расширения для класса AudioFileReader, который возвращает продолжительность паузы в начале / конце файла или начиная с определенной позиции.

Здесь:

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);
    }
}

Принимает практически любой формат аудиофайла , а не только WAV .

Использование:

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

Ссылка:

1 голос
/ 22 октября 2009

Использование Sox . Он может удалить начальное и конечное молчание, но вам придется называть его exe из вашего приложения.

1 голос
/ 21 августа 2008

Я не думаю, что вы найдете какие-либо встроенные API для обнаружения тишины. Но вы всегда можете использовать хорошую математическую / дискретную обработку сигналов для определения громкости. Вот небольшой пример: http://msdn.microsoft.com/en-us/magazine/cc163341.aspx

0 голосов
/ 01 февраля 2014

См. Приведенный ниже код из Обнаружение звука тишины в файлах WAV с использованием 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...