Reputation: 1618
I wrote a simple synth using Codepen. It actually works and does what I'm expecting it to do (on Codepen and in debug mode on the website). Unfortunately it doesn't work on my local machine: if i download the code and try to run it, it gives me the error i mentioned in the question title.
If I "hard copy" the code into the browser console and i run it, it works perfectly.
Here's my full application, it just play some synth sound whenever you mouseover on a pad with the corresponding note: https://codepen.io/mattiasu96/pen/pxPXpB
//Simple definition of some filter and oscillator to create a composite sound
------------------------------------------
var filter = new Tone.AutoFilter(2,40,2.5).toMaster();
filter.depth=1;
filter.wet=1;
filter.filter.rolloff=-48;
filter.start();
var synth = new Tone.Synth({
oscillator: {
type: 'sawtooth',
},
envelope: {
attack: 0.001,
decay: 0.1,
sustain: 5,
release: 0.1
}
}).connect(filter);
var synthB = new Tone.Synth({
oscillator: {
type: 'sawtooth',
detune : -10 ,
},
envelope: {
attack: 0.001,
decay: 0.1,
sustain: 5,
release: 0.1
}
}).connect(filter);
var synthC = new Tone.Synth({
oscillator: {
type: 'sawtooth',
detune : +10 ,
},
envelope: {
attack: 0.001,
decay: 0.1,
sustain: 5,
release: 0.1
}
}).connect(filter);
var synthD = new Tone.Synth({
oscillator: {
type: 'sawtooth',
detune : -5 ,
},
envelope: {
attack: 0.001,
decay: 0.1,
sustain: 5,
release: 0.1
}
}).connect(filter);
var synthE = new Tone.Synth({
oscillator: {
type: 'sawtooth',
detune : -2 ,
},
envelope: {
attack: 0.001,
decay: 0.1,
sustain: 5,
release: 0.1
}
}).connect(filter);
var mode = 0; // 0 = modalità single note, 1 = modalità multiple notes
notes = document.querySelectorAll(".hex");
----------------------------------------
// Triggering the notes using the pads i have created
notes.forEach(function(note) {
note.addEventListener("mouseover", function(event){
x = event.target.title;
filter.baseFrequency=x;
synth.triggerAttack(x);
synthB.triggerAttack(x);
synthC.triggerAttack(x);
synthD.triggerAttack(x);
synthE.triggerAttack(x);
});
});
notes.forEach(function(note) {
note.addEventListener("mouseout", function(event){
x = event.target.title;
synth.triggerRelease();
synthB.triggerRelease();
synthC.triggerRelease();
synthD.triggerRelease();
synthE.triggerRelease();
});
});
It all works fine, but not in local, as i mentioned above. The code is actually correct, since it works fine on Codepen and it works if i hard copy it in my browser debug console.
I can't figure out why i get this error.
Upvotes: 6
Views: 6873
Reputation: 9166
The problem you are describing sounds like the browser doesn't allow the AudioContext (used by Tone.js) to start without any user interaction. Unfortunately 'mouseover' and 'mouseout' events do not count as a user interaction.
Therefore you would need to add a button somewhere which activates the AudioContext on click events. There is a short description in the README of Tone.js which describes how that can be done.
The mechanism which controls if an AudioContext can start on its own or has to be activated by a user interaction is usually called autoplay policy. It is possible to disable that policy on specific sites. Chrome for example also maintains a list of sites which have played audio in the past to allow sites that get heavily used to play audio without any user interaction. I guess this is the case for https://codepen.io/ on your computer.
The autoplay policy does usually also have no effect when running code with the help of the dev tools which is probably why that works for you as well.
Upvotes: 5