【发布时间】:2020-11-26 13:26:24
【问题描述】:
我与 Media Foundation 合作,我需要做的是将声音样本帧从字节转换为音频浮点数据。为了做到这一点,我使用了这样的方法(我在谷歌的某个地方找到了):
private static float[] Convert16BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
{
int wavSize = BitConverter.ToInt32(source, headerOffset);
headerOffset += sizeof(int);
Debug.AssertFormat(wavSize > 0 && wavSize == dataSize, "Failed to get valid 16-bit wav size: {0} from data bytes: {1} at offset: {2}", wavSize, dataSize, headerOffset);
int x = sizeof(Int16); // block size = 2
int convertedSize = wavSize / x;
float[] data = new float[convertedSize];
Int16 maxValue = Int16.MaxValue;
int i = 0;
while (i < convertedSize)
{
int offset = i * x + headerOffset;
data[i] = (float)BitConverter.ToInt16(source, offset) / maxValue;
++i;
}
Debug.AssertFormat(data.Length == convertedSize, "AudioClip .wav data is wrong size: {0} == {1}", data.Length, convertedSize);
return data;
}
我是这样使用的:
...
byte[] source = ...; // lenght 43776
... = Convert16BitByteArrayToAudioClipData(source , 0, 0);
...
看起来这个方法工作错误,因为如果我传递一个大小为 43776 的数组,结果在索引 while 循环中的索引 i = 21886 偏移值将是 offset = 43776 它会导致下一个方法出现异常
data[i] = (float)BitConverter.ToInt16(source /*43776*/, offset /*43776*/) / maxValue;
因为这些值不可能相同。
问题是 - 如何解决这个方法?或者也许有人可以建议改用什么?
编辑
private static float[] Convert16BitByteArrayToAudioClipData(byte[] source)
{
float[] data = new float[source.Length];
for (int i = 0; i < source.Length; i++)
{
data[i] = (float) source[i];
}
return data;
}
【问题讨论】:
-
我认为音频文件有一个 ASCII 标头。用记事本打开。通常有一个像 0x01 这样的起始字符,音频开始的位置和大小。
-
您之前的问题是媒体基金会的 C++ 代码。你真的切换到 C# 了吗?代码 sn-p 对处理假定的 PCM 音频数据缓冲区没有任何意义。
-
@RomanR。我愿意。我与 Unity 合作。使用媒体基础,我解码文件以获得示例帧(在 android 上赢得 impl 我有另一个解码器),然后我将它们全部传递给 C# 端,因为 Unity Audio Player 用 C# 编写以支持跨平台
-
Media Foundation API 为您提供(假设 - 您的问题不包含有关有效音频数据格式的任何信息)有符号 16 位整数的紧凑数组。您附加的代码 sn-p 意外地从比特流中获取大小......这显然是错误的,您只需要一个一个地读取整数并将它们转换为浮点数。
-
@RomanR。编辑了我的问题。是你的意思吗?
标签: c# audio ms-media-foundation