




http://www.codeproject.com/Articles/19590/WAVE-File-Processor-in-C
В нем есть весь код, необходимый для удаления тишины и микширования волновых файлов.
Наслаждаться.
Не думаю, что вы найдете встроенные API для обнаружения тишины. Но вы всегда можете использовать старую хорошую математическую / дискретную обработку сигналов, чтобы узнать громкость. Вот небольшой пример: http://msdn.microsoft.com/en-us/magazine/cc163341.aspx
Аудиоанализ - сложная вещь, требующая большого количества сложных математических расчетов (вспомните преобразования Фурье). Вы должны задать вопрос: «Что такое тишина». Если звук, который вы пытаетесь редактировать, захвачен из аналогового источника, есть вероятность, что тишины нет ... это будут только области с мягким шумом (линейный гул, окружающий фоновый шум и т. д.).
Все это говорит о том, что алгоритм, который должен работать, будет определять минимальный порог громкости (амплитуды) и длительность (скажем, статья CodeProject выглядит интересной; в ней описывается код C# для рисования формы волны ... это тот же самый код, который может использоваться для другого амплитудного анализа.
Если вы хотите эффективно рассчитать среднюю мощность по скользящему окну: возведите каждую выборку в квадрат, а затем добавьте ее к промежуточной сумме. Вычтите квадрат значения из N предыдущих выборок. Затем переходите к следующему шагу. Это простейшая форма фильтра CIC. Теорема Парсеваля сообщает нам, что этот расчет мощности применим как к временной, так и к частотной области.
Также вы можете добавить в систему Гистерезис, чтобы избежать быстрого включения и выключения, когда уровень мощности колеблется около порогового уровня.
Используйте Sox. Он может удалять начальные и конечные тишины, но вам придется называть его как 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), что не совсем дешево.
Похоже на рекламу библиотеки Alvas Audio без открытого кода.
Я не уверен, почему коммерческие решения отвергаются как ответы. Есть ли для этого политика SO? В этом программном обеспечении может быть много качеств, которых не могут достичь другие, которые могут понадобиться OP или будущему посетителю. Вы должны критиковать ответ за его отношение к вопросу, а не вашей идеологии.
Я уверен, что если бы в сообщении был заголовок об использовании сторонней несвободной библиотеки, он бы не получил голоса против, вместо того, чтобы случайно проскользнуть в подобную рекламу.
Я использую 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 в формуле db? Я работаю над обнаружением и удалением тишины из записанного звука около 1,5 месяца, но мне это еще не удалось ... это мои вопросы по этой теме в стеке, Вопрос 1 и вопрос 2 Буду признателен, если вы поможете мне реши эту проблему, я студент и это моя домашняя работа и я не профессионал в этом предмете
Когда я запускаю этот код на видео mp4, значения находятся в диапазоне от -96 до 0. 0 - максимальная громкость.
Вот хороший вариант для обнаружения чередования порогов:
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;
}
}
ссылка не работает ... :(