1
$\begingroup$

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:

enter image description here

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):

enter image description here

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 < waveForm.length ; i++){
      for(int j =0 ; j < 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.

$\endgroup$
  • $\begingroup$ Welcome to DSP.SE! There's nothing obviously wrong with what you're doing as far as I can see. Is the plot of your signal the whole signal as in the Audacity plot? Are you sure you have the length of the signal correct? Can the data array used to store it be set to a longer length than the actual data? Have you looked at the values of waveForm[i][j] ? Are they in fact close to zero? $\endgroup$ – Peter K. Sep 14 '15 at 20:54
  • $\begingroup$ Is [j] the channel index (left/right)? If so, why are you drawing in the y-direction from one channel's per-sample amplitude to the next channel? $\endgroup$ – panthyon Sep 14 '15 at 21:05
  • $\begingroup$ @PeterK. Thanks for the warm welcome! As far as I can tell I have the correct signal size, I'm using [Minim](code.compartmental.net/minim ) to load the file into an AudioSample Object and getting the channels from that. The channels are accessible in a float[] object simply by float[] leftChannel = myAudioSample.left, but I have been copying the samples into a 2d array for rendering as I'm new to audio signal processing and was working off a sample which did the same. I'm sure that I can set the data array to a longer length if it will get me the desired results. $\endgroup$ – Kyle Sep 14 '15 at 23:29
  • $\begingroup$ @AnthonyParks No, each channel is in its own 2d array and rendered using the code snippet above. They are separate :) $\endgroup$ – Kyle Sep 14 '15 at 23:30
  • $\begingroup$ are you concerned about the trailing silence?? $\endgroup$ – ruoho ruotsi Sep 15 '15 at 3:05
2
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ Just adding that the specific issue was the inaccuracy of drawStep due to the size limitations of a float. Changing drawStep to a double resolved the issue. $\endgroup$ – Kyle Sep 15 '15 at 19:19
0
$\begingroup$

mp3 is a block-based encoding format. Thus a signal may have to be extended by zero padding to fill the last block of compressed data.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.