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 .
Mark heath
source share