I've been trying to create an 88 key piano with the Web Audio API. The plan is to run all the 88 oscillators first in the appropriate frequencies and then use Oscillator.connect() and Oscillator.disconnect() methods on the respective oscillators as the piano keys are pressed and released. The state of the AudioContext will be "running" all the time. Now, I have two questions here,
- Is this the right way to do it?
- I get a clicking noise at the start and end of the sounds when I play them. Why is this happening and how to get rid of it?
PS: The reason for creating a piano like this is to indulge myself in the delight of having created something from scratch. So using prerecorded sounds is not an option.
IF you wanted to do it that way, add a gain node to each oscillator, and then turn the gain off and on, instead of disconnect and reconnect.
That's probably what's causing your clicks and snaps. More below.
BUT... that's still pretty overkill, having 88 oscillators. The standard way keyboards do this is with a limited polyphony.
Create an array of ten oscillators, all hooked to their own gain, each gain hooked to the destination.
Keep track of how many keys are being pressed, and how many oscillators are in use.
At any given time there are ten oscillators ready to go, one for each finger. If for some reason you require more, add them dynamically.
The clicking sound is because you're hard disconnecting and reconnecting running oscillators. Use a gain node in between the osc and destination, and turn that on and off.
Also, you might get clicks when changing the values hard such as
That can create a glitch in the sound stream.. It should be:
Maybe the + 1 is necessary. There's also setTargetAtTime and rampToAtTime methods that make things even smoother:
https://developer.mozilla.org/en-US/docs/Web/API/AudioParam