【问题标题】:How to convert 8bit sound to 16bit如何将8bit声音转换为16bit
【发布时间】:2015-02-22 06:30:44
【问题描述】:

我正在使用 DynamicSoundEffectInstance 流式传输原始 PCM 数据。此数据为 16 位且有符号。我的代码工作正常,没有一个问题。问题是压缩此原始 PCM 产生的结果很差:从 13.9mb 降至 13.7mb。

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

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

我发现我必须以某种方式将 8 位数据恢复为 16 位,以便 XNA 可以播放它。这就是我迷路的地方。我已经花了无数个小时来研究如何做到这一点,但没有得到任何结果。无处可去。

如何将 8 位字节转换为 16 位整数? Convert.ToInt16 没用,声音还是乱码废话。

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

编辑: 这是一些使用 Convert.ToInt16 的非常令人震惊的 VB 代码。数据数组包含 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 才能听到它,它仍然几乎听不见并且充满了静电。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多