Search code examples
javascripthtml5-audiomicrosoft-edge

resampling audio in Microsoft Edge since copyToChannel is not supported


I'm attempting to resample some audio. I have a function that works in Chrome and Firefox, but it crashes in Edge on the statement

audioBuffer.copyToChannel(sampleArray,0,0);

saying that copyToChannel is not defined. That is curious, because the Microsoft documentation specifically defines it: https://dev.windows.com/en-us/microsoft-edge/platform/documentation/apireference/interfaces/audiobuffer/

Anyway, I'm looking for a workaround. Inspecting the audioBuffer object in the developer tools didn't yield any clues for me.

Thanks!

Here is my code:

function reSample(sampleArray, targetSampleRate, onComplete) {
    // sampleArray is a Float32Array
    // targetSampleRate is an int (22050 in this case)
    // onComplete is called with the new buffer when the operation is complete
    var audioCtx = new window.AudioContext();

    var audioBuffer = audioCtx.createBuffer(1, sampleArray.length, audioCtx.sampleRate);
    audioBuffer.copyToChannel(sampleArray,0,0); // Not supported by Microsoft Edge 12, evidently.

    var channel = audioBuffer.numberOfChannels;
    var samples = audioBuffer.length * targetSampleRate / audioBuffer.sampleRate;

    var offlineContext = new window.OfflineAudioContext(channel, samples, targetSampleRate);
    var bufferSource = offlineContext.createBufferSource();
    bufferSource.buffer = audioBuffer;

    bufferSource.connect(offlineContext.destination);
    bufferSource.start(0);
    offlineContext.startRendering().then(function(renderedBuffer){
        onComplete(renderedBuffer);
    });
}

Solution

  • I got this working with Edge:

        const offlineCtx = new OfflineAudioContext(sourceBuffer.numberOfChannels, sourceBuffer.duration *
          this.sampleRate, this.sampleRate);
        const cloneBuffer = offlineCtx.createBuffer(sourceBuffer.numberOfChannels, sourceBuffer.length, sourceBuffer.sampleRate);
        cloneBuffer.copyToChannel(sourceBuffer.getChannelData(0), 0);
        const source = offlineCtx.createBufferSource();
        source.buffer = cloneBuffer;
        offlineCtx.oncomplete = (e) => {
          const left = e.renderedBuffer.getChannelData(0);
          this.onAudioProcess(this.float32ToInt16(left, left.length), e.renderedBuffer.duration * 1000);
        };
        source.connect(offlineCtx.destination);
        source.start(0);
        offlineCtx.startRendering();
      }