This project has moved. For the latest updates, please go here.

Using the WdlResamplingSampleProvider correctly

Jun 22, 2016 at 3:16 PM
I read in a .wav of 8bit/22050Hz form, and want to resample it. (this is a UWP). From the articles by the author I should be using the WdlResamplingSampleProvider. As a first test I made it resample to the same rate to have something to compare it with.

But something isn't right. I used WaveStream reader to read the .wav file to a byte array, and it is correct. The size, the data, its fine. But after using the resampler, its resulting float array[] is all zeros. Additionally, the bits per sample is listed as 32 even though the source file is 8. (see pics).

So I am hunting for the correct way to resample and see the results or a work around.
Thanks
private WaveStream reader;
private IRandomAccessStream selectedStream;
byte[] wavByteArray;    

async void Conversion()
{
    using (var stream = await file.OpenAsync(FileAccessMode.Read))
    {
        if (stream == null) return;
        this.selectedStream = stream;
        CreateReader();
        wavByteArray = new byte[reader.Length];
        var result = reader.Read(wavByteArray, 0, (int)reader.Length);
    }
    var resampler = new WdlResamplingSampleProvider(reader.ToSampleProvider(), 22050);
    float[] floatArray = new float[reader.Length];
    var result = resampler.Read(floatArray, 0, (int)reader.Length);
}
pictures of the code running
https://1drv.ms/f/s!Apomoggzevs3hJdrjxg25gFwyzdZ2A
Coordinator
Jun 25, 2016 at 3:53 PM
WDLResampler works exclusively with floating point samples. So ToSampleProvider is resampling. I would also recommend resampling in small chunks, say 1 second of audio at a time, rather than one gigantic call to read.
Jun 27, 2016 at 8:05 PM

Thanks Mark,

You are saying that my reader.ToSampleProvider() won’t work because it will provide the WDLR only 8-bit byte samples and not floats?

Should I take the 8-bit byte array, cast it to float, then somehow turn that back into an ISampleSource? Not sure how to do that exactly.

Coordinator
Jun 27, 2016 at 9:00 PM
sorry, my reply was confusing. ToSampleProvider should turn your incoming audio into 32 bit floating point samples, which should be fine. I still recommend resampling in much smaller blocks.
Jun 30, 2016 at 7:06 PM

Gosh, Mark,

I tried breaking it up into more discrete steps to see where things go wrong. In the code below, neither wavFloatArray ends up with any resampled data. Both output arrays end up 2000 entries long filled with all zeros. If I execute reader.Read(..) I get the source file contents at 22050, 8-bit filled with data. But it’s not resampled, and not 32bit.

If I set a break and look at the contents of the ISampleProvider isp, it says waveFormat.bitspersample= 32bit (like you said, resampled from 8 bits to 32) 22kHz(original sample rate), but the sourceBuffer[] is all zeros except the first entry. And the buffer array size looks peculiar. The 22/8 array is 13235bytes, while the blank isp buffer is 5516. I might have expected 13k/4, but not that.

So basically, still can’t get from that to any other sample rate.

ISampleProvider isp = new Pcm8BitToSampleProvider(reader);

var resampler1 = new WdlResamplingSampleProvider(isp, 8000);

wavFloatArray = new float[2000];

var result = resampler1.Read(wavFloatArray, 0, 2000);

var resampler2 = new WdlResamplingSampleProvider(reader.ToSampleProvider(), 8000);

float[] wavFloatArray2 = new float[2000];

var result2 = resampler2.Read(wavFloatArray2, 0, 2000);