katspaugh / wavesurfer.js

Audio waveform player
https://wavesurfer.xyz
BSD 3-Clause "New" or "Revised" License
8.8k stars 1.63k forks source link

timeline plugin: negative offset rendering issue #2463

Closed othmar52 closed 2 years ago

othmar52 commented 2 years ago

First of all: thank you for this fantastic library
So cool that nearly all of my special needs can be solved by configuration - i never would have expected such a great flexibility!!!

Unfortunately i found a side effect that may be a kind of bug caused by "over-configuration" :D
Currently i am doing some prototyping for a DJ-like web application for playing acapellas for synth jam sessions with precise control for pitching & nudging.

Within this app i need a beat-grid indicating quarter notes and 8 bars as the "longest" unit. It was dead easy to achieve this with the timeline plugin. Thanks to the options.offset i can exactly place the 8 bars to the downbeat.

Approach 1: timeline.options.offset = positive float

This has the side effect that there is no rendering of the beat-grid between 0 and this configured second
image

Approach 2: timeline.options.offset = negative float

My idea was to subtract the 8 bars duration from the downbeat to get rid of the missing rendering at the begin of the waveform.
This basically works but now i have no rendering of the beat-grid at the end of the waveform.

image
Then i found timeline.options.duration which overrides the duration. but adding this negative offest to the duration messes up the resolution of the beat-grid

So here is my question:
Can you confirm that this very special need/usecase can't be solved by configuration?
Thank you

othmar52 commented 2 years ago

@thijstriemstra in the meantime i answered the question myself: it's not possible to solve this by configuration

so now i have created a BeatGridPlugin that extends the TimelinePlugin which basically adds only 3 lines of code to the Timeline plugin:

--- wavesurfer.js/src/plugin/timeline/index.js  2022-03-04 06:39:48.473576216 +0100
+++ wavesurfer.js.beatgrid/src/plugin/timeline/index.js 2022-03-04 06:42:08.012582564 +0100
@@ -371,7 +371,13 @@
         // build an array of position data with index, second and pixel data,
         // this is then used multiple times below
         const positioning = [];
-        for (i = 0; i < totalSeconds / timeInterval; i++) {
+
+        // render until end in case we have a negative offset
+        const renderSeconds = (this.params.offset < 0)
+            ? totalSeconds - this.params.offset
+            : totalSeconds;
+
+        for (i = 0; i < renderSeconds / timeInterval; i++) {
             positioning.push([i, curSeconds, curPixel]);
             curSeconds += timeInterval;
             curPixel += pixelsPerSecond * timeInterval;

Does it make sense to add this change to the TimelinePlugin?
Case yes, i can create a PR

thijstriemstra commented 2 years ago

Case yes, i can create a PR

Sounds good.