16Bit 바이트 배열을 오디오 클립 데이터로 올바르게 변환하는 방법은 무엇입니까?

Nov 26 2020

저는 Media Foundataion과 함께 작업하며 사운드 샘플 프레임을 바이트에서 오디오 플로트 데이터로 변환해야합니다. 이를 수행하기 위해 다음과 같은 방법을 사용합니다 (Google 어딘가에서 찾았습니다).

    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);
...

while인덱스 i = 21886오프셋 값 에서 루프 가 발생하여 43776 크기의 배열을 전달하면 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 RomanR. Nov 26 2020 at 13:58

정수는 -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;
    }
AlekseyTimoshchenko Dec 01 2020 at 13:54

결국 나는 이렇게했다 :

    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;
    }