1

I'm task with analyzing a wav audio file (filtering, FFT, etc.) in C#. Currently I'm stuck trying to properly convert the bytes to double in order to plot the audio signal of the waveform with scottplot, I have tried using Naudio library but didn't find any success with reading the audio data and plotting it, ended up corrupting my project. the code below is where I read the wav byte into an array and convert it to a double array to plot the signal using scottplot which is not working, I'm using windows forms app(.NET core)

        byte[] wavData = File.ReadAllBytes(@"C:\Users\me\Documents\africa-song.wav");
        double[] values = new double[wavData.Length / 8];
        Buffer.BlockCopy(wavData, 0, values, 0, values.Length * 8);
        formsPlot1.plt.PlotSignal(values, 44100);

if there's a better library I can use or a work around to achieve this, would be really appreciated

kat N
  • 81
  • 2
  • 11
  • You are missing some key information... Is it mono? stereo? There is a good chance it's not `double`, but instead `float`. If it is floating point, you just map from `-1.0` to `1.0`. If it's `short` values, then it's `-32535` to `32536`. Also, if it's a WAV, then there is a header on the file you have to read in which will tell you all these details. – Andy Nov 10 '20 at 23:52
  • You should google this. There is multitudes of info on it. For example: https://stackoverflow.com/questions/8754111/how-to-read-the-data-in-a-wav-file-to-an-array – Andy Nov 10 '20 at 23:54
  • I would strongly recommend not cluttering your project with tonnes of external libraries when Winforms already has inbuilt features to handle graph plotting with ease. – D J Nov 11 '20 at 06:21

1 Answers1

1

Read Values from a WAV File with NAudio

You could read bytes right out of the WAV file, but this isn't always easy because different WAV files have differently sized headers so you don't always know where the first data byte is located. You also have to read and interpret the header to learn what the data format is (number of bytes per sample, whether it's floating point or not, etc) and how many channels there are.

A simpler way to read values from a WAV file is using NAudio. I use this method to convert values from any WAV file data into a double array:

static (double[] audio, int sampleRate) ReadWav(string filePath)
{
    using var afr = new NAudio.Wave.AudioFileReader(filePath);
    int sampleRate = afr.WaveFormat.SampleRate;
    int sampleCount = (int)(afr.Length / afr.WaveFormat.BitsPerSample / 8);
    int channelCount = afr.WaveFormat.Channels;
    var audio = new List<double>(sampleCount);
    var buffer = new float[sampleRate * channelCount];
    int samplesRead = 0;
    while ((samplesRead = afr.Read(buffer, 0, buffer.Length)) > 0)
        audio.AddRange(buffer.Take(samplesRead).Select(x => (double)x));
    return (audio.ToArray(), sampleRate);
}

Plot Values with ScottPlot

Unlike the built-in graphing libraries, ScottPlot allows mouse-interactive pan and zoom for datasets with millions of points, so even if your audio file is an hour long you can easily display it. It looks like you got pretty close with your original code!

(double[] audio, int sampleRate) = ReadWav("demo.wav");

formsPlot1.plt.PlotSignal(audio, sampleRate);
formsPlot1.plt.Title("WAV File Data");
formsPlot1.plt.XLabel("Time (seconds)");
formsPlot1.plt.YLabel("Audio Value");
formsPlot1.plt.AxisAuto(0);
formsPlot1.Render();

enter image description here

SWHarden
  • 136
  • 8