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

feature: preserving pitch when changing tempo (#149) #1157

Closed
wants to merge 84 commits into from

Conversation

katspaugh
Copy link
Owner

@katspaugh katspaugh commented Jul 2, 2017

A first stab at preserving the pitch when changing the playback rate of an audio clip.

Todo:

  • Currently, it makes the audio mono. Ideally, it should keep all channels.

Update:
I went with the solution that @jsphweid suggested. The wavesurfer.js code is unmodified. Soundtouch.js is attached as an external filter.

Basically, the full implementation can be seen here: https://github.com/katspaugh/wavesurfer.js/blob/76da8d6411a593e850bc6dc9c641ded1d5e31645/example/stretcher/app.js

Here's a live demo: http://wavesurfer-js.org/example/stretcher/

mspae and others added 30 commits November 16, 2016 23:13
…862)

* close the audiocontext in the destroy method of the webaudio backend

* ac is only closed in WebAudio destroy function if it was created internally and not passed in as a parameter

* removed WaveSurfer.WebAudio.audioContext caching (and WebAudio.getAudioContext)

* getAudioContext method is back in place, but doesn't cache to WebAudio.audioContext
When running code that uses Wavesurfer under PhantomJS (even if not explicitly testing the Wavesurfer code), the JS interpreter crashes because PhantomJS DOM `<audio>` elements don't have a `load()` method. This change skips that one line if the method doesn't exist.
* Adds an optional 'partialRender' parameter to enable
* Calculates and renders peaks only for current visible waveform
* Keeps track of currently calculated/rendered peaks to avoid
  duplicate calculation and only incremental scroll changes are rendered

Tested all combinations of Canvas/MultiCanvas and Wave/Bars rendering
at various zoom levels.
* fix draw wrong position while playing backward seeking

* fix spelling mistake
add getPlaybackRate method and return playback rate.
…awWave + drawBars without the start and end parameters introduced by peakCache (#945)
* fix getDuration() return value for MediaElement 

change getDuration function in mediaelement.js to return the correct duration length same as WebAudio.

from
        var duration = this.media.duration; // incorrect duration value returned
        console.log preview:
        https://cloud.githubusercontent.com/assets/5193884/22399178/6d26c1fe-e565-11e6-9b13-e6107641666a.png
to
        var duration = this.buffer.duration; // correct duration value returned same as WebAudio
        console.log preview:
        https://cloud.githubusercontent.com/assets/5193884/22393549/7b130096-e4d6-11e6-83ff-4ebb78b9e42f.png

* Update mediaelement.js
Updated the render function to call the new version of the getPeaks and drawPeaks calls which now require start and end parameters.  Fixes flat waveform drawing in minimap plugin.
add check for browser support of AudioContext.close(). This is only supported by Chrome 43+ and FireFox 40+ for now. Edge and other non supported browsers will give an undefined error.

https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/close

// check if browser supports AudioContext.close()
            if(typeof this.ac.close() !== 'undefined'){
                this.ac.close();
            }

fixes #949
* Update wavesurfer.minimap.js

renders the minimap without the need to resize the window.
Changed 

        this.wavesurfer.on('ready', this.render.bind(this));

to 

        this.wavesurfer.on('ready', my.render.bind(this));

* Update wavesurfer.minimap.js

added the fixes for the drawPeaks()

* update my.render to this.render

* add parameter check renderOnLoad

check to see if a parameter called "miniRenderOnLoad" is set to true, if it is render the minimap on load.

* Update wavesurfer.minimap.js

* add space after else

* render minimap on load

will update docs and create example for minimap plugin
- minimap should be initialized within the main wavesurfer ready event.
* create debounce method in util.js

Can be used as follows with a resize event to prevent drawBuffer() from running concurrently when resizing the browser window.
preview:
http://codepen.io/entonbiba/pen/jyKrEz

var responsiveWave = debounce(function() {
  wavesurfer.empty();
  wavesurfer.drawBuffer();
}, 150);

window.addEventListener(‘resize’, responsiveWave);

* create debounce method in util.js

* Update util.js

* create debounce method in util.js, remove spaces
entonbiba and others added 14 commits April 29, 2017 04:46
* add getPeaks background compatibility

* remove space

* add space
timeline plugin: Round to milliseconds
* "for... in" should not be used with arrays. This causes bugs!

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js
* requestAnimationFrame addition to utils.

* Update util.js

* Update util.js

* Update util.js

* Update util.js

* Update util.js
* Wrap drawing in requestAnimationFrame.

Wrap drawing in requestAnimationFrame per #1084.

* Update drawer.canvas.js

* Update drawer.canvas.js

* Update drawer.canvas.js

* Update drawer.canvas.js

* Update drawer.canvas.js
* Listen to and relay play and pause events on media element

* Corrected the 'pause' event label

* removed play and pause emits from respective functions
* Remove pointer events from the left and right sides of the wave and change `zIndex` to 2.

The reasoning behind this is to allow, for example, the region plugin to have a styling such that the regions are below the waves (so that the waves look clearer and not blended with the regions), while still allowing resize events on the regions. Otherwise, the left/right sections of the wave block the resize elements of the regions, since their `zIndex` needs to be necessarily higher to be drawn over the regions.
* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* I have no idea why this failed.

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js
@katspaugh katspaugh changed the title feature: added kali for preserving pitch when changing tempo (#149) feature: preserving pitch when changing tempo (#149) Jul 2, 2017
glebm and others added 4 commits July 2, 2017 20:31
refs #1127

Before #909, calling `drawBuffer` to redraw the wave invoked
`drawer.drawPeaks` which in turn invoked `drawer.setWidth` which
always caused the canvas to be cleared as a side effect of
`drawer.updateSize`.

In #909 `setWidth` was changed to short circuit if the width did not
change. This now causes the waveform to be redrawn on top of the
previous rendition, making the edges of the wave appear less crisp.

This change makes `setWidth`/`setHeight` return a boolean to indicate
whether changes were needed. If not, `drawer.clearWave` is called
manually. So we make sure that the previous wave is always cleared,
but do not perform the possibly performance intensive task of clearing
the canvas twice if it already happened as a side effect of
`setWidth`.
* Join ends of peaks

I'm not entirely sure that the peaks are joined at the ends. When I zoomed all the way in, it seemed that there were gaps...

* Update drawer.multicanvas.js

* Update drawer.multicanvas.js
* fixes safari browser missing buffer when using webaudio

* return correct buffer

* set samples to 4096

* add safari comment
@katspaugh katspaugh force-pushed the preserve-pitch branch 3 times, most recently from 2ba22f0 to 08909fb Compare July 15, 2017 21:10
@katspaugh
Copy link
Owner Author

katspaugh commented Jul 17, 2017

Closing this to create the same PR into the es5 branch. See #1169.

@infernocloud
Copy link

I've filed a bug issue reporting that this example only works in Chrome and audio fails to play in Firefox and Edge while changing the speed. #1307

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

Successfully merging this pull request may close these issues.