Everytime I try to run my code with a Feedback Delay, my Chrome Browser crashes, I get that blue screen saying:
"Aw, Snap!
Something went wrong while displaying this webpage. To continue, reload or go to another page."
My code uses this kind of structure:
//Create any kind of input (only to test if it works or not);
var oscillator = context.createOscillator();
//Create the delay node and the gain node used on the feedback
var delayNode = context.createDelay();
var feedback = context.createGain();
//Setting the feedback gain
feedback.gain.value = 0.5;
//Make the connections
oscillator.connect(context.destination);
oscillator.connect(delayNode);
delayNode.connect(feedback);
feedback.connect(delayNode);
delayNode.connect(context.destination);//This is where it crashes
Did you put panner nodes after the delay node?
I had a similar problem.
In my case, it was like a panner nodes' bug.
After debugging for hours, I found this page:
http://lists.w3.org/Archives/Public/public-audio-dev/2013Oct/0000.html
It says that connecting panner nodes after delay causes the problem.
If your code actually is like this, it will crash.
var pannerNode = context.createPanner();
delayNode.connect(pannerNode);
pannerNode.connect(context.destination);
My program was like this code.
When I removed panner node from my program, it worked fine.
So if you're in same occasion, you can avoid the problem by writing panner by youself.
Here is a sample I wrote for my program (in CoffeeScript).
class #Panner
constructor: (#ctx) ->
#in = #ctx.createChannelSplitter(2)
#out = #ctx.createChannelMerger(2)
#l = #ctx.createGain()
#r = #ctx.createGain()
#in.connect(#l, 0)
#in.connect(#r, 1)
#l.connect(#out, 0, 0)
#r.connect(#out, 0, 1)
#setPosition(0.5)
connect: (dst) -> #out.connect(dst)
setPosition: (#pos) ->
#l.gain.value = #pos
#r.gain.value = 1.0 - #pos
I Hope this will help you.
Related
I've been working in WebAudio trying to ramp a oscillator node on and off. I've been trying to verify the ramping on the signal with an oscilloscope, and noticing that the linear ramp (from linearRampToValueAtTime() function) is not working as anticipated.
First, I'm unable to change the duration of the ramping and then when I manage to get a ramp, it is not linear (using setValueAtTime() function).
So I guess my question is this - has anyone been able to validate using external equipment that the ramps are working in Chrome?
I tried verifying the example listed on the MDN documentation site:
https://mdn.github.io/webaudio-examples/audio-param/
but those demos also don't ramp - is this an issue with my audio driver, web browser, or some other issue? I'm assuming there's something wrong in the implementation, because it's not working anywhere, and others don't seem to have this issue so any help I can get would be appreciated!
snippets of the code below:
Creating nodes
for (i = 0; i < 2; i++) {
oscCarrier[i] = audioCtx.createOscillator();
panOsc[i] = audioCtx.createStereoPanner();
gainOsc[i] = audioCtx.createGain();
oscCarrier[i].frequency.value = 1000;
gainOsc[i].gain.setValueAtTime(0,audioCtx.currentTime);
oscCarrier[i].connect(panOsc[i]);
panOsc[i].connect(gainOsc[i])
gainOsc[i].connect(audioCtx.destination)
oscCarrier[i].start();
}
for ramping off:
let rampTime = .025 //(25 ms ramp off)
gainOsc[channel].gain.linearRampToValueAtTime(0, audioCtx.currentTime + rampTime)
for ramping on:
let rampTime = .025 //(25 ms ramp on)
gainOsc[channel].gain.linearRampToValueAtTime(0, audioCtx.currentTime + rampTime)
We are working on a Digital Audio Workstation kind of thing in the browser. We need to work with multiple audio files in a tab. We use new Audio(audioUrl) to be able to play the audio in our own audio mixer. It has been working for us up to now.
With the latest version of Chrome (92), we have the problem where the above code snippet causes the following error:
[Intervention] Blocked attempt to create a WebMediaPlayer as there are too many WebMediaPlayers already in existence. See crbug.com/1144736#c27
I cannot access the bug link provided, it says permission denied. And is there a suggested workaround to handle this?
UPDATE:
I moved away from using HTMLAudioElement to AudioBufferSourceNode. Seems like the only straightforward solution as Chrome team is discussing to limit them anyway. Note: We may need more than 1000 audio clips to be played back. This is in reference to the chromium discussion thread where they are going to increase the number of webmediaplayers to 1000 on the next release for August 5 2021.
Chrome 92 has introduced a limit on number of audio and video tags that can be allocated in a particular tab.
75 for desktop browsers and 40 for mobile browsers.
For now the only solution is to limit the number of audio and video tags created in the page. Try reusing the already allocated audio / video elements.
The number can only be increased by passing the following flag when starting up chrome, for example --max-web-media-player-count=5000
(Of course we cannot expect the end user to do this)
Related Source code here:
https://chromium-review.googlesource.com/c/chromium/src/+/2816118
Edit:
Before deallocating the audio/video elements setting the following seems to force clean up of the element.
mediaElement.remove();
mediaElement.srcObject = null;
const MaxWebMediaPlayerCount = 75;
class VideoProducer {
static #documentForVideo
static createVideo() {
if (!this.#documentForVideo || this.#documentForVideo.videoCount === MaxWebMediaPlayerCount) {
const iframeForVideo = document.body.appendChild(document.createElement('iframe'));
iframeForVideo.style.display = 'none';
iframeForVideo.contentDocument.videoCount = 0;
this.#documentForVideo = iframeForVideo.contentDocument;
}
this.#documentForVideo.videoCount++;
const video = this.#documentForVideo.createElement('video');
return video;
}
foo() {
const video = VideoProducer.createVideo();
// ...
}
Yeah me too it broke my game,
This is what I found as a workaround, hope this helps in the mean time:
function playSound( ) {
var jump_sound = new Audio("./jump.mp3");
jump_sound.play();
jump_sound.onended = function(){
this.currentSrc = null;
this.src = "";
this.srcObject = null;
this.remove();
};
}
Note: it still blocks if there's too many concurrent sound but with this code in place the blocking is temporary.
Chrome version 92.0.4515.131 seems to resolve the issue
I'm currently working on adapting this web audio API demo for a project that I am working on, but there is no sound when I test on an iPhone. It works fine on the iPad.
I've searched for solutions and found this thread on StackOverflow with the following snippet of one of the answers:
Safari on iOS 6 effectively starts with the Web Audio API muted. It
will not unmute until you attempt to play a sound in a user input
event (create a buffer source, connect it to destination, and call
noteOn()). After this, it unmutes and audio plays unrestricted and as
it ought to. This is an undocumented aspect of how the Web Audio API
works on iOS 6 (Apple's doc is here, hopefully they update it with a
mention of this soon!)
The user input event should be the onclick event on the play button but changing to use noteOn() instead of start() still doesn't fix it.
Update: I've also tried binding the play button with the touchend event but to no avail.
Here is the function that uses noteOn():
function playNote(buffer, pan, x, y, z, sendGain, mainGain, playbackRate, noteTime) {
// Create the note
var voice = context.createBufferSource();
voice.buffer = buffer;
voice.playbackRate.value = playbackRate;
// Optionally, connect to a panner
var finalNode;
if (pan) {
var panner = context.createPanner();
panner.panningModel = "HRTF";
panner.setPosition(x, y, z);
voice.connect(panner);
finalNode = panner;
} else {
finalNode = voice;
}
// Connect to dry mix
var dryGainNode = context.createGain();
dryGainNode.gain.value = mainGain * effectDryMix;
finalNode.connect(dryGainNode);
dryGainNode.connect(masterGainNode);
// Connect to wet mix
var wetGainNode = context.createGain();
wetGainNode.gain.value = sendGain;
finalNode.connect(wetGainNode);
wetGainNode.connect(convolver);
if (iOS) {
voice.noteOn(noteTime);
}
else {
voice.start(noteTime);
}
}
Any suggestions would be greatly appreciated. Thanks.
I feel really stupid. Apparently, if you have your iPhone on vibrate mode, the sound doesn't play.
The start() method should work fine without the if else statements on iOS as long as you call the function with a user interaction event. Also flip the order you pass y and z to the panner cause z is second for some strange reason.
Here's a working example, change stuff in it to fit what you need, most isn't need and I've got others somewhere that use the dom to add event listeners
<script>
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillator.type = 'sine';
oscillator.frequency.value = 440;
gainNode.gain.value = 1;
</script>
<button onclick="oscillator.start();">play</button>
My own experience has been that sometimes the Web Audio API works on iPhones, sometimes it doesn't. Here is a page that worked 5 minutes ago on my iPhone 6s; 1 minute ago it didn't work; now it does again!
http://www.stephenandrewtaylor.net/dna-sonification/
Here is another one that works intermittently; it worked 2 minutes ago and now it doesn't (the animations work, there is just no audio).
http://www.stephenandrewtaylor.net/lie-sonification/
It might have to do with how many tabs are open in Safari; you could try closing some of your open tabs (right now I have 5 tabs, including the lie-sonificaton page which worked 2 minutes ago but now doesn't). I am also a novice programmer and I'm sure there are much better ways I could be writing the code.
I've just started learning web dev and designed this website for my school's spelling bee contest:
https://rawgit.com/evandocarmo/spellingbee/v0.1/index.html
I also designed a little game in which students listen to words and spell them out. I was helped here to get it running:
https://rawgit.com/evandocarmo/spellingbee/v0.1/game.html
I can't make the goddamn repeat button work, though.
my java script code is this to get a random word from my object and play its audio property:
var play = function() {
var list = Object.keys(words);
window.randomWord = list[Math.floor(Math.random() * list.length)];
var playWord = words[window.randomWord].audio
playWord.play()
I used window to create a global variable that could be accessed by a second function, which works the repeat button:
var repeat = function(){
var playWord = words[window.randomWord].audio
playWord.play()
My biggest frustration is that I did this at home last night and it worked both offline and online!
And this morning at work it just stopped working =\ I click the button and it doesn't repeat the word. The rest works just fine.
any tips?
var audioContext = new window.AudioContext
chrome.runtime.onMessage.addListener(
function(imageUrl, sender, sendResponse) {
if (imageUrl != "") sound(523.251, 587.330) else sound(523.251, 493.883)
})
function sound(frequency1, frequency2) {
soundDuration = 0.1
var audioGain1 = audioContext.createGain()
audioGain1.gain.value = 0.1
audioGain1.connect(audioContext.destination)
var audioGain2 = audioContext.createGain()
audioGain2.gain.value = 0.1
audioGain2.connect(audioContext.destination)
var audioOscillator1 = audioContext.createOscillator()
audioOscillator1.type = "sine"
audioOscillator1.frequency.value = frequency1
audioOscillator1.connect(audioGain1)
var audioOscillator2 = audioContext.createOscillator()
audioOscillator2.type = "sine"
audioOscillator2.frequency.value = frequency2
audioOscillator2.connect(audioGain2)
audioOscillator1.start(0); audioOscillator1.stop(soundDuration)
audioOscillator2.start(soundDuration); audioOscillator2.stop(soundDuration*2)
}
I am developing a Google Chrome extension (Version 47.0.2526.111 m). I ran into the problem were I exceed the AudioContext (AC) limit of six (6) with code running in the Web Page Content Script (CS). I rewrote the code to have the CS send a message to a persistent Background Script (BS). I defined the AudioContext in the body of the BS hoping that would only create one copy. Each time the CS sends a message to the BS, I want to play two (2) tones. I found I needed to create the GainNodes and OscillatorNodes in the BS .onMessage.addListener function in order to avoid the “one time use” behavior of these nodes.
When tested, no tones are generated. If I breakpoint the code and step through the .start() and .stop() statements, the tones are generated. If I let the code run free across the .start() and .stop() and breakpoint just after the .stop(), no tones. I suspected scope issues and tried the .createGain() and .createOscillator() creating local (var) and global (no var) variables, but that does not change the behavior.
If I put all the AC object creation in the listener function, it works fine, but I am back to running out of ACs.
The BS script code is above
I found the answer after reading a lot of web research. The issue seems to be the .start()/.stop() values being passed. I changed:
audioOscillator1.start(0); audioOscillator1.stop(soundDuration)
to
audioOscillator1.start(audioContext.currentTime + 0)
audioOscillator1.stop(audioContext.currentTime + soundDuration)
The code now works with the audiocontext in the script body (global) and does not hit the audioconext limit. The gain/oscillator nodes are still local to the onMessage function.