Ron Daulagupu
Ron Daulagupu

Reputation: 423

can't fine variable OfflineAudioContext in safari

I am using web audio API to stream audio to my remote server. I am using OfflineAudioContext. The code works fine in chrome and firefox but in safari, it gives the above mentioned error when trying to use OfflineAudioContext. I have tried adding webkit prefix to OfflineAudioContext, then it gives me this error:

SyntaxError: The string did not match the expected pattern.

I have tried adding different values to the OfflineAudioContext constructor but its always giving me the same error.

I went through Mozilla developers page for browser compatibility and I found this :

enter image description here

So, here its mentioned that for OfflineAudioContext constructor the compatibility is unknown for edge and safari. So, is this the reason, why I am not able to use OfflineAudioContext in safari? Is it not supported yet? or Am I doing it wrong? Or Is there another way to solve this in safari?

This is the first time I am using the Web Audio API. So, I hope somebody can clear my doubt if I missed out somewhere. Thank You.

Code of OfflineAudioContext added below:

let sourceAudioBuffer = e.inputBuffer; // directly received by the audioprocess event from the microphone in the browser

let TARGET_SAMPLE_RATE = 16000;
let OfflineAudioContext =
  window.OfflineAudioContext || window.webkitOfflineAudioContext;
let offlineCtx = new OfflineAudioContext(
  sourceAudioBuffer.numberOfChannels,
  sourceAudioBuffer.duration *
    sourceAudioBuffer.numberOfChannels *
    TARGET_SAMPLE_RATE,
  TARGET_SAMPLE_RATE
);

(if more code is needed of the js file to know the problem better. Just comment for it. I will add that but I thought the snippet is enough to understand the problem)

Upvotes: 2

Views: 973

Answers (1)

chrisguttandin
chrisguttandin

Reputation: 9076

It's a bit confusing, but a SyntaxError is what Safari throws if it doesn't like the arguments. And unfortunately Safari doesn't like a wide range of arguments which should normally be supported.

As far as I know Safari only accepts a first parameter from 1 to 10. That's the parameter for numberOfChannels.

The second parameter (the length) just needs to be positive.

The sampleRate can only be a number between 44100 and 96000.

However it is possible to translate all the computations from 16kHz to another sampleRate which then works in Safari. Let's say this is the computation you would like to do at 16kHz:

const oac = new OfflineAudioContext(1, 10, 16000);
const osciallator = oac.createOscillator();

osciallator.frequency.value = 400;

osciallator.connect(oac.destination);
osciallator.start(0);

oac.startRendering()
    .then((renderedBuffer) => {
        console.log(renderedBuffer.sampleRate);
        console.log(renderedBuffer.getChannelData(0));
    });

You can do almost the same at 48kHz. Only the sampleRate will be different but the channelData of the rendered AudioBuffer will be the same.

const oac = new webkitOfflineAudioContext(1, 10, 48000);
const osciallator = oac.createOscillator();

osciallator.frequency.value = 1200;

osciallator.connect(oac.destination);
osciallator.start(0);

oac.oncomplete = (event) => {
    console.log(event.renderedBuffer.sampleRate);
    console.log(event.renderedBuffer.getChannelData(0));
};
oac.startRendering();

Aside: Since I'm the author of standardized-audio-context which is a library that tries to ease out inconsistencies between browser implementations, I have to mention it here. :-) It won't help with the parameter restrictions in Safari, but it will at least throw the expected error if the parameter is out of range.

Also please note that the length is independent of the numberOfChannels. If IfsourceAudioBuffer.duration in your example is the duration in seconds, then you just have to multiply it with the TARGET_SAMPLE_RATE to get the desired length.

Upvotes: 1

Related Questions