Jer*_*ski 10 c# audio base64 unity-game-engine
我在base64中编码了wav文件(参考资料/声音中的audioClipName.txt).
然后我尝试解码它,从它做一个AudioClip并像这样播放:
public static void CreateAudioClip()
{
string s = Resources.Load<TextAsset> ("Sounds/audioClipName").text;
byte[] bytes = System.Convert.FromBase64String (s);
float[] f = ConvertByteToFloat(bytes);
AudioClip audioClip = AudioClip.Create("testSound", f.Length, 2, 44100, false, false);
audioClip.SetData(f, 0);
AudioSource as = GameObject.FindObjectOfType<AudioSource> ();
as.PlayOneShot (audioClip);
}
private 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;
}
Run Code Online (Sandbox Code Playgroud)
每件事情都很好,除了声音只是一个噪音.
我发现这个在这里堆栈溢出,但答案dosnt解决问题.
以下是Unity3D的wav文件的详细信息:
有谁知道这里的问题是什么?
编辑
我写下了二进制文件,一个是在从base64解码后,在最后一次转换后第二个,并将其与原始的二进制wav文件进行比较:
正如您所看到的,文件已正确编码,因为只需对其进行解码并将文件写入如下:
string scat = Resources.Load<TextAsset> ("Sounds/test").text;
byte[] bcat = System.Convert.FromBase64String (scat);
System.IO.File.WriteAllBytes ("Assets/just_decoded.wav", bcat);
Run Code Online (Sandbox Code Playgroud)
给了同样的文件.所有文件都有一定的长度.
但最后一个是错误的,所以问题在于转换为float数组.但我不明白可能出现的问题.
编辑:
这是写下final.wav的代码:
string scat = Resources.Load<TextAsset> ("Sounds/test").text;
byte[] bcat = System.Convert.FromBase64String (scat);
float[] f = ConvertByteToFloat(bcat);
byte[] byteArray = new byte[f.Length * 4];
Buffer.BlockCopy(f, 0, byteArray, 0, byteArray.Length);
System.IO.File.WriteAllBytes ("Assets/final.wav", byteArray);
Run Code Online (Sandbox Code Playgroud)
您尝试播放的wave文件(meow.wav)具有以下属性:
您的主要错误是,您正在解释二进制数据,就好像它已经代表浮点数一样.这是什么呢BitConverter.ToSingle().
但是你需要做的是,从每两个字节创建一个带符号的16位little-endian值(如Wavefile-header中所指定的),将其转换为float,然后将其标准化.并且每个两个字节在您的文件(16位!)的情况下进行采样,而不是四个字节.数据是小端(s16le),所以如果主机没有,你只需要交换它.
这将是纠正的转换函数:
private static float[] ConvertByteToFloat(byte[] array) {
float[] floatArr = new float[array.Length / 2];
for (int i = 0; i < floatArr.Length; i++) {
floatArr[i] = ((float) BitConverter.ToInt16(array, i * 2))/32768.0;
}
return floatArr;
}
Run Code Online (Sandbox Code Playgroud)
你应该跳过波形文件的标题(真实音频数据从偏移44开始).
对于一个干净的解决方案,您必须正确解释Wave-header并根据其中指定的内容调整您的操作(如果它包含不受支持的参数,则进行挽救).例如,必须注意样本格式(每个样本的比特数和字节数),采样率和通道数.