NAudio - Get Wav Peak Data as Int16 Values

608 views Asked by At

I want to use NAudio to extract the peak values of wav audio files like the audiowaveform library provides. Which is an array of short values like:

{
  "version": 2,
  "channels": 2,
  "sample_rate": 48000,
  "samples_per_pixel": 512,
  "bits": 8,
  "length": 3,
  "data": [-65,63,-66,64,-40,41,-39,45,-55,43,-55,44]
}

https://github.com/bbc/audiowaveform/blob/master/doc/DataFormat.md

I saw that NAudio has a built-in WaveformRenderer that outputs png images, but I just need the raw peak data. Built-in NAudio classes like MaxPeakProvider (which is initialized with waveReader.ToSampleProvider()) etc works with floats, I need them as short values. Is it possible?

Edit after @Blindy's response

I have this piece of code, converting peak data to shorts, but it produces slightly wrong values when comparing with the output of audiowaveform. What might be the problem? I guess there is a data type conversion or rounding error?

        var waveReader = new WaveFileReader(openFileDialog1.FileName);
        var wave = new WaveChannel32(waveReader);

        var peakProvider = new MaxPeakProvider();

        int bytesPerSample = (waveReader.WaveFormat.BitsPerSample / 8);
        var samples = waveReader.Length / bytesPerSample;

        int pixelsPerPeak = 1;
        int spacerPixels = 0;

        var samplesPerPixel = 32; 
        var stepSize = pixelsPerPeak + spacerPixels;
        peakProvider.Init(waveReader.ToSampleProvider(), samplesPerPixel * stepSize);
        List<short> resultValuesAsShort = new List<short>();
        List<float> resultValuesAsFloat= new List<float>();

        PeakInfo currentPeak = null;
        for (int i = 0; i < samples / samplesPerPixel; i++)
        {
            currentPeak = peakProvider.GetNextPeak();

            resultValuesAsShort.Add((short)(currentPeak.Min * short.MaxValue));
            resultValuesAsShort.Add((short)(currentPeak.Max * short.MaxValue));

            //resultValuesAsFloat.Add(currentPeak.Min);
            //resultValuesAsFloat.Add(currentPeak.Max);
        }

Here are the results comparison:

enter image description here

Edit2: Examining further, I noticed that it is generating quite different results for the latter values than audiowaveform library and I don't have any idea for the reason:

enter image description here

1

There are 1 answers

0
Blindy On

MaxPeakProvider [...] works with floats, I need them as short values

NAudio in general works with floats, it's just how it was designed. To get the 2-byte short representation, multiply each float by short.MaxValue (the floats are in the [-1..1] range).