AAC 和音频采样率不匹配

AAC and naudio sampling rate mismatch

我在 C# 中通过 naudio 运行 在通过线程安全队列馈送的单独线程中流式传输音频。输入到 naudio 的是一个由 16 位 PCM 数据组成的流,AAC 由 libfaad2 使用 PInvoke 解码,因为我没有找到原生的 C# AAC 解码器。数据由来自实时 "dab plus" 广播源的连续流组成。

这一切都非常顺利,只有一点例外。 AAC 解码器和 naudio 报告的数据速率不匹配。例如,libfaad2 解码器报告 48000 Hz 采样率,已使用广播电台的元数据进行初始化。 NAudio - 使用此采样率初始化 - 在短时间后生成 "Buffer full" 异常(30 秒,512000 字节 naudio 缓冲区,超时与缓冲区大小成线性比例)。

naudio 的 "DiscardOnBufferOverflow" 选项不是该问题的可行解决方案,因为它会在该事件之后导致 - 当然 - 可听见的伪影。 当我将 naudio 报告的 48000 Hz 增加 3000 时,即用 51000 Hz 初始化 naudio,它在缓冲区溢出异常之前运行了将近一个小时。

我还录制了一个三分钟的文件,音频保留在 48kHz,听起来很完美。

我的问题:流式传输时,naudio 和 AAC 解码器之间的比特率不匹配可能是什么原因?我真的很想知道这样做的原因,因为我不想让当前的 hack 实施。

采样率以 Hz 而非 bps 为单位进行测量。您确定 AAC 是 48kHz 还是 48kbps?在这种情况下,采样率可以是 44.1kHz,这可以解释差异。

为了调试它,我将 libfaad2 的一些输出写入 48kHz WAV 文件并检查它是否以预期速度播放。

虽然快 2 岁了,但直到今天我找到了解决方案,才解决了该行为的原因。

原因是 libfaad2.dll 的行为,它将 AAC 编码缓冲区转换为 pcm16 缓冲区。由其 "NeAACDecInit" API 调用 (DTS headers) 初始化,它假定帧长度为 1024 字节,而 DAB+ 数据编码为 960 字节。尽管如此,libfaad 对其进行解码,导致上述不匹配。 正常的解决方案是使用 "Audio Specific Coding (ASC)" 和 "NeAACDecInit2" API 调用,这通常适用于 DAB+ 解码软件。使用 ASC 编码的 "Init2" 可以选择 select 帧长度,与使用 DTS headers 的 "Init" 相比,默认帧长度为 1024 字节。

但是,很有可能使用附加参数修改 libfaad "NeAACDecInit" API 调用,并使用它来命令 libfaad 使用短帧长度。在 libfaad2 库中执行此操作的正确位置可能是文件 "decoder.c",在第 321 行附近,然后插入 hDecoder->frameLength = 960;.

NAudio 不会再抱怨了。