Wavetable sound synthesis engine.
It's a proof of concept helping understaing the topic and eventually implementing similar synthesizer on STM32 ARM chip.
What's included:
To play a sound load and run sound.core
(use toggle-playing
to start/stop sound generation).
sound.patch
defines complete configuration of the synthesizer you can change it live(!).
Listen to the Lost Woods from Zelda - Koji Kondo generated by syntesizer. This is what is defined in sound.patch
Implementation is highly based on Mutable Instruments source code and enables easy translation to C++ (custom types and class-like modularity).
Singal is created by following path:
Every step generates new sample which are gathered in small buffer and send to audio engine.
Waveforms are bandlimited (generated as sum of sines or as FFT/IFFT interpolation) wavetables of 256 samples. Waveform is stored as integrated signal (according to Higher-Order Integrated Wavetable Synthesis) as 16 bit signed integer (short
type). This representation + following procedure generates sample with minimized aliasing.
Sample generation follows the procedure:
State Variable Filter is used here because it's simple and doesn't require trigonometry (actually it's partly true, tan
is required but some interpolations can be used instead) functions to calculate the parametrization and the result. The second: 3 filtered samples are generated at once: low pass, high pass and band pass.
There is an option to modulate the phase (which is cheap replacement for frequency modulation (FM) - but works well enough) by other oscillator. Also there is an option to shape wave by any defined waveform.
It works by adding value of one oscillator (multiplied by amount) to the phase of second oscillator.
Amplitude of the signal is used as a phase of the shaping oscillator. Both values are mixed together (you can control amount)
Attack-Delay-Sustain-Release shaper is used to control amplitude of the signal and frequency of the filter. Slopes are exponential.
Patch, as a configuration of every module in the path, are kept as global variables to allow live coding. Playing is done in separated thread as future
. Thread is stopped via playing?
atom.
Copyright © 2020 GenerateMe
This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.