I finished getting row data from a WAV file. So now, I know the informatipon about the WAV file, such as DataRate and SamplingPerBits, etc.
And I have several kinds of data types after reading the WAV file: 16 bits - []Int16, 8 bits - []byte.
Now I am trying to convert []Int16 to []float!
I found the NAudio.wave function Wave16ToFloatProvider().
I have seen Converting 16 bit to 32-nit floating point. But I couldn't get about it, because I don't need to write WaveFileWriter. So I tried to do without WaveFileWriter. Here is my code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NAudio;
using NAudio.Wave;
namespace WaveREader
{
class WaveReader
{
WaveFileReader reader = new WaveFileReader("wavetest.wav");
IWaveProvider stream32 = new Wave16ToFloatProvider(reader);
byte[] buffer = new byte[8192];
float[] DATASIXTEEN;
for (int i = 0; i < buffer.Length; i++)
{
DATASIXTEEN = new float[buffer.Length];
DATASIXTEEN[i] = stream32.Read(buffer, 0, buffer.Length);
}
}
}
I think this part would be wrong, DATASIXTEEN[i] = stream32.Read(buffer, 0, buffer.Length);
, but I have no idea how to correct it.
Would you give me some advice for it or code by using Wave16ToFloatProvider?
Or would I ask you how to convert without Wave16ToFloatProvider?
The return value from Stream.Read
is the count of the number of bytes read, not what you're after. The data you want is in the buffer, but each 32-bit sample is spread across 4 8-bit bytes.
There are a number of ways to get the data as 32-bit float.
The first is to use an ISampleProvider
which converts the data into the floating point format and gives a simple way to read the data in that format:
WaveFileReader reader = new WaveFileReader("wavetest.wav");
ISampleProvider provider = new Pcm16BitToSampleProvider(reader);
int blockSize = 2000;
float[] buffer = new float[blockSize];
// Read blocks of samples until no more available
int rc;
while ((rc = provider.Read(buffer, 0, blockSize)) > 0)
{
// Process the array of samples in here.
// rc is the number of valid samples in the buffer
// ....
}
Alternatively, there is a method in WaveFileReader
that lets you read floating point samples directly. The downside is that it reads one sample group (, that is, one sample for each channel - one for mono, two for stereo) at a time, which can be time consuming. Reading and processing arrays is faster in most cases.
WaveFileReader reader = new WaveFileReader("wavetest.wav");
float[] buffer;
while ((buffer = reader.ReadNextSampleFrame()) != null)
{
// Process samples in here.
// buffer contains one sample per channel
// ....
}