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

3
我正在使用DynamicSoundEffectInstance来流式传输原始PCM数据。这些数据是16位和有符号的。我的代码运行良好,没有任何问题。问题在于压缩这个原始PCM会产生很差的结果:从13.9mb降至13.7mb。
如果我将PCM数据编码为8位有符号值,然后压缩它,结果是一个小的5.24mb文件 - 这比Ogg文件小约1mb。
为什么不直接使用Ogg?太麻烦了。我不想有任何依赖关系,并且需要跨平台支持,而原始PCM通过DynamicSoundEffectInstance可以完美地实现这一点。
我已经想出了,必须以某种方式将8位数据转换回16位,以便XNA可以像播放它一样播放它。这就是我迷失的地方。我花费了无数个小时来研究如何做到这一点,但没有取得任何进展。根本没有任何进展。
如何将8位字节转换为16位整数?Convert.ToInt16毫无帮助,声音仍然是垃圾。是否有人知道简单的方法来做到这一点,或者我是否看错了?您不能像这样将8位转换为16位的音频吗?
编辑:这里是一些非常令人震惊的VB代码,使用Convert.ToInt16。数据数组包含44,100个字节的音频。
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个回答

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

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

https://dev59.com/JGTWa4cB1Zd3GeqPAzEq#43939741


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接