Blending pure tones: Additive Synthesis from scratch with Python code
There are a few basic waveforms that are commonly seen in analog synthesizers as building blocks for more complex sounds. But indeed, they can all be built from the purest sound — sine waves! You just need the correct recipe for the combination.
純音手工特調:用 Python 做聲音加法合成
類比合成器上常可見到幾款基本波形,用以構成更複雜的聲音。事實上,只要秘方在手,全部基本波形都可以用 sine wave 純音組合而成。
medium.com
Although we hear the vibration of a single frequency as a single pitch, the harmonious sound from musical instruments all happen to have a collection of frequencies for every single pitch. With a different recipe of combination of these frequencies, the tone colour (timbre) differs.
Timbre /ˈtambə/: The character or quality of a musical or vocal sound (Oxford English Dictionary)
The set of harmonics is an important base of the timbre. Technically, we need to look for an appropriate proportion of the fundamental frequency and its integer multiples.
A Violin Sound
For example, a violin sound of A440 has a fundamental frequency of 440 Hz. On top of it, the sound also has a mix of 880 Hz (440×2), 1320 Hz (440×3), 1760 Hz (440×4), and so on. Let’s use this table of secret recipe that we can find using some sound analysis tools. Ignore the vibrato for the moment…
With a very simple synthesis, it sounds like this:
Try comparing it with the pure sine tone. It sounds so different, isn’t it?
To mix pure sine tones into a new timbre is called additive synthesis. Let’s do this step by step with Python code!
Don’t worry. It’s not so addictive…
Additive Synthesis with Python
We start with importing the necessary libraries— IPython
for showing the sound player, matplotlib
for plotting charts, numpy
for arrays, and math
for some mathematical functions. We also define the sampling rate sr
.
We have seen making a pure sine waveform before. We can put the code into a function makesine()
to easily reuse it:
Then, we can run makesine()
several times to make a new waveform, with certain frequency freq
and duration dur
. We can put all of them together using numpy.concatenate()
.
The basic sine wave sounds pretty good! Now let’s make more sine waves with frequencies at integer multiples using freq*i
, where i
is a counter from 1
and adds 1 every time. The sine waves need to softened into the predefined amplitudes in amplist
. They are then stacked up in out
.
Basic Waveforms with Additive Synthesis
Now, here are the common basic waveforms re-created with a simple additive synthesizer which only includes the first 10 harmonics: (I’m too lazy to obtain more harmonic amplitudes…)
And here’s the violin again!
While all of them have 440 Hz as the fundamental frequency, it sounds quite drastically different with a different combination of harmonics.
More Sophisticated Ways to Generate a Melody
Going further, here we prepare a function for the pitch-to-frequency calculator:
And a melody player to accept lists of notes and durations to play, with a pre-defined list of harmonic ratios:
Then… let’s play a melody! Here p
is the notes to play, d
is the durations of each note (made faster by ×4 times), and h
is the list of harmonic amplitudes.
I guess this may sound like the 80’s for you? (Indeed it’s the 90’s and beyond…)
Such an operation of additive synthesis can be quite tedious, even for computers (in older days when computation resource was less plentiful as today)! Just like mixing paints manually, such a synthesis gives the developer/musician the highest degree of control, but could be less favourable than a ready-mix that saves plenty of time.
Next time we can use easier tools such as programming libraries or software to get pre-mixture of tones for further manipulation.
You can try and play with the code in this notebook: https://deepnote.com/workspace/chuckjee-f06aaf72-cebf-4a01-bee7-1d8eb93c1d61/project/Additive-synthesis-from-scratch-e0fb471d-1cce-4e57-9142-cfb7f9a4899c/%2Fnotebook.ipynb