我一直在寻找答案,我只能找到一些零碎的东西。我想要做的是加载多个mp3文件(暂时合并它们),然后使用静音检测将它们分割成碎片。
我的理解是我可以使用Mp3FileReader,但问题是: 1.如何从mp3文件中读出20秒的音频?我是否需要阅读20次阅读器.WaveFormat.AverageBytesPerSecond?或者可能继续阅读框架,直到Mp3Frame.SampleCount / Mp3Frame.SampleRate的总和超过20秒? 2.我如何真正发现沉默?我会查看相应数量的连续样本,以检查它们是否都低于某个阈值。但是我如何访问样本,无论它们是8位还是16位,单声道还是立体声等?我可以直接解码MP3帧吗? 3.在示例10465处检测到静音后,如何将其映射回mp3帧索引以执行切割而不重新编码?
答案 0 :(得分:3)
以下是我推荐的方法(涉及重新编码)
AudioFileReader
直接在Read方法ISampleProvider
,并在其Read
方法中,不会返回静默的样本答案 1 :(得分:2)
MP3是一种压缩音频格式。你不能只删除比特并期望其余部分仍然是有效的MP3文件。实际上,由于它是基于DCT的变换,所以比特位于频域而不是时域。样本10465根本没有比特。其中包含样本10465的帧,并且存在描述该帧中所有频率的一组比特。
在样本10465处切换音频并继续使用一些随机的其他样本可能会导致不连续,这意味着所产生的帧中出现的频率数量会急剧增加。所以这绝对意味着一个完整的重新编码。更好的方法是平滑过渡,但这不是一个微不足道的操作。结果当然与输入略有不同,所以它仍然意味着重新编码。
我不明白你为什么要阅读20秒的音频。该号码来自何处?你通常想读一切。
声音是一波;完全可以预期它会过零。所以接近于零并不是特别的。对于20 Hz波(听觉阈值),零交叉每秒发生40次,但每次你有多个样本接近零。因此,您基本上需要多个样本,这些样本都接近于零,但两侧都是如此。 5 6 7
对于16位声音来说并不是很多,但它很可能是一个最大值为10000的波的一部分。你真的应该检查至少0.05秒来捕捉那些20赫兹的声音。
由于您在50毫秒的时间间隔内检测到静音,因此您有一个"位置"大约有几百个样本宽。幸运的是,那里有一个框架边界。切到那里。是的,还有重新编码的时间。
答案 2 :(得分:2)
在阅读之前: Mark的回答更容易实现,您几乎肯定会对结果感到满意。这个答案适合那些愿意花费大量时间的人。
所以说,基于静音切割MP3文件而不重新编码或完全解码实际上是可行的...基本上,你可以看看每个帧的侧面信息和每个粒子的增益和放大器。霍夫曼数据“估计”沉默。
现在它变得棘手......