Sound Distorter

06 Oct 2011

Making a synthesizer is fun because it's so cross-discipline - hardware, firmware, music theory and very importantly - lots of low-level performance tricks. It is also simple enough that a single person can design and build it. I passionately made one and here's how it works: the sequencer plays a chiptune, the basic I/O and the display allow us to change parameters on the fly and the tone generators deliver all this to our ears.

Sound Distorter runs mostly in software - a tool chain preprocesses a midi file so that it can be efficiently stored and played on the 8-bit Atmega168 microcontroller. After loading the chiptune midi file, sconv runs a series of filters to compact it and to preprocess operations to save cycles on the microcontroller. For example, instead of storing the tone (such as C#4), it could store the frequency. To be more efficient, it actually stores the wavetable offsets in samples per sample. Thus, playing a tone becomes a matter of just incrementing the wave-table index. The optimized file format I call .sad, short for sound distorter and the reminiscence of the C64 .sid should be obvious :) Finally, the .sad file gets converted to an assembly listing because the only way it can fit into the Atmega168 is in the text segment as program instructions.

The synth runs in 2 threads - a heavy-duty control thread that schedules events (such as note on, pitch-bend change, volume, etc.) and a fast, sample generating thread. The sample generator has real-time constraints and may preempt the control thread. To guarantee fairness, if overrun occurs and the control thread doesn't get to run, the synth drops (but does not delay) a sample. The sound generators use 2 shape wave-table - a sinusoid and a sharp, noisy wave. Besides the volume envelope, there is a blend envelope that linearly mixes the two shapes so that the sound changes in time. For example, during attack, primarily the noisy shape can be used, eventually resolving to a sinusoidal soft tone to mimic a plucking sound. Initially, I implemented FM modulation, but since the two wave shapes actually produce similar sound quality computationally much faster, I dropped it. There is also per channel pan mask to produce simple stereo effects.

The generated wave is then converted to an analog signal using 2 of the on-chip pulse-width modulators. To filter out the pulses and the bit flipping, the signals go through second order Sallen-Key low-pass filters.

The circuit board.

I feel I've made the project fairly easy to understand - code, schematic, mp3 and more pics. A secret prize goes to the one who figures out what the 3rd chip is for :)

Comments for Sound Distorter

Deni on October 6, 2011, 6:06:04 am EDT

Brilliant job! As always! :)

He-he! Super! on October 6, 2011, 2:20:41 pm EDT

Yunelis on January 15, 2013

What a joy to find such clear thinking. Thanks for psoitng!

Ed on May 7, 2015

Hi, great project. I try to compile source code. But it's seems incomplete: From synth.c, read_song_byte() , read_song_word() functions and wave_table1[] , wave_table2[] are undefined. Best regards

Post a new comment

Name: Comment:
4 + 8:
7 characters word: