Wav analysis and graph drawing

I am trying to print a wave from a wav file, but I kind of lost the way how long I have to take for the sample.

this is what I would like to archive (without colors): Music wav

so for reading in my data i use the following code:

// first we need to read our wav file, so we can get our info: byte[] wav = File.ReadAllBytes(filename); // then we are going to get our file info info.NumChannnels = wav[22]; info.SampleRate = bytesToInt(wav[24], wav[25]); // nr of samples is the length - the 44 bytes that where needed for the offset int samples = (wav.Length - 44) / 2; // if there are 2 channels, we need to devide the nr of sample in 2 if (info.NumChannnels == 2) samples /= 2; // create the array leftChannel = new List<float>(); if (info.NumChannnels == 2) rightChannel = new List<float>(); else rightChannel = null; int pos = 44; // start of data chunk for (int i = 0; i < samples; i++) { leftChannel.Add(bytesToFloat(wav[pos], wav[pos + 1])); pos += 2; if (info.NumChannnels == 2) { rightChannel.Add(bytesToFloat(wav[pos], wav[pos + 1])); pos += 2; } } 

BytesToFloat = Converts 2 bytes to a float between -1 and 1

So now I have 2 lists of data, but now how do I how many numbers should I take to create 1 row?

what bothers me more: when you play a song, you can see the following data in most music players, this is, in my opinion, a representation of 1 sample. enter image description here

but how do you know the value of each of these bars and how many bars in the sample

+8
c # graph wav
source share
1 answer

Your question is about two different audio renderings. To draw a waveform, the code you posted is close to being ready to draw, but you add one entry to the sample in your list. Because audio is often 44100 samples per second, a waveform for a 3-minute song will require nearly 8 million pixels per second. So what you do is their package. For each, say 4410 pixels (i.e. 100 ms), find the one that has the highest and lowest values, and then use this to draw a line. in fact, you can usually get away by simply finding the maximum value of Abs and plotting the symmetrical waveform.

Here is some code to draw the main WaveForm audio file in WPF, using NAudio to make it easy to access samples (it can make WAV or MP3 files). I have not included any separation of the left and right channels, but it is quite easy to add:

 var window = new Window(); var canvas = new Canvas(); using(var reader = new AudioFileReader(file)) { var samples = reader.Length / (reader.WaveFormat.Channels * reader.WaveFormat.BitsPerSample / 8); var f = 0.0f; var max = 0.0f; // waveform will be a maximum of 4000 pixels wide: var batch = (int)Math.Max(40, samples / 4000); var mid = 100; var yScale = 100; float[] buffer = new float[batch]; int read; var xPos = 0; while((read = reader.Read(buffer,0,batch)) == batch) { for(int n = 0; n < read; n++) { max = Math.Max(Math.Abs(buffer[n]), max); } var line = new Line(); line.X1 = xPos; line.X2 = xPos; line.Y1 = mid + (max * yScale); line.Y2 = mid - (max * yScale); line.StrokeThickness = 1; line.Stroke = Brushes.DarkGray; canvas.Children.Add(line); max = 0; xPos++; } canvas.Width = xPos; canvas.Height = mid * 2; } window.Height = 260; var scrollViewer = new ScrollViewer(); scrollViewer.Content = canvas; scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; window.Content = scrollViewer; window.ShowDialog(); 

The second visualization is sometimes called a spectrogram or spectrum analyzer. It does not represent 1 sample, but represents the frequencies present in the block of samples. To get this information, you need to pass your samples through the fast Fourier transform (FFT). Usually you go through blocks with 1024 samples (this should be power 2). Fortunately, FFT can be difficult to work if you are new to DSP, as you need to learn to do a few things:

  • apply window function
  • receive audio in the correct input format (many FFTs expect input as complex numbers)
  • determine which bin numbers correspond to the frequency
  • Find the size of each hopper and convert it to decibel.

You can find more information on each of these topics here at StackOverflow. I wrote a little about how you can use FFT in C # in this article .

+10
source share

All Articles