How can I accurately represent an mp3's wave form in respects to time? I'm trying to programmatically plot a sound wave that I have placed in a 2d array, however, I cannot consistently get the sound wave to reach the end of the window. For example, when you load a sound in audacity, you get this:



In contrast, when I load a sound into my program I will often get something like this (red is the play head that moves at speed of one blue tick mark every second. The Green line is the end of the song in seconds):



As you can see, I can plot the complete wave form, but it does not sync up with the end of the song. Oddly enough, there are times during this song that the wave form is an accurate representation of what's being played. There are also a handful of songs that do not seem to have this issue (but more than a handful of others that do have this issue). 

This is how I'm drawing the wave form: 

    float drawStep = songLengthInSeconds / numberOfSamples;
    for(int i = 0; i &lt; waveForm.length ; i++){
      for(int j =0 ; j &lt; waveForm.length - 1; j++){
         renderer.line(x, waveForm[i][j], x + drawStep, waveForm[i][j+1]);

         x+= drawStep;    
}

}


The renderer.line method signature is 

renderer.line(beginningX, beginningY, endingX, endingY);


And I get the number of samples by just adding all of the waveForm[x].length together. 

Finally, the top and bottom wave forms in the picture below are being drawn differently which is why they don't match. The bottom wave form is the one that is represented by the code above. 

I've been fighting with this for a couple weeks now and would be very grateful if anyone has any suggestions that would push me in the right direction.
Storing the samples in a square array is weird. You can't represent all song lengths (in samples) as squares of integer array dimensions but yet the complete array is being plotted.

Your code seems to miss one x+=drawStep when transitioning between rows of the array. Neither does it "connect the dots" across the rows. If the last sample of each row is duplicated at the next row then it's fine as a row represents only waveForm.length - 1 samples.

Additionally, it just might be that x and drawStep are not accurate enough. Try making both doubles instead of floats. If there is an improvement but not yet good enough, calculate x by multiplication before each j loop. You should typecast songLengthInSeconds to double too.