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

Stretcher example does not work in Firefox and Edge #1307

Closed
infernocloud opened this issue Jan 22, 2018 · 8 comments
Closed

Stretcher example does not work in Firefox and Edge #1307

infernocloud opened this issue Jan 22, 2018 · 8 comments

Comments

@infernocloud
Copy link

infernocloud commented Jan 22, 2018

Wavesurfer.js version(s):

1.4.0 and 2.0.2

Browser version(s):

OS: Windows 10
Firefox 58.0 (64-bit)
Microsoft Edge 40.15063.674.0

Code needed to reproduce the issue:

The example located at http://wavesurfer-js.org/example/stretcher/
https://github.com/katspaugh/wavesurfer.js/tree/master/example/stretcher

Use behaviour needed to reproduce the issue:

Click play and then change the playback speed to anything besides 100%. The audio will no longer be heard on Firefox and Edge. Setting speed back to 100% will continue playing the audio.

On Chrome, adjusting the speed does so correctly and the audio plays.

@thijstriemstra
Copy link
Contributor

You're using an old version (1.4.0). Can you reproduce this with the latest version?

@infernocloud
Copy link
Author

The wavesurfer example still uses 1.4.0. I haven't had a chance to look into what changes are necessary to move from v1 to v2 yet.

@thijstriemstra
Copy link
Contributor

@infernocloud the example in the repository uses 2.x, not 1.4.0

@infernocloud
Copy link
Author

Ok, I can confirm now that the problem still exists with 2.0.2. I cloned the repo, built the files, ran the development server, and went to the stretcher example and it performs the same as 1.4.0 - no audio when playback speed is anything but 100% (in Firefox and Edge).

@infernocloud
Copy link
Author

It looks like the issue may be with the Soundtouch library chosen to maintain pitch or how it works with Wavesurfer.

For possible reference, I found some other libraries that change tempo correctly cross-browser:
https://github.com/echo66/OLA-TS.js (example: http://echo66.github.io/demos/OLA-TS.js/#)
https://github.com/echo66/PhaseVocoderJS (example: http://echo66.github.io/demos/PhaseVocoder.js/)

Maybe one of those can be swapped in for Soundtouch. I'm very unfamiliar with the WebAudio API so I'm not sure if these would work the same as a drop in replacement.

@thijstriemstra
Copy link
Contributor

@infernocloud replacing soundtouch with one of these libs sounds like a plan if it's cross-browser. Pull requests are welcome.

@clndwhr
Copy link

clndwhr commented Feb 25, 2019

I was able to get this to work utilizing the soundtouchjs library on github that was refactored for ES2015 development. This is setup in a VueJS environment and is not clean or optimized yet, but will be shortly.

I have confirmed this to work in both Chrome 72.0.3626.109 and FF65.0.1

import { SoundTouch, SimpleFilter, getWebAudioNode } from 'soundtouchjs/dist/soundtouch,js'

let this_ = this;
  this.wavesurfer.on('ready', function() {
    let context = new AudioContext();
    let sampleRate = 44100;
    let st = new SoundTouch(sampleRate);
    st.tempo = 1.0;
    this_.wavesurfer.backend.source.buffer.extract = function(
      target,
      numFrames,
      position
    ) {
      var l = this_.wavesurfer.backend.source.buffer.getChannelData(0),
        r = this_.wavesurfer.backend.source.buffer.getChannelData(1);
      for (var i = 0; i < numFrames; i++) {
        target[i * 2] = l[i + position];
        target[i * 2 + 1] = r[i + position];
      }
      return Math.min(numFrames, l.length - position);
    };
    let filter = new SimpleFilter(
      this_.wavesurfer.backend.source.buffer,
      st
    );
    let node = getWebAudioNode(this_.wavesurfer.backend.ac, filter);
    this_.wavesurfer.backend.setFilter(node);
    this_.wavesurfer.backend.filters[0].disconnect();
    this_.wavesurfer.on('play', function() {
      let semitones = 1;
      let frequencyFactor = Math.pow(2, semitones / 12);
      st.pitch = frequencyFactor;
      st.tempo = this_.rateValue / 100;
      node.connect(this_.wavesurfer.backend.ac.destination);
    });
    this_.wavesurfer.on('pause', function() {
      node.disconnect();
    });
  });

@rjl20
Copy link

rjl20 commented Apr 8, 2020

I was able to get this to work utilizing the soundtouchjs library on github that was refactored for ES2015 development. This is setup in a VueJS environment and is not clean or optimized yet, but will be shortly.

I'm trying to get this working myself, and while I can get your code to work with some modifications, I think the soundtouch node starts playing immediately, even if it's not connected to a destination, and the only effect play/pause has is on whether the wavesurfer cursor is moving and whether the playback is routing through the wavesurfer destination or into the void.

My not-quite-working example: https://slowerthandirt.org/wavesurfer.js-3.3.1/example/stretcher-new/

Do you have a working example hosted anywhere that I could check out? Thanks!

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

No branches or pull requests

5 participants