如何将8位声音转换为16位



我正在使用DynamicSoundEffectInstance流式传输原始PCM数据。此数据为16位,并带有符号。我的代码运行良好,没有一个问题。问题是压缩这个原始PCM会产生较差的结果:139MB下降到13.7mb。

如果我将PCM数据编码为8位有符号值,然后压缩它,结果是一个5.24mb的小文件——这比Ogg文件小大约1mb。

为什么不直接使用Ogg太麻烦了。我不想要任何依赖关系,需要跨平台支持,而原始PCM使用DynamicSoundEffectInstance可以做到这一点。

我已经想好了,我必须以某种方式将8位数据恢复到16位,这样XNA就可以按原样播放了。这就是我迷失的地方。我花了无数个小时研究如何做到这一点,但没有取得任何进展。根本没有。

如何将8位字节转换为16位整数?Convert.ToInt16没有任何帮助,声音仍然是混乱的胡言乱语。

有人知道一个简单的方法吗?还是我认为这一切都错了?关于音频,你能不能不把8位转换成16位?

编辑:以下是一些VERY使用Convert.ToInt16的令人震惊的VB代码。数据数组包含44100个字节的音频。

Dim buffer((44100 * 2) - 1) As Byte ' place to dump 8-16bit data
For i As Integer = 0 To data.Count - 1 ' data holds 8bit data
    Dim aaa = Convert.ToInt16(data(i))
    Dim bb() As Byte = BitConverter.GetBytes(aaa)
    buffer(i * 2) = bb(0)
    buffer(i * 2 + 1) = bb(1)
Next

这确实有效,尽管Windows需要将系统音量调到100才能听到,但它仍然几乎听不见,而且充满了静电。

根据您的代码示例,您似乎只剩下将8位样本向左移动8位,这样数据就占据了16位样本的最高有效位。

即:

Dim buffer((44100 * 2) - 1) As Byte ' place to dump 8-16bit data
For i As Integer = 0 To data.Count - 1 ' data holds 8bit data
    Dim aaa = Convert.ToInt16(data(i)) << 8 ' shift to most-significant-bits
    Dim bb() As Byte = BitConverter.GetBytes(aaa)
    buffer(i * 2) = bb(0)
    buffer(i * 2 + 1) = bb(1)
Next

您可能仍然会遇到噪声问题,因为将样本量减半也会使信噪比减半。

我刚刚在尝试从头开始构建音频播放器时遇到了类似的问题。令我惊讶的是,我发现8位音频通常是无符号的,而16位音频通常有符号。请参阅另一个SO用户的回答:

https://stackoverflow.com/a/43939741/7732473

最新更新