0

I have a 32 bit wav array and I wanted to convert it to 8 bit

So I tried to take this function which converts 32 to 16

void _waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
    byte[] newArray16Bit = new byte[e.BytesRecorded / 2];
    short two;
    float value;
    for (int i = 0, j = 0; i < e.BytesRecorded; i += 4, j += 2)
    {
        value = (BitConverter.ToSingle(e.Buffer, i));
        two = (short)(value * short.MaxValue);

        newArray16Bit[j] = (byte)(two & 0xFF);
        newArray16Bit[j + 1] = (byte)((two >> 8) & 0xFF);
    }
}

And modify it to take x bit as destination

    private byte[] Convert32BitRateToNewBitRate(byte[] bytes, int newBitRate)
    {
        var sourceBitRate = 32;

        byte[] newArray = new byte[bytes.Length / (sourceBitRate / newBitRate)];

        for (int i = 0, j = 0; i < bytes.Length; i += (sourceBitRate / 8), j += (newBitRate / 8))
        {
            var value = (BitConverter.ToSingle(bytes, i));
            var two = (short)(value * short.MaxValue);

            newArray[j] = (byte)(two & 0xFF);
            newArray[j + 1] = (byte)((two >> 8) & 0xFF);
        }

        return newArray;
    }

My problem is that I wasn't sure how to convert the code within the "for" loop, I tried to debug it but I couldn't quite figure out how it works.

I saw here : simple wav 16-bit / 8-bit converter source code?, that they divided the value by 256 to get from 16 to 8, I tried to divide by 256 to get from 32 to 16 but it didn't work

        for (int i = 0, j = 0; i < bytes.Length; i += sourceBitRateBytes, j += newBitRateBytes)
        {
            var value = BitConverter.ToInt32(bytes, i);
            value /= (int)Math.Pow(256, sourceBitRate / newBitRate / 2.0);

            var valueBytes = BitConverter.GetBytes(value);

            for (int k = 0; k < newBitRateBytes; k++)
            {
                newArray[k + j] = valueBytes[k];
            }
Community
  • 1
  • 1
user779444
  • 1,365
  • 4
  • 21
  • 38

1 Answers1

0

The for loop is still using 16 bit in the following places:

  • short.MaxValue. Use byte.MaxValue instead.
  • by assigning two bytes at [j] and [j+1]. Assign one byte only.

I don't have the rest of the program and no sample data, so it's hard for me to try. But I'd say the following sounds about right

for (int i = 0, j = 0; i < bytes.Length; i += (sourceBitRate / 8), j += (newBitRate / 8))
{
    var value = (BitConverter.ToSingle(bytes, i));
    var two = (byte)(value * byte.MaxValue);

    newArray[j] = two;
}

Be aware that this works for 8 bit only, so newBitRate must be 8, otherwise it does not work. It should probably not be a parameter to the method.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222