Sunday, May 29, 2011

Resampling and noise

Very often we have to change the sampling rate, number of channels and the size of a sample when converting from one format to another. You can use AudioCompression.Convert method for these purposes. Unfortunately, for the uncompressed PCM -> PCM this leads to a significant reduction in sound quality and appearance of extraneous noise. We can verify this by example.


private void Convert()

{

    string fileName = @"Original.WAV";

    IntPtr formatNew = AudioCompressionManager.GetPcmFormat(2, 16, 44100);

    string fileNameNew = fileName + ".Convert.Wav";

    for (int i = 0; i < 100; i++)

    {

        WaveReader wr = new WaveReader(File.OpenRead(fileName));

        IntPtr format = wr.ReadFormat();

        byte[] data = wr.ReadData();

        wr.Close();

        byte[] dataNew = AudioCompressionManager.Convert(format, formatNew, data, false);

        WaveWriter ww = new WaveWriter(File.Create(fileNameNew),

            AudioCompressionManager.FormatBytes(formatNew));

        ww.WriteData(dataNew);

        ww.Close();

        fileName = fileNameNew;

        //Previous format

        formatNew = format;

    }

}


Fortunately, Alvas.Audio library has AudioCompression.Resample method. It is a wrapper over Resampler DMO object.
If we rewrite the code above using AudioCompression.Resample method, we get much better sound quality.


private void Resample()

{

    string fileName = @"Original.WAV";

    IntPtr formatNew = AudioCompressionManager.GetPcmFormat(2, 16, 44100);

    string fileNameNew = fileName + ".Resample.Wav";

    for (int i = 0; i < 100; i++)

    {

        WaveReader wr = new WaveReader(File.OpenRead(fileName));

        IntPtr format = wr.ReadFormat();

        byte[] data = wr.ReadData();

        wr.Close();

        byte[] dataNew = AudioCompressionManager.Resample(format, data, formatNew);

        WaveWriter ww = new WaveWriter(File.Create(fileNameNew),

            AudioCompressionManager.FormatBytes(formatNew));

        ww.WriteData(dataNew);

        ww.Close();

        fileName = fileNameNew;

        //Previous format

        formatNew = format;

    }

}


You can compare the sound of these 3 files.


As a bonus AudioCompression.Resample method can encode and decode the PCM 24 and 32 bit, more than 2 channels, and also 32-bit IEEE Float audio format.


Summary: For encode and decode a compressed format to PCM AudioCompression.Convert fits perfectly, but for resampling use AudioCompression.Resample method.

No comments:

Post a Comment