Обнаружение звуковой тишины в файлах WAV с использованием C#
Вопрос
Мне поручено создать клиентское приложение .NET для обнаружения тишины в файлах WAV.
Возможно ли это с помощью встроенных API Windows?Или, альтернативно, какие-нибудь хорошие библиотеки могут помочь в этом?
Решение
Аудиоанализ — сложная задача, требующая большого количества сложных математических вычислений (вспомните преобразования Фурье).Вам следует задаться вопросом: «Что такое молчание».Если звук, который вы пытаетесь отредактировать, захвачен из аналогового источника, скорее всего, тишины нет...это будут только области мягкого шума (линейный шум, окружающий фоновый шум и т. д.).
Все это говорит о том, что алгоритм, который должен работать, должен заключаться в определении минимального порога громкости (амплитуды) и продолжительности (скажем, <10 дБА в течение более 2 секунд), а затем просто выполнять объемный анализ формы сигнала в поисках областей, соответствующих этим критериям. (возможно, с некоторыми фильтрами для миллисекундных всплесков).Я никогда не писал это на C#, но это Статья о кодпроекте выглядит интересно;он описывает код C# для рисования сигнала...это тот же код, который можно использовать для другого амплитудного анализа.
Другие советы
http://www.codeproject.com/Articles/19590/WAVE-File-Processor-in-C
Здесь есть весь код, необходимый для удаления тишины и микширования волновых файлов.
Наслаждаться.
Если вы хотите эффективно рассчитать среднюю мощность по скользящему окну:возведите каждую выборку в квадрат, а затем прибавьте ее к промежуточной сумме.Вычтите значение квадрата из N предыдущих выборок.Затем переходите к следующему шагу.Это простейшая форма ЦИК Фильтр. Теорема Парсеваля говорит нам, что этот расчет мощности применим как к временной, так и к частотной области.
Также вы можете добавить Гистерезис в систему, чтобы избежать быстрого включения и выключения, когда уровень мощности колеблется около порогового уровня.
я использую НАудио, и я хотел обнаружить тишину в аудиофайлах, чтобы можно было либо сообщить об этом, либо обрезать.
После долгих исследований я пришел к этой базовой реализации.Итак, я написал метод расширения для 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);
}
Использованная литература:
Я не думаю, что вы найдете какие-либо встроенные API для обнаружения тишины.Но вы всегда можете использовать старую добрую математическую/дискретную обработку сигналов, чтобы определить громкость.Вот небольшой пример: http://msdn.microsoft.com/en-us/magazine/cc163341.aspx
Использовать Сокс.Он может удалить начальные и конечные паузы, но вам придется вызывать его как exe-файл из вашего приложения.
См. код ниже из Обнаружение звуковой тишины в файлах 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();
}