繁体   English   中英

如何正确将 16Bit 字节数组转换为音频剪辑数据?

[英]How to convert 16Bit byte array to audio clip data correctly?

我与 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 的数组,结果在索引i = 21886处的while循环中,偏移值将是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;
    }

整数需要变成 -1..+1 浮点值

    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] / Int16.MaxValue); // <<---
        }

        return data;
    }

最终我这样做了:

    public static float[] Convert16BitByteArrayToAudioClipData(byte[] source)
    {
        int x = sizeof(Int16); 
        int convertedSize = source.Length / x;
        float[] data = new float[convertedSize];
        Int16 maxValue = Int16.MaxValue;

        for (int i = 0; i < convertedSize; i++)
        {
            int offset = i * x;
            data[i] = (float)BitConverter.ToInt16(source, offset) / maxValue;
            ++i;
        }

        return data;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM