/ PROJECT, MUSIC, PROGRAMMING, SYNTH

Digital Synthesizer Project - Part 1

This is an adventure started a few days ago when my group of friends came up with the idea of creating a band. Already having a singer, two guitarists, a drummer and a bassist, I had to invent my role. Actually, I was already defined as the saxophonist, but being honest saxophone is not used in every song. So I thought I could have tried to make a synth spending no money and using things I already had in my house.

That means that probably a DIY analogical synth would have been quite cheap and not so hard to make, with probably a better final result. But genoise people are famous in Italy for being stingy :)

The idea was simple: generating a sound wave with a computer (hopefully a Raspberry Pi), controlling effects with a DJ controller I already had and controlling the note with a cheap keyboard.

This is a demo video of the current version of the synthesizer. Below you’ll find the full article

The controller

The controller I’m using is a Hercules DJ Control Instinct (no sponsorship sadly). It would have been much simpler to just google it at first, but not, I just thought it was using a Serial Port and I wasted something like two hours trying to get any input from that. Then I discovered it was just a simple MIDI controller, easy to use.

So the language I chose was Python: it has a bunch of libraries which would have probably been extremely useful. Apparently, pygame has a great midi library, pygame.midi. Initialization is extremely easy and requires a few lines of code

import pygame
import pygame.midi

pygame.init()
pygame.midi.init()
device = pygame.midi.Input(3)

Reading the input is almost as easy:

while(True):
    while(midi.device.poll()):
        read = midi.device.read(1)[0];
        print(read)

And it gives something like

[[status,data1,data2,data3],timestamp],...]

Perfect, right?

The sound wave

This is where things get a little bit more complicated… I’ve spent hours trying different python libraries with no real success, the best one being synthesizer. Relatively easy to use, small documentation for little features

import pygame
import pygame.midi
import midi
from synthesizer import Player, Synthesizer, Waveform
import math

player = Player()
player.open_stream()
synthesizer = Synthesizer(osc1_waveform=Waveform.square, osc1_volume=1.0, use_osc2=False)

val = 0
while(True):
    while(midi.device.poll()):
        read = midi.device.read(1)[0];
        # reading value from midi controller
        if read[0][1] == 54:
            val = int(read[0][2])
    note = float(val) / 127 * 500
    player.play_wave(synthesizer.generate_chord([note], 0.1)) # using chord to be able to play more notes as once

Although this may seem to work with no problem whatsoever it actually has some ‘clipping’ sound: every single note generated by this synthesizer is clearly recognizable from the other ones. This is clearly not good at all and had to be solved in some way. I did a lot of researches trying to find another Python library but I had no success. Thinking of which programming language could have helped I came out with the idea that maybe all the control you have with C++ would have been useful to generate custom sound waves in the audio output. And I was right. Simply googling “C++ sound oscillator” I discovered a library, named Juce, with a free education license. But first, let’s clarify what an oscillator is.

Oscillators

An electronic oscillator is an electronic circuit that produces a periodic, oscillating electronic signal, often a sine wave or a square wave. […] An audio oscillator produces frequencies in the audio range, about 16 Hz to 20kHz     - Wikipedia

So when we talk about oscillators in synthesizer we talk about a small object that is able to generate our sound wave, which we can control in terms of frequency and amplitude. This is beautiful and usually results in the best sound quality, but we don’t want to use that.

Since we are talking about a full digital synthesizer we need to digitally create an oscillator. We need nothing but some program that writes an oscillating wave in the audio output of our computer. This wave is extremely simple, we can just use the sin function present in every math library:

In this equation “time” is the elapsed time since the start of the program.

As you can see generating a sine wave is very simple. Generating other types of waves is not so different. Here some examples:

  • Square wave (the simplest way is to return 1 when the sine is positive and -1 when it’s negative):
  • Triangular and sawtooth wave are more difficult to express, so I’ll report the C++ code, hoping it is more easy to understand
float triangularWave(const float frequency, const float time)
{
    float res = 0.0;
    float fullPeriodTime = 1.0 / frequency;
    float localTime = fmod(time, fullPeriodTime);

    float value = localTime / fullPeriodTime;

    if(value < 0.25)
        res = value * 4;
    else if(value < 0.75)
        res = 2.0 - (value * 4.0);
    else
        res = value * 4 - 4.0;
    return res;
}

float sawtoothWave(const float frequency, const float time)
{
    float fullPeriodTime = 1.0 / frequency;
    float localTime = fmod(time, fullPeriodTime);

    return  (localTime / fullPeriodTime) * 2 - 1.0;
}

That’s it. What now remains to do is to use the Juce library to create a program, complete with GUI, which takes the MIDI input, processes it and generate the correct sound wave. Since this article is starting to get long, and since I’ve been spending quite a few time writing it, I’ll cover this part in the next post, named Part 1.5. If you don’t care about the library you can skip it and read Part 2, since it will be tutorial-like.

To be continued...