Web audio api 5.1 surround example not working in firefox - javascript

I've been playing a lott lately with the Web Audio Api on both Firefox and Chrome. A few days ago i started to experiment with a surround set. When i was trying surround audio in the web audio api i came to notice that my example works fine in Chrome v59 but not in Firefox v54.
// create web audio api context
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
audioCtx.destination.channelInterpretation = 'discrete';
audioCtx.destination.channelCountMode = 'explicit';
audioCtx.destination.channelCount = 6;
var oscillators = [];
var merger = audioCtx.createChannelMerger(6);
console.log(audioCtx.destination, merger);
//merger.channelInterpretation = 'discrete';
//merger.channelCountMode = 'explicit';
//merger.channelCount = 6;
var addOscilator = function(channel, frequency) {
var oscillator = audioCtx.createOscillator();
oscillator.frequency.value = frequency; // value in hertz
oscillator.connect(merger,0,channel);
oscillator.start();
oscillators.push(oscillator);
};
addOscilator(0,300);
addOscilator(1,500);
addOscilator(2,700);
addOscilator(3,900);
addOscilator(4,1100);
addOscilator(5,1300);
merger.connect(audioCtx.destination);
When i do a console log of the audio context destination the maxChannelCount is 6 and the channelCount is also 6 but i still get only output on the left and right channel. these channels play all the output. (So its downmixed from 5.1 to stereo)
I also tried playing a 5.1 surround audiofile in a html-audio element in firefox and this worked fine. In other words, the browser is reconizing and able to output o the surround set.
Am i doing something wrong in this example or is this a feature not yet implemented by firefox(because the web audio api is still a draft)? I can't find any reports like this so i think its a fault on my side, but the inconsitency between the browsers makes me doubt.
Thanks in advance

After some deeper research it turned out to be a bug in firefox v54.
https://bugzilla.mozilla.org/show_bug.cgi?id=1378070
The channels will be processed but in the end down mixed to stereo. Mozilla is at the time of writing working on a fix.
Marked as resolved in firefox v57.

Related

Can't get Web Audio API to work with iOS 11 Safari

So iOS 11 Safari was supposed to add support for the Web Audio API, but it still doesn't seem to work with this javascript code:
//called on page load
get_user_media = get_user_media || navigator.webkitGetUserMedia;
get_user_media = get_user_media || navigator.mozGetUserMedia;
get_user_media.call(navigator, { "audio": true }, use_stream, function () { });
function use_stream(stream){
var audio_context = new AudioContext();
var microphone = audio_context.createMediaStreamSource(stream);
window.source = microphone; // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=934512
var script_processor = audio_context.createScriptProcessor(1024, 1, 1);
script_processor.connect(audio_context.destination);
microphone.connect(script_processor);
//do more stuff which involves processing the data from user's microphone...
}
I copy pasted most of this code, so I only have a cursory understanding of it. I know that it's supposed to (and does, on other browsers) capture the user's microphone for further processing. I know that the code breaks on the var audio_context = new AudioContext(); line (as in, no code after that is run), but don't have any error messages cause I don't have a mac which is required to debug iOS Safari (apple die already >_<) Anyone know what's going on and/or how to fix it?
e: forgot to mention that I looked it up and apparently I need the keyword "webkit" before using Web Audio API in Safari, but making it var audio_context = new webkitAudioContext(); doesn't work either
#TomW was on the right track - basically the webkitAudioContext is suspended unless it's created in direct response to the user's tap (before you get the stream).
See my answer at https://stackoverflow.com/a/46534088/933879 for more details and a working example.
Nothing works on mobile save to home screen apps. I issued a bug report to Apple developer. Got a response that it was a duplicate ( which means they know..no clue if or when they will actually fix it).

Buzz on iOS 9.2 with AudioContext (Web Audio API)

I've been playing with a few different Web Audio API libraries, and I've been having mixed results. My favourite so far is Timbre.js. I'm generally getting a 'buzz' coming out of the speaker on iOS (even when using AudioContextMonkeyPatch). This sometimes does not happen. For example, reboot the phone, start the app, click the 'go' button, and the sound is identical (to my ears) as per my desktop browser. Make a change (eg. change tempo), and buzz buzz buzz. Generally though, the audio output is buzz buzz buzz.
Example code:
var freqs = T(function(count) {
return [220, 440, 660, 880][count % 4];
});
var osc = T("sin", {freq:freqs, mul:0.5});
var env = T("perc", {a:50, r:500}, osc).bang();
var interval = T("param", {value:500}).linTo(50, "30sec");
T("interval", {interval:interval}, freqs, env).start();
env.play();
I asked a similar question a little while after you (Distortion in WebAudio API in iOS9?) and believe I found an answer: WebKit Audio distorts on iOS 6 (iPhone 5) first time after power cycling
Summary: play an audio sample at the desired bitrate and then create a new context.
// inside the click/touch handler
var playInitSound = function playInitSound() {
var source = context.createBufferSource();
source.buffer = context.createBuffer(1, 1, 48000);
source.connect(context.destination);
if (source.start) {
source.start(0);
} else {
source.noteOn(0);
}
};
playInit();
if (context.sampleRate === 48000) {
context = new AudioContext();
playInit();
}
Editing to note that it's possible you'd have to do some hacking of Timbre.js to get this to work, but it at least worked for me in using Web Audio on its own.

IE 9 and 10 yield unexpected and inconsistent MediaError's

We have a set of HTML blocks -- say around 50 of them -- which are iteratively parsed and have Audio objects dynamically added:
var SomeAudioWrapper = function(name) {
this.internal_player = new Audio();
this.internal_player.src = this.determineSrcFromName(name);
// ultimately an MP3
this.play = function() {
if (someOtherConditionsAreMet()) {
this.internal_player.play();
}
}
}
Suppose we generate about 40 to 80 of these on page load, but always the same set for a particular configuration. In all browsers tested, this basic strategy appears to work. The audio load and play successfully.
In IE's 9 and 10, a transient bug surfaces. On occasion, calling .play() on the inner Audio object fails. Upon inspection, the inner Audio object has a .error.code of 4 (MEDIA_ERR_SRC_NOT_SUPPORTED). The file's .duration shows NaN.
However, this only happens occasionally, and to some random subset of the audio files. E.g., usually file_abc.mp3 plays, but sometimes it generates the error. The network monitor shows a successful download in either case. And attempting to reload the file via the console also fails -- and no requests appears in IE's network monitor:
var a = new Audio();
a.src = "the_broken_file.mp3";
a.play(); // fails
a.error.code; // 4
Even appending a query value fails to refetch the audio or trigger any network requests:
var a = new Audio();
a.src = "the_broken_file.mp3?v=12345";
a.play(); // fails
a.error.code; // 4
However, attempting the load the broken audio file in a new tab using the same code works: the "unsupported src" plays perfectly.
Are there any resource limits we could be hitting? (Maybe the "unsupported" audio finishes downloading late?) Are there any known bugs? Workarounds?
I think we can pretty easily detect when a file fails. For other compatibility reasons we run a loop to check audio progress and completion stats to prevent progression through the app (an assessment) until the audio is complete. We could easily look for .error values -- but if we find one, what do we do about it!?
Addendum: I just found a related question (IE 9/10/11 sound file limit) that suggests there's an undocumented limit of 41 -- not sure whether that's a limit of "41 requests for audio files", "41 in-memory audio objects", or what. I have yet to find any M$ documentation on the matter -- or known solutions.
Have you seen these pages on the audio file limits within IE? These are specific to Sound.js, but the information may be applicable to your issue:
https://github.com/CreateJS/SoundJS/issues/40 ...
Possible solution as mentioned in the last comment: "control the maximum number of audio tags depending on the platform and reuse these instead of recreating them"
Additional Info: http://community.createjs.com/kb/faq/soundjs-faq (see the section entitled “I load a lot of sounds, why am running into errors in Internet Explorer?”)
I have not experienced this problem in Edge or IE11. But, I wrote a javascript file to run some tests by looping through 200 audio files and seeing what happens. What I found is that the problem for IE9 and IE10 is consistent between ALL tabs. So, you are not even guaranteed to be able to load 41 files if other tabs have audio opened.
The app that I am working on has a custom sound manager. Our solution is to disable preloading audio for IE9 and IE10 (just load on demand) and then when the onended or onpause callback gets triggered, to run:
this.src = '';
This will free up the number of audio that are contained in IE. Although I should warn that it may make a request to the current page the user is on. When the play method in the sound manager is called again, set the src and play it.
I haven't tested this code, but I wrote something similar that works. What I think you could do for your implementation, is resolve the issue by using a solution like this:
var isIE = window.navigator.userAgent.match(/MSIE (9|10)/);
var SomeAudioWrapper = function(name) {
var src = this.determineSrcFromName(name);
this.internal_player = new Audio();
// If the browser is IE9 or IE10, remove the src when the
// audio is paused or done playing. Otherwise, set the src
// at the start.
if (isIE) {
this.internal_player.onended = function() {
this.src = '';
};
this.internal_player.onpause = this.internal_player.onended;
} else {
this.internal_player.src = src;
}
this.play = function() {
if (someOtherConditionsAreMet()) {
// If the browser is IE, set the src before playing.
if (isIE) {
this.internal_player.src = src;
}
this.internal_player.play();
}
}
}

Web audio: Can't get ScriptProcessor node to work in Chrome

In web audio, I can't get the ScriptProcessor node to work in Chrome, although it works fine in Firefox.
// Create audio context (Chrome/Firefox)
var context;
if (window.AudioContext) {
context = new AudioContext();
} else {
context = new webkitAudioContext();
}
// Create oscillator and start it
oscillator = context.createOscillator();
oscillator.start(0);
// Set up a script node that sets output to white noise
var myscriptnode = context.createScriptProcessor(4096, 1, 1);
myscriptnode.onaudioprocess = function(event) {
console.log('Processing buffer');
var output = event.outputBuffer.getChannelData(0);
for (i = 0; i < output.length; i++) {
output[i] = Math.random() / 10;
}
};
// Connect oscillator to script node and script node to destination
// (should output white noise)
oscillator.connect(myscriptnode);
myscriptnode.connect(context.destination);
// NOTE: This commented-out code connects oscillator directly to
// destination, which works in Chrome as well as Firefox.
//oscillator.connect(context.destination);
Expected result of this sample is that it should play white noise at 1/10 volume (the oscillator is actually ignored).
You can try this code at http://jsfiddle.net/78yKV/3/ - be aware that on Firefox this URL will play white noise straight away! On Chrome 30, it doesn't give any errors, but also doesn't give any audio output. I also checked in Chrome 31 beta but saw the same results. The 'Processing buffer' log entry never appears.
To test the general audio system, if you uncomment the last line and connect the oscillator directly to the destination, it does play audio (the oscillator tone) correctly on Chrome. But I can't get the ScriptProcessor to work on Chrome.
I searched the net for tutorials etc. with ScriptProcessor but those I found either didn't come with runnable examples or didn't work (or were too complex).
(Just to make clear - this is a stripped-down sample and doesn't relate in any way to what I'm actually trying to do, so please don't tell me that I shouldn't use a ScriptProcessor to generate white noise. That's not what it's for; I do absolutely need ScriptProcessor to work for my real usage.)
I think most likely I am doing something very stupid like I have the wrong event name or something like that, but I can't find it. Can anyone help?
I now managed to check on several other machines and I think the problem is specific to the default audio device on my machine, which is a telephone handset using the Microsoft default USB audio driver. I've reported this to Google using the menu option in Chrome; my speculation is that the problem occurs because the handset only supports mono 16 kHz output, and somehow this causes Chrome to get confused.
I can reproduce the bug on a colleague's machine which has the same make of handset. To reiterate:
Firefox works correctly on both machines when using the handset.
Both machines work correctly in Chrome when you select a different output device.
The oscillator playback works correctly in Chrome even when using the telephone handset.
Final version of test code http://jsfiddle.net/78yKV/7/
function doStuff(osc) {
// Create audio context (Chrome/Firefox)
var context;
if (window.AudioContext) {
context = new AudioContext();
} else {
context = new webkitAudioContext();
}
// Set up a script node that sets output to white noise
var myscriptnode;
if (context.createScriptProcessor) {
myscriptnode = context.createScriptProcessor(4096, 1, 1);
} else {
myscriptnode = context.createJavaScriptNode(4096, 1, 1);
}
var buffer = 1;
myscriptnode.onaudioprocess = function(event) {
console.log('Processing buffer ' + (buffer++));
var output = event.outputBuffer.getChannelData(0);
for (i = 0; i < output.length; i++) {
output[i] = Math.random() / 10;
}
};
// Connect script node to destination
if (osc) {
oscillator = context.createOscillator();
oscillator.start(0);
oscillator.connect(context.destination);
} else {
myscriptnode.connect(context.destination);
}
}
The white noise playback from this script (well actually a slightly earlier test version but I think it's the same) works in Chrome 30 on Windows 7, Windows 8.1, Linux, and Android 4.1; on Firefox on Windows; on an iPad (latest OS); and on a Mac using Safari 6.0.5 as well (it breaks if you open the developer tools there, but as long as you don't, it works). It only fails when using the USB telephone handset (Polycom CX300) mentioned.
So in other words, as apsillers suggested, this still looks like a Chrome bug, but a rather specific one. (By the way I also tried the latest 'Canary' version of Chrome but it didn't help.)

Web Audio API parameter modulation not working in Safari

I'm trying to modulate a filter with the output of another node, and having trouble getting this to work in Safari (6.0.4).
Here's a simplified code snippet:
context = new webkitAudioContext();
osc1 = context.createOscillator();
osc2 = context.createOscillator();
osc2.frequency.value = 2;
osc2.noteOn(0);
filter = context.createBiquadFilter();
filter.frequency.value = 100;
amp = context.createGainNode();
amp.gain.value = 100;
osc2.connect(amp);
amp.connect(filter.frequency);
osc1.connect(filter);
filter.connect(context.destination);
osc1.noteOn(0);
osc1.noteOff(2);
I've set up an example on jsFiddle with the same code: http://jsfiddle.net/p7EC6/
This works exactly as I want in Chrome - you can hear the filter frequency pulsing. In Safari, nothing happens. Interestingly, if I connect the amp output to a paramater of osc1 like amp.connect(osc1.detune), it does work in Safari.
Is there a fundamental browser support issue here, or is there something obvious I'm missing?
Yep, this was a bug that has since been fixed, but just not propagated into Safari's Webkit yet. (I believe it would work on nightly builds.)

Categories