题
我的任务是建设一个.净客户应用程序来检测沉默,在有声文件。
这是可能的内置Windows Api?或交替,任何好的图书馆有帮助吗?
解决方案
音频分析是一种困难的事情需要很多复杂的数学(认为傅里叶变换).这个问题你要问的是"什么是沉默"。如果声音,你是在试图编辑被捕获,从一个模拟源的机会,没有任何沉默...他们将只能领域的软噪音(行的嗡嗡声,环境背景噪音等等)。
所有这一切说,一种算法,应工作将确定一个最低限量(幅度)的阈值和持续时间(说 <10dbA超过2秒),然后只是做一卷的分析在波寻找领域满足这种标准(或许是一些过滤器,用于毫秒的峰值).我从来没写这C#但是这 演示文章 看起来很有趣;它描述了C#码绘制一种波形...这是同样的代码这可能是用来做其他的幅度分析。
其他提示
如果你想要有效地计算的平均功率超过一个滑动窗口:广场每个样品,然后将它添加到总运行。减去的方价值从N样本上。然后移动到一个新的步骤。这是最简单的形式 CIC 滤波器。 Parseval定理 告诉我们,这种功率的计算适用于这两个时间和频率的领域。
你也可能想要加入 滞后 系统,以避免交换和关闭迅速时的功率水平是跳舞的关于阈值水平。
我在使用 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);
}
}
这将接受几乎任何音频文件的格式 不仅仅是。.
使用:
using (AudioFileReader reader = new AudioFileReader(filePath))
{
TimeSpan duration = reader.GetSilenceDuration(AudioFileReaderExt.SilenceLocation.Start);
Console.WriteLine(duration.TotalMilliseconds);
}
参考文献:
我不认为你会找到的任何内在的用于检测的沉默。但你可以永远使用良好的ol'数学/discreete信号处理,以找出响度。这里有一个小的例子: http://msdn.microsoft.com/en-us/magazine/cc163341.aspx
使用 Sox.它可以删除开头和结尾的沉默,但你必须把它作为一个exe从你的应用程序。
见下面的代码从 检测音沉默果文件,使用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();
}