使用C#检测WAV文件中的音频静音

我的任务是构建一个.NET客户端应用程序来检测WAV文件中的静音。

内置Windows API可以实现这一点吗? 或者,还有任何好的图书馆来帮助解决这个问题吗?

音频分析是一项困难的事情,需要大量复杂的数学运算(想想傅立叶变换)。 你要问的问题是“什么是沉默”。 如果您尝试编辑的音频是从模拟信号源捕获的,则可能没有任何静音……它们只会是软噪声区域(线路嗡嗡声,环境背景噪声等)。

所有这一切,一个应该工作的算法是确定最小音量(幅度)阈值和持续时间(例如,<10dbA超过2秒),然后简单地对波形进行体积分析,寻找符合此标准的区域(可能有一些过滤器用于毫秒尖峰)。 我从来没有在C#中写过这个,但这个CodeProject文章看起来很有趣; 它描述了用于绘制波形的C#代码......这是可用于进行其他振幅分析的相同类型的代码。

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

这具有剥离静音和混合波形文件所需的所有代码。

请享用。

如果要有效计算滑动窗口的平均功率:对每个样本求平方,然后将其添加到运行总计中。 从之前的N个样本中减去平方值。 然后转到下一步。 这是CICfilter的最简单forms。 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); } } 

这将接受几乎任何音频文件格式, 而不仅仅是WAV

用法:

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

参考文献:

  • 如何计算音频dB级别 。
  • 浮点样本范围 。
  • 更多关于振幅 。

我认为你找不到任何用于检测沉默的内置API。 但是你总是可以使用好的数学/ discreete信号处理来找出响度。 这是一个小例子: http : //msdn.microsoft.com/en-us/magazine/cc163341.aspx

使用Sox 。 它可以删除前导和尾随静音,但您必须将其称为应用程序中的exe。

请参阅下面的代码, 使用C#检测WAV文件中的音频静音

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