最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

web audio api - Restart oscillator in javascript - Stack Overflow

programmeradmin0浏览0评论

I'm trying to make oscillator play when mouse is on canvas and stop when it's not. However, with current code, it works just once after loading page, when mouse is on canvas second time error occurs:

"Uncaught InvalidStateError: Failed to execute 'start' on 'OscillatorNode': cannot call start more than once.

var ac = new window.AudioContext() || new window.webkitAudioContext();
var osc = ac.createOscillator();
var canvas1 = document.getElementById("canvas1");
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

function playosc() {
    osc.frequency.value = 440;
    osc.connect(ac.destination);
    osc.start();
}

function stoposc() {
    osc.stop();
}

How to restart oscillator? Thanks.

I'm trying to make oscillator play when mouse is on canvas and stop when it's not. However, with current code, it works just once after loading page, when mouse is on canvas second time error occurs:

"Uncaught InvalidStateError: Failed to execute 'start' on 'OscillatorNode': cannot call start more than once.

var ac = new window.AudioContext() || new window.webkitAudioContext();
var osc = ac.createOscillator();
var canvas1 = document.getElementById("canvas1");
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

function playosc() {
    osc.frequency.value = 440;
    osc.connect(ac.destination);
    osc.start();
}

function stoposc() {
    osc.stop();
}

How to restart oscillator? Thanks.

Share Improve this question edited Jun 8, 2016 at 22:27 m-a-r-c-e-l-i-n-o 2,6721 gold badge20 silver badges27 bronze badges asked Jun 8, 2016 at 18:30 user3043626user3043626
Add a ment  | 

2 Answers 2

Reset to default 5

You would need to create an Oscillator object each time as the OscillatorNodes are not reusable. Example:

var canvas1 = document.getElementById("canvas1");
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

var ac = new window.AudioContext() || new window.webkitAudioContext();
var osc;

function playosc() {
    osc = ac.createOscillator()
    osc.frequency.value = 440;
    osc.connect(ac.destination);
    osc.start();
}

function stoposc() {
    osc.stop();
}

Please refer to this excellent blog post for more guidance.

A simpler way is to have the oscillator start and connect to a gain node which you modulate between 0 and 1 to determine if the oscillator outputs or not.

var ac = new window.AudioContext() || new window.webkitAudioContext();
var osc = ac.createOscillator();
var gain = ac.createGain();
var canvas1 = document.getElementById("canvas1");
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

gain.gain.value = 0;
osc.connect(ac.gain);
gain.connect(ac.destination);
osc.start();

function playosc() {
    osc.frequency.value = 440;
    gain.gain.value = 1;
}

function stoposc() {
    gain.gain.value = 0;
}

You can also (and should) use the ramping. Plus you can modulate the gain further (such as based on mouse position within the canvas) and so on.

Yes it will use more CPU usage (since the oscillator is always running). However gain nodes of values at 0 cheat and don't actually multiply, they just spit out arrays of zeros.

发布评论

评论列表(0)

  1. 暂无评论