Ashish
Ashish

Reputation: 8529

Plotting waveform of the .wav file

I wanted to plot the wave-form of the .wav file for the specific plotting width.

Which method should I use to display correct waveform plot ?

Any Suggestions , tutorial , links are welcomed....

Upvotes: 10

Views: 9427

Answers (4)

shabtronic
shabtronic

Reputation: 31

Either use RMS, BlockSize depends on how far you are zoomed in!

float RMS = 0;
for (int a = 0; a < BlockSize; a++)
{
    RMS += Samples[a]*Samples[a];
}
RMS = sqrt(RMS/BlockSize);

or Min/Max (this is what cool edit/Audtion Uses)

float Max = -10000000;
float Min = 1000000;
for (int a = 0; a < BlockSize; a++)
{
    if (Samples[a] > Max) Max = Samples[a];
    if (Samples[a] < Min) Min = Samples[a];
}

Upvotes: 3

Dhruv
Dhruv

Reputation: 962

What exactly do you mean by a waveform? Are you trying to plot the level of the frequency components in the signal a.k.a the spectrum, most commonly seen in musci visualizers, car stereos, boomboxes? If so, you should use the Fast Fourier Transform. FFT is a standard technique to split a time domain signal into its individual frequencies. There are tons of good FFT library routines available.

In C++, you can use the openFrameworks library to set up a music player for wav, extract the FFT and draw it.

You can also use Processing with the Minim library to do the same. I have tried it and it is pretty straightforward.

Processing even has support for OpenGL and it is a snap to use.

Upvotes: 0

kauppi
kauppi

Reputation: 17406

Basic algorithm:

  1. Find number of samples to fit into draw-window
  2. Determine how many samples should be presented by each pixel
  3. Calculate RMS (or peak) value for each pixel from a sample block. Averaging does not work for audio signals.
  4. Draw the values.

Let's assume that n(number of samples)=44100, w(width)=100 pixels:

then each pixel should represent 44100/100 == 441 samples (blocksize)

for (x = 0; x < w; x++)
    draw_pixel(x_offset + x,
               y_baseline - rms(&mono_samples[x * blocksize], blocksize));

Stuff to try for different visual appear:

  • rms vs max value from block
  • overlapping blocks (blocksize x but advance x/2 for each pixel etc)

Downsampling would not probably work as you would lose peak information.

Upvotes: 17

Jerry Coffin
Jerry Coffin

Reputation: 490048

Almost any kind of plotting is platform specific. That said, .wav files are most commonly used on Windows, so it's probably a fair guess that you're interested primarily (or exclusively) in code for Windows as well. In this case, it mostly depends on your speed requirements. If you want a fairly static display, you can just draw with MoveTo and (mostly) LineTo. If that's not fast enough, you can gain a little speed by using something like PolyLine.

If you want it substantially faster, chances are that your best bet is to use something like OpenGL or DirectX graphics. Either of these does the majority of real work on the graphics card. Given that you're talking about drawing a graph of sound waves, even a low-end graphics card with little or no work on optimizing the drawing will probably keep up quite easily with almost anything you're likely to throw at it.

Edit: As far as reading the .wav file itself goes, the format is pretty simple. Most .wav files are uncompressed PCM samples, so drawing them is a simple matter of reading the headers to figure out the sample size and number of channels, then scaling the data to fit in your window.

Edit2: You have a couple of choices for handling left and right channels. One is to draw them in two separate plots, typically one above the other. Another is to draw them superimposed, but in different colors. Which is more suitable depends on what you're trying to accomplish -- if it's mostly to look cool, a superimposed, multi-color plot will probably work nicely. If you want to allow the user to really examine what's there in detail, you'll probably want two separate plots.

Upvotes: 2

Related Questions