将 32 位浮点音频转换为 16 位字节数组?

Posted

技术标签:

【中文标题】将 32 位浮点音频转换为 16 位字节数组?【英文标题】:Convert 32 bit float audio to 16 bit byte array? 【发布时间】:2013-09-08 22:47:45 【问题描述】:

我正在使用 NAudio 库获取音频,该库返回 32 位 float[] 音频数据。我正在尝试找到一种方法将其转换为 16 位 byte[] 进行播放。

private void sendData(float[] samples)

    Buffer.BlockCopy(samples, 0, byteArray, 0, samples.Length);
    byte[] encoded = codec.Encode(byteArray, 0, byteArray.Length);
    waveProvider.AddSamples(byteArray, 0, byteArray.Length);
    s.Send(encoded, SocketFlags.None);

发送到waveProvider 的音频是静态输出的——我认为我的转换不正确。如何转换为 16 位样本的字节数组?

【问题讨论】:

【参考方案1】:

Buffer.BlockCopy 复制了一些字节,但你传递给它一些元素。由于 float 是 4 个字节,而 byte 显然是 1,因此您使用 samples 的四分之一来填充 byteArray 的一半,其余部分保持不变。至少可以说,这可能不会为您提供非常好的音频。

您需要做的是将 -1 和 1 之间的浮点值转换为 -215 和 215之间的 16 位整数值>-1。如果我们转换为shorts 而不是bytes,那就很简单了:

shortSample = (short)Math.Floor(floatSample * 32767);

(如果您知道 floatSample 将始终小于 1,则应乘以 32,768 而不是 32,767。) 当然,您需要一个字节数组而不是short 数组。不幸的是,您没有为最后一步提供足够的信息。您需要了解两件事:字节序和符号。如果它未签名,则需要通过添加 32,768 将 short 转换为 ushort。然后你需要将每个shortushort 分成两个字节。字节序决定了顺序,但您可能需要进行一些位移。

【讨论】:

感谢您的回复,它开始变得更有意义了。我对 Endianness 不是很熟悉,但我会查看图书馆,看看我是否能弄清楚。只是为了我自己的学习 - 为什么需要将它们分成 2 个字节?当我使用 GetBytes 方法 (byte[] samplesByteArray = BitConverter.GetBytes(shortSample);) @user547794:如果它需要一个 16 位字节数组并且每个字节是 8 位,那么每个 16 位短需要两个字节。 Math.Floor 调用不是多余的吗?

以上是关于将 32 位浮点音频转换为 16 位字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

在 C/C+ 中从 16 位线性 PCM 音频转换为 32 位浮点的最佳方法?

将 32 位浮点数转换为 16 位 PCM 范围

PCM音频实时播放:音频字节数组(16/8位)转为PCM ArrayBuffer流

如何正确将 16Bit 字节数组转换为音频剪辑数据?

如何将 Int16 音频样本的数据转换为浮点音频样本数组

Jack 中的“32 位浮点单声道音频”