Мне поручено создать клиентское приложение .NET для обнаружения тишины в файлах WAV.
Возможно ли это с помощью встроенных API-интерфейсов Windows? Или, альтернативно, есть какие-нибудь хорошие библиотеки, чтобы помочь с этим?
Аудиоанализ - это сложная вещь, требующая много сложной математики (вспомним преобразования Фурье). Вопрос, который вы должны задать, это «что такое тишина». Если аудио, которое вы пытаетесь редактировать, получено из аналогового источника, есть вероятность, что тишины нет ... они будут только областями с мягким шумом (гул линии, фоновый шум и т. Д.).
Все это говорит о том, что алгоритм, который должен работать, должен определить минимальный порог громкости (амплитуды) и длительность (скажем, <10 дБА в течение более 2 секунд), а затем просто выполнить анализ объема сигнала, ища области, которые соответствуют этим критериям. (возможно с некоторыми фильтрами для пиков в миллисекундах). Я никогда не писал этого на C #, но эта статья CodeProject выглядит интересно; он описывает код C # для рисования формы сигнала ... это тот же код, который можно использовать для другого анализа амплитуды.
http://www.codeproject.com/Articles/19590/WAVE-File-Processor-in-C
Здесь есть весь код, необходимый для удаления тишины и микширования волновых файлов.
Наслаждаться.
Я не думаю, что вы найдете какие-либо встроенные API для обнаружения тишины. Но вы всегда можете использовать хорошую математическую / дискретную обработку сигналов для определения громкости. Вот небольшой пример: http://msdn.microsoft.com/en-us/magazine/cc163341.aspx
Если вы хотите эффективно рассчитать среднюю мощность по скользящему окну: возведите в квадрат каждую выборку, а затем добавьте ее к промежуточной сумме. Вычтите значение квадрата из N выборок предыдущего. Затем перейдите к следующему шагу. Это самая простая форма фильтра CIC . Теорема Парсеваля говорит нам, что этот расчет мощности применим как во временной, так и в частотной областях.
Также вы можете захотеть добавить гистерезис в систему, чтобы избежать быстрого включения и выключения, когда уровень мощности превышает пороговый уровень.
Используйте Сокс . Он может удалить начальное и конечное молчание, но вам придется называть его 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();
}
Alvas Audio
библиотеки с открытым исходным кодом . Я использую 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);
}
Ссылки:
amplitude
в формуле БД? Я работаю над обнаружением и удалением тишины из записанного аудио в течение 1,5 месяцев, но мне это еще не удалось ... это мои вопросы по этому вопросу в стеке, вопрос 1 и вопрос 2, я буду благодарен, если вы поможете Я, чтобы решить эту проблему, я студент, и это мой домашний проект, и я не профессионал в этом предметеВот хороший вариант для определения пороговых чередований:
static class AudioFileReaderExt
{
private static bool IsSilence(float amplitude, sbyte threshold)
{
double dB = 20 * Math.Log10(Math.Abs(amplitude));
return dB < threshold;
}
private static bool IsBeep(float amplitude, sbyte threshold)
{
double dB = 20 * Math.Log10(Math.Abs(amplitude));
return dB > threshold;
}
public static double GetBeepDuration(this AudioFileReader reader,
double StartPosition, sbyte silenceThreshold = -40)
{
int counter = 0;
bool eof = false;
int initial = (int)(StartPosition * reader.WaveFormat.Channels * reader.WaveFormat.SampleRate / 1000);
if (initial > reader.Length) return -1;
reader.Position = initial;
var buffer = new float[reader.WaveFormat.SampleRate * 4];
while (!eof)
{
int samplesRead = reader.Read(buffer, 0, buffer.Length);
if (samplesRead == 0)
eof = true;
for (int n = initial; n < samplesRead; n++)
{
if (IsBeep(buffer[n], silenceThreshold))
{
counter++;
}
else
{
eof=true; break;
}
}
}
double silenceSamples = (double)counter / reader.WaveFormat.Channels;
double silenceDuration = (silenceSamples / reader.WaveFormat.SampleRate) * 1000;
return TimeSpan.FromMilliseconds(silenceDuration).TotalMilliseconds;
}
public static double GetSilenceDuration(this AudioFileReader reader,
double StartPosition, sbyte silenceThreshold = -40)
{
int counter = 0;
bool eof = false;
int initial = (int)(StartPosition * reader.WaveFormat.Channels * reader.WaveFormat.SampleRate / 1000);
if (initial > reader.Length) return -1;
reader.Position = initial;
var buffer = new float[reader.WaveFormat.SampleRate * 4];
while (!eof)
{
int samplesRead = reader.Read(buffer, 0, buffer.Length);
if (samplesRead == 0)
eof=true;
for (int n = initial; n < samplesRead; n++)
{
if (IsSilence(buffer[n], silenceThreshold))
{
counter++;
}
else
{
eof=true; break;
}
}
}
double silenceSamples = (double)counter / reader.WaveFormat.Channels;
double silenceDuration = (silenceSamples / reader.WaveFormat.SampleRate) * 1000;
return TimeSpan.FromMilliseconds(silenceDuration).TotalMilliseconds;
}
}
Основное использование:
using (AudioFileReader reader = new AudioFileReader("test.wav"))
{
double duratioff = 1;
double duration = 1;
double position = 1;
while (duratioff >-1 && duration >-1)
{
duration = reader.GetBeepDuration(position);
Console.WriteLine(duration);
position = position + duration;
duratioff = reader.GetSilenceDuration(position);
Console.WriteLine(-duratioff);
position = position + duratioff;
}
}