将原始字节数据转换为float

我有这个代码用于将byte[]转换为float[]

 public float[] ConvertByteToFloat(byte[] array) { float[] floatArr = new float[array.Length / sizeof(float)]; int index = 0; for (int i = 0; i < floatArr.Length; i++) { floatArr[i] = BitConverter.ToSingle(array, index); index += sizeof(float); } return floatArr; } 

问题是,我通常得到NaN结果! 为什么会这样? 我检查了byte[]是否有数据,数据似乎没问题。 如果它有帮助,值的一个例子是:

 new byte[] { 231, 255, 235, 255, } 

但是这会在转换为float后返回NaN (非数字)。 可能是什么问题呢? 还有其他更好的方法将byte[]转换为float[]吗? 我确信读入缓冲区的值是正确的,因为我将它与我的其他程序(对.wav文件执行放大)进行了比较。

如果endianness是问题,您应该检查BitConverter.IsLittleEndian的值以确定是否必须反转字节:

 public static float[] ConvertByteToFloat(byte[] array) { float[] floatArr = new float[array.Length / 4]; for (int i = 0; i < floatArr.Length; i++) { if (BitConverter.IsLittleEndian) { Array.Reverse(array, i * 4, 4); } floatArr[i] = BitConverter.ToSingle(array, i * 4); } return floatArr; } 

问题是指数中的255代表NaN(参见指数部分中的维基百科 ),所以你应该得到一个NaN。 尝试将最后255个更改为其他内容…

如果这是错误的字节顺序(你正在读大端数字)尝试这些(请注意它们是“不安全的”所以你必须检查项目属性中的unsafe标志)

 public static unsafe int ToInt32(byte[] value, int startIndex) { fixed (byte* numRef = &value[startIndex]) { var num = (uint)((numRef[0] << 0x18) | (numRef[1] << 0x10) | (numRef[2] << 0x8) | numRef[3]); return (int)num; } } public static unsafe float ToSingle(byte[] value, int startIndex) { int val = ToInt32(value, startIndex); return *(float*)&val; } 

我假设你的byte []不包含浮点数的二进制表示,但是包含Int8Int16的序列。 您发布的示例看起来不像基于float的音频样本(NaN和-2.41E + 24都不在-1到1的范围内。虽然一些新的音频格式可能支持该范围之外的浮点数,但传统上音频数据包含签名8或16位整数样本。

您需要注意的另一件事是通常不同的通道是交错的。 例如,它可以包含左边的第一个样本,然后是右边的通道,然后是第二个样本……所以你需要在解析时分离通道。

样本也是无符号的,但不常见。 在这种情况下,您需要从转换函数中删除偏移量。

因此,您首先需要将字节数组中的当前位置解析为Int8 / 16。 然后将该整数转换为-1到1范围内的浮点数。

如果格式是小端,您可以使用BitConverter。 使用两个字节序的另一种可能性是手动获取两个字节并将它们与位移组合。 我不记得小端或大端是否常见。 所以你需要自己尝试一下。

这可以通过以下函数完成(我没有测试它们):

 float Int8ToFloat(Int8 i) { return ((i-Int8.MinValue)*(1f/0xFF))-0.5f; } float Int16ToFloat(Int16 i) { return ((i-Int16.MinValue)*(1f/0xFFFF))-0.5f; } 

取决于您希望如何将字节转换为浮点数。 首先尝试精确定位实际存储在字节数组中的内容。 也许有文件格式规范? 您的代码中的其他转换?

在这种情况下,每个字节应转换为0到255之间的浮点数:

 public float[] ConvertByteToFloat(byte[] array) { return array.Select(b => (float)b).ToArray(); } 

如果bytes数组包含浮点数的二进制表示,则有几种表示forms,如果存储在文件中的表示与c#语言标准浮点表示( IEEE 754 )不匹配,则会发生类似这样的奇怪事情。