我用 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;
}
一切正常,除了声音只是一种噪音。
我找到了 this这里是堆栈溢出,但答案并没有解决问题。
以下是有关 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);
给了同样的文件。所有文件都有一定的长度。
但是最后一个是错误的,所以问题出在转换为 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);
最佳答案
您尝试播放的 wave 文件 (meow.wav
) 具有以下属性:
- PCM
- 2 个 channel
- 44100 赫兹
- 带符号的 16 位小端
您的主要错误是,您正在解释二进制数据好像它已经代表了一个 float 。这就是 BitConverter.ToSingle()
的作用。
但您需要做的是,从每两个字节创建一个带符号的 16 位小端值(如 Wavefile header 中指定的),cast 将其转换为 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;
}
并且您应该跳过波形文件的标题(真正的音频数据从偏移量 44 开始)。
对于干净的解决方案,您必须正确解释 Wave-header 并根据那里指定的内容调整您的操作(或者如果它包含不受支持的参数则退出)。 例如,必须注意样本格式(每个样本的位数和字节序)、采样率和 channel 数。
关于c# - 从 base64 解码后的嘈杂音频剪辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35228767/