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

时间:2015-02-22 06:30:45

标签: c# vb.net bit-shift monogame

我使用DynamicSoundEffectInstance来传输原始PCM数据。这个数据是16位并签名。我的代码工作正常,而不是一个问题。问题是压缩这个原始PCM产生不良结果:13.9mb降至13.7mb。

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

为什么不使用Ogg?太麻烦了。我不想要任何依赖项,需要跨平台支持,而原始PCM就可以使用DynamicSoundEffectInstance。

我已经发现我已经以某种方式将8位数据恢复到16位,因此XNA可以像它一样播放它。这就是我迷失的地方。我花了无数个小时看着如何做到这一点但却无处可去。无处可去。

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

有没有人知道这样做的简单方法,还是我看错了?关于音频,你能不能像这样将8bit转换成16bit吗?

修改 这是使用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才能听到它,它仍然几乎听不见并且充满了静电。

2 个答案:

答案 0 :(得分:3)

根据您的代码示例,您还剩下要做的唯一事情是将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

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

答案 1 :(得分:-1)

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

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