Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error of time conversion #552

Open
jason30704 opened this issue Oct 18, 2024 · 3 comments
Open

Error of time conversion #552

jason30704 opened this issue Oct 18, 2024 · 3 comments

Comments

@jason30704
Copy link

Hi @chrisn ,

I try to draw some custom canvases outside peaks, so I need to know how peaks convert position into time. I found two functions (timeToPixelOffset() and pixelOffsetToTime()).

When the zoomview time is greater than about 3 seconds, the conversion using these two methods is accurate, but as long as the zoomview duration is 1 second or even lower, they will have increasing errors.

Is this the current expected situation?

@chrisn
Copy link
Member

chrisn commented Oct 19, 2024

I'm not sure... Would you mind sharing an example, to help me investigate?

@jason30704
Copy link
Author

Hi @chrisn ,
Sorry for replying to you so late.

I found that the root cause of this problem is that when I use the following method to crop the zoomview, it will not be able to perfectly cut to the time interval I want.
(ex: I want to capture 0 ~ 0.52 seconds. But actually what can be seen on the UI may be only 0 ~ 0.48 seconds)

Therefore, when I use pixelOffsetToTime(), there will be an error in the calculation of time. Is my cutting method wrong? Thanks!

image

@chrisn
Copy link
Member

chrisn commented Oct 26, 2024

The waveform is computed based on a number of audio samples per pixel. This is what you set in the zoomLevels option in Peaks.init().

When you call zoomView.setZoom({ duration: seconds }), internally it does this:

const samplesPerPixel = Math.floor(duration * sampleRate / width);

and because samplesPerPixel must be an integer for the waveform calculation which is why we use Math.floor(), you get an approximation.

As an example, let's say sampleRate is 48000, your container width is 500px, and you call zoomView.setZoom({ duration: 0.4 }).

This gives samplesPerPixel as 38, rounded down from 38.4.

Now, 0.4 * 48000 = 19200 samples. At 38 samples per pixel, this gives a waveform length of 506 pixels.

This is just to illustrate the approximation, and this tends to be worse for short durations, as you've found.

I'd like to fix this, to make it more accurate, but it's non-trivial.

Related: bbc/audiowaveform#114 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants