javascript pitch shift with time stretch

*爱你&永不变心* 提交于 2019-11-28 11:24:45

I want to pitch shift audio as well, and after ages I found this.
I also re-formatted the code to make it easier to use for myself (you will need to replace "decode-audio-data/viper.ogg" with your own WAV or OGG filename.):

<script>
function playSound(file, speed=1, pitchShift=1, loop=false, autoplay=true) {
    /*
    Use the play() method to start the audio. if pitchShift is true
    use the stop() method to stop the audio and destroy the object.
    If pitchShift is false use the pause() method to pause and set
    the attribute currentTime to 0 to reset the time.
    */
    if(pitchShift) {
        /*
        After weeks of searching, I have finally found a way to pitch shift audio.
        Thank you Mozilla.
        2018/03/31:
            https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/playbackRate
            https://github.com/mdn/webaudio-examples/tree/master/decode-audio-data
            https://www.w3schools.com/jsref/prop_audio_loop.asp
        Original comments:
            use XHR to load an audio track, and
            decodeAudioData to decode it and stick it in a buffer.
            Then we put the buffer into the source
        */
        audioCtx = new (window.AudioContext || window.webkitAudioContext)();
        source = audioCtx.createBufferSource();
        request = new XMLHttpRequest();

        request.open('GET', file, true);

        request.responseType = 'arraybuffer';


        request.onload = function() {
            var audioData = request.response;

        audioCtx.decodeAudioData(audioData, function(buffer) {
            myBuffer = buffer;
            songLength = buffer.duration;
            source.buffer = myBuffer;
            source.playbackRate.value = speed;
            source.connect(audioCtx.destination);
            source.loop = loop;
        },

        function(e){"Error with decoding audio data" + e.error});

        }

        request.send();
        source.play=source.start
    } else {
        source=new Audio(file)
        source.playbackRate=speed
        source.loop=loop
    }
    if(autoplay) {
        source.play()
    }
    return source
}
var source
function play() {
    source=playSound('decode-audio-data/viper.ogg', pitch=2);
}

function stop() {
    source.stop(0);
    document.getElementById('play').href=''
    document.getElementById('play').innerHTML='Refresh to play again'
}
</script>
<a id="play" href="#" onclick="play()">Play</a> | <a href="#" onclick="stop()">Stop</a>

you can set the mozPreservesPitch property to false to change the pitch of an element or soundfile with Firefox. webkitPreservesPitch is supposed to work with webkit browsers but note that "this API is not yet standardized" ...

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

This worked for me:

var soundPlayer = new Audio();

function playLowerNote() {
    soundPlayer.src = "piano.mp3";
    soundPlayer.mozPreservesPitch = false;
    soundPlayer.playbackRate = 0.5;
    soundPlayer.play();
}

playLowerNote();

Still looking myself for a better way to loop.

Some points, when you said I tried myAudio.playbackRate = 0.5; we are talking about Web Audio API ?

if yes, listen again the pitch as well as the duration of the sample will be affected.

if no, probably that are you using a native html5 function, if you want keep the original speed and change the pitch one way is after change the speed you apply some type of interpolation try linear interpolation with same factor used to stretch your audio. If you need change speed and pitch just apply interpolation without change the speed (in original sound), this can be equivalent to play your audio in a different sample rate Web Audio API can do it.

The code pitchshift.js is a port of the code from Stephan Bernsee to javascript (this change the pitch and keep the speed untouchable), you need call this function at every chunk audio, so first you need do an function that decode your audio file in short int or float.

Hey your web audio API seems to work now for sine waves at least , will learn how to use samples too soon https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API info from here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!