我目前正在编写将音频片段转换为float数组的代码,然后想将该float数组转换为字节,最后将该字节数组转换为十六进制。
一切正常但我们正在尝试保存数据的数组,当这些数据被转换为字节时,这些数据是数十万个元素,一旦我们尝试将这些数据保存为十六进制字符串,它有点多或需要太长时间对于我们正在测试的移动设备来处理。
所以我的问题是有没有办法优化/加快这个过程?
这是我的将我们的浮点数组转换为字节的代码:
public byte[] ConvertFloatsToBytes(float[] audioData){
byte[] bytes = new byte[audioData.Length * 4];
//*** This function converts our current float array elements to the same exact place in byte data
Buffer.BlockCopy(audioData,0,bytes,0,bytes.Length);
return bytes;
}
在这里,我们将该数据转换为十六进制字符串:
public static string ByteArrayToString(byte[] ba)
{
string hex = BitConverter.ToString(ba);
//Debug.Log("ba.length = " + ba.Length.ToString() +"hex string = " + hex);
return hex.Replace("-","");
}
最后,我们将字符串保存并将其从十六进制字符串转换为浮点数组。
就像我说代码很慢但它正在工作我只是想找到优化/加速此过程以提高性能的最佳方法
答案 0 :(得分:2)
你知道哪个部分花费了你吗?我强烈怀疑转换为十六进制数组不是程序中的瓶颈。
最后一部分,你删除连字符最终复制字符串。您可以通过编写自己的方法来复制BitArray.ToString
所做的更好,而不使用连字符。那就是:
const string chars = "0123456789ABCDEF";
public string ByteArrayToString(byte[] ba)
{
var sb = new StringBuilder(ba.Length*2);
for (int i = 0; i < ba.Length; ++i)
{
var b = ba[i];
sb.Append(chars[b >> 4]);
sb.Append(chars[b & 0x0F]);
}
return sb.ToString();
}
这将避免一个字符串副本。
如果您愿意使用不安全的代码(不知道您是否可以使用您正在使用的设备),您甚至可以通过不复制到字节数组来进一步加快速度。相反,你修复了内存中的浮点数组,然后用字节指针对它进行寻址。如果你对此感兴趣,请参见Unsafe Code and Pointers。
答案 1 :(得分:0)
听起来真的很复杂 - 音频样本通常不是整数吗?
无论如何,StreamWriter本身支持单一和双写,因此您可以使用它来构建一个然后转换为十六进制的内存流。