4

I've been trying to convert a 32 bit stereo wav to 16 bit mono wav. I use naudio to capture the sound I and thought that using just the two of four more significant bytes will work.

Here is the DataAvailable implementation:

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


          newArray[j] = (byte)(two & 0xFF);
          newArray[j + 1] = (byte)((two >> 8) & 0xFF);
     }
     //do something with the new array:
}

Any help would be greatly appreciated!

Eduard Niesner
  • 175
  • 4
  • 10

2 Answers2

3

I finally found the solution. I just had to multiply the converted value by 32767 and cast it to short:

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);
    }
}
Eduard Niesner
  • 175
  • 4
  • 10
1

A 32-bit sample can be as high as 4,294,967,295 and a 16-bit sample can be as high as 65,536. So you'll have to scale down the 32-bit sample to fit into the 16-bit sample's range. More or less, you're doing something like this...

SixteenBitSample = ( ThirtyTwoBitSample / 4294967295 ) * 65536;

EDIT:

For the stereo to mono portion, if the two channels have the same data, just dump one of them, otherwise, add the wave forms together, and if they fall outside of the sample range (65,536) then you'll have to scale them down similarly to the above equation.

Hope that helps.

S1LENT WARRIOR
  • 11,704
  • 4
  • 46
  • 60
Quanta
  • 465
  • 5
  • 14
  • 16-bit samples are signed; 32-bit samples are unlikely to be integer in first place (floating point instead) – Roman R. Dec 29 '12 at 00:06
  • Thanks for trying to help! I must have done something wrong because it did not work the way you said. For the stereo to mono, I succeeded to use a stereo signal in my application which is much better. Thanks! – Eduard Niesner Dec 29 '12 at 00:17
  • @RomanR. : I used floating point in the final version ... see my solution. – Eduard Niesner Dec 29 '12 at 00:19