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

Wavesurfer loading precomputed peaks is broken (at least for this test file) #3691

Closed
ajrisi opened this issue May 9, 2024 · 2 comments · Fixed by #3692
Closed

Wavesurfer loading precomputed peaks is broken (at least for this test file) #3691

ajrisi opened this issue May 9, 2024 · 2 comments · Fixed by #3692
Labels

Comments

@ajrisi
Copy link

ajrisi commented May 9, 2024

Bug description

Providing peaks exported from the exact same audio file results in a short waveform. It seems sample dependent?

Environment

  • Browser: Chrome

Minimal code snippet

var aud = document.querySelector('#aud');
var peaks = undefined;

const wavesurfer = WaveSurfer.create({
container: '#wavesurf',
waveColor: '#4F4A85',
progressColor: '#383351',
media: aud,
backend: 'MediaElement',
width:"100%",
})

wavesurfer.on('click', () => {
wavesurfer.play()
})

wavesurfer.on('ready', () => {
let peaks = wavesurfer.exportPeaks();

let wavesurfer2 = WaveSurfer.create({
container: '#wavesurf2',
waveColor: '#4F4A85',
progressColor: '#383351',
media: aud,
peaks: peaks,
backend: 'MediaElement',
interact: false,
duration: aud.duration,
width: "100%",
})
})

Expected result

I expect the same waveform to show in the 2nd wave as is in the first - but it shows a shorter one! This same result happens when I cache pre-computed waves, etc. I should see the same waveform in the 2nd view as I do in the 1st.

I included my audio test file - its an OGG but github wanted me to name it something else, so its door-knocking.LOG. Rename to ogg to test.

Obtained result

I got a different waveform in the 2nd version and the first. This almost looks like a floating point error or some other propagating error when exporting the peaks.

As an experiment, I used getDecodedData().getChannelData(0) directly for peaks instead, and that works as you'd expect (showing the same view as the original).

Screenshots

Screen Shot 2024-05-09 at 8 24 41 AM
door-knocking.LOG

@ajrisi ajrisi added the bug label May 9, 2024
@ajrisi
Copy link
Author

ajrisi commented May 9, 2024

Fixed it for myself, but I'm a little busy to do a push onto your repo. The sample calculation was losing up to a half second of audio when exporting peaks. I just had to patch your exportPeaks to calculate its sample window start and end without accumulating a precision error.

  /** Get decoded peaks */
  public exportPeaks({ channels = 2, maxLength = 8000, precision = 10_000 } = {}): Array<number[]> {
    if (!this.decodedData) {
      throw new Error('The audio has not been decoded yet')
    }
    const maxChannels = Math.min(channels, this.decodedData.numberOfChannels)
    const peaks = []
    for (let i = 0; i < maxChannels; i++) {
      const channel = this.decodedData.getChannelData(i)
      const data = []
      const sampleSize = (channel.length / maxLength)
      for (let i = 0; i < maxLength; i++) {
        const sample = channel.slice(Math.floor(i * sampleSize), Math.ceil((i + 1) * sampleSize))
        let max = 0
        for (let x = 0; x < sample.length; x++) {
          const n = sample[x]
          if (Math.abs(n) > Math.abs(max)) max = n
        }
        data.push(Math.round(max * precision) / precision)
      }
      peaks.push(data)
    }
    return peaks
  }
@katspaugh
Copy link
Owner

Thanks @ajrisi! I’ll make sure to push the fix 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 participants