block by alexmacy 04fe3a2dfa43a07f8a6ca84bfdcd4a55

Additive Synthesizer

Full Screen

I originally tried building the sound wave manually by pulling values form the oscillators to calculate each sample and pushing it to the audio buffer as one compound wave, but timing the updates is problematic. This is in part because it is a lot of data to process on the fly! While I had some luck using turbo.js to offload the processing to the gpu, I found it to be virtually impossible to sync the waves on each cycle.

The original solution I came up with was to give each oscillator its own Web Audio OscillatorNode, but that wouldn’t allow for proper phasing of the waves. It also kinda fealt like cheating since the goal in my mind was to create a synthesizer that outputs one compound tone rather than one that creates multiple tones and mixes them together on output.

What I ended up doing was using Web Audio’s createPeriodicWave() method. First, it creates two blank arrays (real and imag) that will function like a Fourier Series and then populating them with the values from the oscillators. There was still the tricky part of handling the phase offsets, but I found a nice solution where you simply apply a 2D rotation to the value in the Fourier Series!

This result is pretty much exactly what I was hoping for. The one catch is that there is a clipping that can happen when adjusting the phase or the frequency. This is because due a timing issue regarding the position of the wave when it gets changed. That is, if the end of old wave and start of the new wave don’t align, they can cause an unwanted sound. The only way I could find for resolving that was to add a very fast fade in/out effect to the sound whenever a value is changed, but this was also unreliable and would usually resulting in a stuttering effect that was even more distracting than the clipping.

This is part of a series exploring the visualization of audio that was presented at a d3.oakland meetup. A big list of the demos from this series can be found here.

index.html