调试NAudio MP3读取差异?
我使用 NAudio 读取特定 MP3 的代码得到的结果与其他几个商业应用程序不同。
具体来说:我的基于 NAudio 的代码发现,在“可听音频”(鼓拾音器)开始之前,该 MP3 的开头有约 1.4 秒的静音,而其他应用程序(Windows Media Player、RealPlayer、WavePad)则在开始之前显示约 2.5 秒的静音同一个鼓拾音器。
该 MP3 是从 Amazon.com 下载的“Like A Rolling Stone”。测试了其他几个 MP3,没有显示出我的代码和其他应用程序之间有任何类似的差异。大多数 MP3 的开头不会有这么长时间的静音,所以我怀疑这就是差异的根源。
调试问题:
我实际上找不到一种方法来证明其他应用程序是正确的而 NAudio/me 是错误的,即逐块比较我的代码结果与“已知良好的参考实现”;因此我什至无法精确定义我需要调试的“错误”。
由于我的代码在 1.4 秒内读取了数千个样本,没有明显错误,因此我无法想象如何缩小输入流中的位置/时间范围以查找错误。
NAudio 代码的核心是对 acmStreamConvert() 的 P/Invoke 调用,这是一个 Windows“黑匣子”调用,我不知道如何进行错误检查。
任何人都可以想到任何技巧/技术来调试这个吗?
My code using NAudio to read one particular MP3 gets different results than several other commercial apps.
Specifically: My NAudio-based code finds ~1.4 sec of silence at the beginning of this MP3 before "audible audio" (a drum pickup) starts, whereas other apps (Windows Media Player, RealPlayer, WavePad) show ~2.5 sec of silence before that same drum pickup.
The particular MP3 is "Like A Rolling Stone" downloaded from Amazon.com. Tested several other MP3s and none show any similar difference between my code and other apps. Most MP3s don't start with such a long silence so I suspect that's the source of the difference.
Debugging problems:
I can't actually find a way to even prove that the other apps are right and NAudio/me is wrong, i.e. to compare block-by-block my code's results to a "known good reference implementation"; therefore I can't even precisely define the "error" I need to debug.
Since my code reads thousands of samples during those 1.4 sec with no obvious errors, I can't think how to narrow down where/when in the input stream to look for a bug.
The heart of the NAudio code is a P/Invoke call to acmStreamConvert(), which is a Windows "black box" call which I can't think how to error-check.
Can anyone think of any tricks/techniques to debug this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
NAudio ACM 代码最初并非用于 MP3,而是用于解码恒定比特率电话编解码器。有一天,我尝试设置 WaveFormat 以指定 MP3 作为实验,结果听起来不错。然而,我一直对使用 ACM 解码 MP3(尤其是 VBR)感到有点紧张(例如,如果 ID3 标签或专辑封面被传入会出现什么结果 - 这是否会导致额外的沉默?),而且我从来没有 100%确信 NAudio 做得正确 - 关于如何准确使用 ACM 编解码器的文档很少。遗憾的是,没有可以在 NAudio 中使用的带有许可证的托管 MP3 解码器,因此 ACM 目前仍然是唯一的选择。
我不确定其他媒体播放器采用什么方法来播放 MP3,但我怀疑其中许多媒体播放器都有自己的内置 MP3 解码器,而不是依赖操作系统。
The NAudio ACM code was never originally intended for MP3s, but for decoding constant bit rate telephony codecs. One day I tried setting up the WaveFormat to specify MP3 as an experiment, and what came out sounded good enough. However, I have always felt a bit nervous about decoding MP3s (especially VBR) with ACM (e.g. what comes out if ID3 tags or album art get passed in - could that account for extra silence?), and I've never been 100% convinced that NAudio does it right - there is very little documentation on how exactly you are supposed to use the ACM codecs. Sadly there is no managed MP3 decoder with a license I can use in NAudio, so ACM remains the only option for the time being.
I'm not sure what approach other media players take to playing back MP3, but I suspect many of them have their own built-in MP3 decoders, rather than relying on the operating system.
我找到了我自己的问题的一些部分答案:
由于我的问题归结为消耗了太多 MP3 而没有产生足够的 PCM,所以我使用条件命中计数断点来查找发生这种情况的位置, 。
这表明一些 acmStreamConvert() 调用返回成功,消耗 417 src 字节,但产生 0“使用的目标字节”。
接下来我计划尝试 acmStreamSize() 询问编解码器它“想要”消耗多少 src 字节,而不是“告诉”它消耗 417。
编辑(后续):我修复了它!
归结为传递 acmStreamConvert() 足够的 src 字节以使其满意。为其提供 acmStreamSize() 请求的大小可以解决某些地方的问题,但随后又会在其他地方弹出;给它请求的大小乘以 3 似乎可以解决我测试过的所有 MP3 中“使用 0 目标字节”的结果。
通过此修复,acmStreamConvert() 有时会返回更大的转换块(几乎 32 KB),因此我还必须修改其他一些 NAudio 代码以传入更大的目标缓冲区来保存结果。
I've found some partial answers to my own Q:
Since my problem boils down to consuming too much MP3 w/o producing enough PCM, I used conditional-on-hit-count breakpoints to find just where this was happening, then drilled into that.
This showed me that some acmStreamConvert() calls are returning success, consuming 417 src bytes, but producing 0 "dest bytes used".
Next I plan to try acmStreamSize() to ask the codec how many src bytes it "wants" to consume, rather than "telling" it to consume 417.
Edit (followup): I fixed it!
It came down to passing acmStreamConvert() enough src bytes to make it happy. Giving it its acmStreamSize() requested size fixed the problem in some places but then it popped up in others; giving it its requested size times 3 seems to cure the "0 dest bytes used" result in all MP3s I've tested.
With this fix, acmStreamConvert() then sometimes returned much larger converted chunks (almost 32 KB), so I also had to modify some other NAudio code to pass in larger destination buffers to hold the results.