Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用NAudio和.NET检测静音并在不重新编码的情况下剪切mp3文件_Naudio - Fatal编程技术网

如何使用NAudio和.NET检测静音并在不重新编码的情况下剪切mp3文件

如何使用NAudio和.NET检测静音并在不重新编码的情况下剪切mp3文件,naudio,Naudio,我一直在到处寻找答案,但我只能找到一些零碎的东西。我想做的是加载多个mp3文件(有点临时合并它们),然后使用静音检测将它们切碎 我的理解是,我可以使用Mp3FileReader进行此操作,但问题是: 1.如何读取mp3文件中的20秒音频?我需要读20次reader.WaveFormat.AverageBytesPerSecond吗?或者继续读取帧,直到Mp3Frame.SampleCount/Mp3Frame.SampleRate之和超过20秒? 2.我怎样才能真正察觉到沉默?我将查看适当数量的

我一直在到处寻找答案,但我只能找到一些零碎的东西。我想做的是加载多个mp3文件(有点临时合并它们),然后使用静音检测将它们切碎

我的理解是,我可以使用Mp3FileReader进行此操作,但问题是: 1.如何读取mp3文件中的20秒音频?我需要读20次reader.WaveFormat.AverageBytesPerSecond吗?或者继续读取帧,直到Mp3Frame.SampleCount/Mp3Frame.SampleRate之和超过20秒? 2.我怎样才能真正察觉到沉默?我将查看适当数量的连续样本,以检查它们是否都低于某个阈值。但是,无论是8位还是16位、单声道还是立体声等,我如何访问样本。?我可以直接解码MP3帧吗?
3.在我检测到样本10465的静音后,如何将其映射回mp3帧索引以执行剪切而无需重新编码?

mp3是一种压缩音频格式。你不能只删掉一些位,而期望剩下的仍然是一个有效的MP3文件。事实上,因为它是基于DCT的变换,所以位在频域而不是时域。对于样本10465,根本没有位。有一个包含样本10465的帧,有一组比特描述了该帧中的所有频率

在样本10465处简单地剪切音频并继续使用一些随机的其他样本可能会导致不连续,这意味着结果帧中出现的频率数量急剧增加。所以这肯定意味着完全重新编码。更好的方法是平滑过渡,但这不是一个简单的操作。结果当然与输入略有不同,所以它仍然意味着重新编码

  • 我不明白你为什么要读20秒的音频。那个号码是从哪里来的?你通常想阅读所有的东西

  • 声音是一种波;完全可以预料它会越过零度。所以接近零并不特别。对于一个20赫兹的声波(听力阈值),零交叉每秒发生40次,但每次都会有多个样本接近零。所以你基本上需要多个样本,它们都接近于零,但两边都是<代码>5 6 7对于16位的声音来说并不多,但它很可能是最大值为10000的波形的一部分。你真的应该检查至少0.05秒来捕捉那些20赫兹的声音

  • 由于在50毫秒的间隔内检测到静默,因此有一个大约几百个采样宽的“位置”。幸运的是,这里有一个框架边界。停在那儿。否则是时候重新编码了


  • 下面是我推荐的方法(它确实涉及到重新编码)

  • 使用
    AudioFileReader
    以读取方法直接获取MP3作为浮点样本
  • 找到一个开源的噪声门算法,将其移植到C#,并使用它来检测静默(即,当噪声门关闭时,您拥有静默。您需要调整阈值和攻击/释放时间)
  • 创建使用噪波门的派生
    ISampleProvider
    ,并且在其
    Read
    方法中不返回静默的样本
  • 或者:将输出传递到WaveFileWriter以创建WAV文件,并将WAV文件编码为MP3 或:用于直接编码,无需WAV步长。您可能首先需要从SampleProvider返回到16位WAV provider

  • 在阅读以下内容之前:马克的答案更容易实现,你几乎肯定会对结果感到满意。这个答案是为那些愿意花大量时间在上面的人准备的

    这样说来,在无需重新编码或完全解码的情况下,在静音的基础上剪切MP3文件实际上是可能的。。。基本上,您可以查看每个帧的侧面信息和每个颗粒的增益&哈夫曼数据来“估计”静音

    • 找到沉默
    • 将静默之前的所有帧复制到新文件
    现在事情变得棘手了

    • 静音后从帧中提取音频数据,跟踪哪个帧头与什么音频数据
    • 开始写入第二个新文件,但在写入帧时,请更新main_data_begin字段,以便位库与音频数据的实际位置同步

    下面是如何执行的一个基本实现,可以很容易地用来截断文件中的静默。