I need to get all the samples of a wav file into an array (or two if you need to do that to keep the stereo) so that I can apply some modifications to them. I was wondering
At time of writing nobody has addressed 32-bit or 64-bit encoded WAVs.
The following code handles 16/32/64 bit and mono/stereo:
static bool readWav( string filename, out float[] L, out float[] R )
{
L = R = null;
try {
using (FileStream fs = File.Open(filename,FileMode.Open))
{
BinaryReader reader = new BinaryReader(fs);
// chunk 0
int chunkID = reader.ReadInt32();
int fileSize = reader.ReadInt32();
int riffType = reader.ReadInt32();
// chunk 1
int fmtID = reader.ReadInt32();
int fmtSize = reader.ReadInt32(); // bytes for this chunk (expect 16 or 18)
// 16 bytes coming...
int fmtCode = reader.ReadInt16();
int channels = reader.ReadInt16();
int sampleRate = reader.ReadInt32();
int byteRate = reader.ReadInt32();
int fmtBlockAlign = reader.ReadInt16();
int bitDepth = reader.ReadInt16();
if (fmtSize == 18)
{
// Read any extra values
int fmtExtraSize = reader.ReadInt16();
reader.ReadBytes(fmtExtraSize);
}
// chunk 2
int dataID = reader.ReadInt32();
int bytes = reader.ReadInt32();
// DATA!
byte[] byteArray = reader.ReadBytes(bytes);
int bytesForSamp = bitDepth/8;
int nValues = bytes / bytesForSamp;
float[] asFloat = null;
switch( bitDepth ) {
case 64:
double[]
asDouble = new double[nValues];
Buffer.BlockCopy(byteArray, 0, asDouble, 0, bytes);
asFloat = Array.ConvertAll( asDouble, e => (float)e );
break;
case 32:
asFloat = new float[nValues];
Buffer.BlockCopy(byteArray, 0, asFloat, 0, bytes);
break;
case 16:
Int16 []
asInt16 = new Int16[nValues];
Buffer.BlockCopy(byteArray, 0, asInt16, 0, bytes);
asFloat = Array.ConvertAll( asInt16, e => e / (float)(Int16.MaxValue+1) );
break;
default:
return false;
}
switch( channels ) {
case 1:
L = asFloat;
R = null;
return true;
case 2:
// de-interleave
int nSamps = nValues / 2;
L = new float[nSamps];
R = new float[nSamps];
for( int s=0, v=0; s