【发布时间】:2018-06-26 21:24:57
【问题描述】:
所以我目前正在尝试从外部麦克风(在这种情况下实际上是在机器人上)获取音频并将其流式传输到 Unity 以在场景中播放。我相当肯定这段音频是以 mp3 格式编码的,采样率为 16000 Hz,比特率为 192 kHz。
我能够在 Unity 中将此音频作为字节数组(似乎总是小端序),我想转换为浮点数组,每个值的范围从 -1.0f 到 +1.0f这样我就可以使用 AudioClip.SetData 在 Unity 场景中播放它。我的问题是到目前为止我无法做到这一点。
我的第一次尝试是基于这个 StackOverflow 答案:create AudioClip from byte[] 它使用以下函数进行转换:
private 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) / 0x80000000;
}
return floatArr;
}
然后我像这样调用它:
scaledAudio = ConvertByteToFloat(audioData);
AudioClip audioClip = AudioClip.Create("RobotAudio", scaledAudio.Length, 1, 16000, false);
audioClip.SetData(scaledAudio, 0);
AudioSource.PlayClipAtPoint(audioClip, robot.transform.position);
但是结果是很多静态的,并且在记录一些输出时,我意识到我得到了一堆 NaN...
我在某处读到可以使用 BitConverter.ToInt16() 函数提取 mp3 音频,因此我相应地更改了 ConvertByteToFloat 函数,如下所示:
private float[] ConvertByteToFloat16(byte[] array) {
float[] floatArr = new float[array.Length / 2];
for (int i = 0; i < floatArr.Length; i++) {
if (BitConverter.IsLittleEndian) {
Array.Reverse(array, i * 2, 2);
}
floatArr[i] = (float) (BitConverter.ToInt16(array, i * 2) / 32767f);
}
return floatArr;
}
[注意:结果除以 32767f,因为我读到这是可能出现的最大值,我想将其缩小到 -1.0f 和 1.0f 之间]
由此得出的数字看起来更有希望。它们确实都在 -1.0f 和 1.0f 之间。但是当我尝试使用 Unity 播放音频时,我听到的都是静态的。
几乎可以肯定,问题似乎在于将 byte[] 转换为 float[],但我可能在为 AudioClip 或 AudioSource 设置数据或播放器时犯了错误。
非常感谢任何帮助/建议!
[附加资源:我进入unity的byte[]来自这里:https://github.com/ros-drivers/audio_common/blob/master/audio_capture/src/audio_capture.cpp 有一个相关脚本可以获取此捕获程序编码的数据并播放它(https://github.com/ros-drivers/audio_common/blob/master/audio_play/src/audio_play.cpp)。这工作得很好 - 所以如果我可以在第二个链接中复制 audio_play 脚本的解码功能,看起来我会很高兴!]
【问题讨论】: