1 of 90

How to build a digital music synthesizer

By Tina Belmont- SoftEgg LLC

2 of 90

How to build a digital music synthesizer

(in two minutes)

3 of 90

Music is sound that communicates emotion

Duh.

4 of 90

Sounds are vibrations in the air

5 of 90

Air can be vibrated by a speaker

6 of 90

Speaker can be attached to a pin of a microcontroller

You might want an amplifier in between for best results.

Use a D/A pin or PWM.

7 of 90

Parameters of sound

Frequency (aka Pitch)

8 of 90

Parameters of sound

Frequency (aka Pitch)

9 of 90

Parameters of Sound

Amplitude (aka volume)

10 of 90

Parameters of Sound

Harmonic content (generally, the waveform)

11 of 90

Output sound from microcontroller

Store waveform in a table of numbers

12 of 90

Output sound from a microcontroller

Store waveform in a table of numbers.

You could store a whole recording of an instrument.

13 of 90

Output sound from a microcontroller

Store waveform in a table of numbers.

You could store a whole recording of an instrument.

This is called digital sampling.

14 of 90

Output sound from a microcontroller

Store waveform in a table of numbers.

You could store a whole recording of an instrument.

This is called digital sampling.

We’re not going to do that because we are making a synthesizer.

15 of 90

Output sound from a microcontroller

Store waveform in a table of numbers.

You could store a whole recording of an instrument.

This is called digital sampling.

We’re not going to do that because we are making a synthesizer.

Microcontrollers don’t have that much memory anyway.�

16 of 90

Output sound from a microcontroller

We just want one period of a simple waveform.

We can loop it.

17 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�

18 of 90

Different pitches from one waveform

Skip or duplicate table entries for different speeds / pitches.

19 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

20 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

21 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

It’s a slightly flat F3… (which is 174.61Hz)

22 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

It’s a slightly flat F3… how do we get actual notes?

23 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

24 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

25 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

26 of 90

Different pitches from one waveform

D/A output is always the same speed (sample rate).�Skip or duplicate table entries for different speeds.

27 of 90

Different pitches from one waveform

Aliasing may be an issue!

28 of 90

Different pitches from one waveform

Aliasing may be an issue! Nyquist frequency is a thing!

29 of 90

Different pitches from one waveform

Avoid low frequency grit by making sample table large enough for the lowest note.

30 of 90

Different pitches from one waveform

Avoid low frequency grit by making sample table large enough for the lowest note.

C0 is 16.35Hz.

31 of 90

Different pitches from one waveform

Avoid low frequency grit by making sample table large enough for the lowest note.

C0 is 16.35Hz.

32 of 90

Different pitches from one waveform

Avoid low frequency grit by making sample table large enough for the lowest note.

C0 is 16.35Hz.

33 of 90

Different pitches from one waveform

Avoid low frequency grit by making sample table large enough for the lowest note.

C0 is 16.35Hz.

Make it a power of two for reasons. 2048 or 4096 plz.

34 of 90

Different pitches from one waveform

Avoid low frequency grit by making sample table large enough for the lowest note.

C0 is 16.35Hz.

Make it a power of two for reasons. 2048 or 4096 plz.

Or live with the grit… maybe you like it!

35 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

36 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

Each octave doubles in pitch.

37 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

Each octave doubles in pitch.

So the frequency of each note increases as .

38 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

Each octave doubles in pitch.

So the frequency of each note increases as .

Or

39 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

Each octave doubles in pitch.

So the frequency of each note increases as .

Or

Traditional tuning has A4 at 440 Hz.

40 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

Each octave doubles in pitch.

So the frequency of each note increases as .

Or

Traditional tuning has A4 at 440 Hz.

Just make or copy a table and stick it in your code, OK?

41 of 90

What are note frequencies?

Octave is 12 notes (“half-steps” because music is stupid.)

Each octave doubles in pitch.

So the frequency of each note increases as .

Or

Traditional tuning has A4 at 440 Hz.

Just make or copy a table and stick it in your code, OK?

If you want fine tuning:

42 of 90

Help!

43 of 90

Help!

My microcontroller can’t

44 of 90

Help!

My microcontroller can’t FLOATING POINT!

45 of 90

Bro!

46 of 90

Bro!

Do you even

47 of 90

Bro!

Do you even

FIXED POINT MATH?

48 of 90

Bro! Do you even FIXED POINT MATH?

It’s just bloody fractions!

49 of 90

Bro! Do you even FIXED POINT MATH?

It’s just bloody fractions!

Multiply by a value to bring fractional part into integer space.

50 of 90

Bro! Do you even FIXED POINT MATH?

It’s just bloody fractions!

Multiply by a value to bring fractional part into integer space.

Use a power of 2, so that you can use shift operators << >>.

51 of 90

Bro! Do you even FIXED POINT MATH?

It’s just bloody fractions!

Multiply by a value to bring fractional part into integer space.

Use a power of 2, so that you can use shift operators << >>.

Example:

1<<8 = 256 or 0x100

52 of 90

Bro! Do you even FIXED POINT MATH?

It’s just bloody fractions!

Multiply by a value to bring fractional part into integer space.

Use a power of 2, so that you can use shift operators << >>.

Example:

1<<8 = 256 or 0x100 (0x means hexadecimal, duh!)

53 of 90

Bro! Do you even FIXED POINT MATH?

It’s just bloody fractions!

Multiply by a value to bring fractional part into integer space.

Use a power of 2, so that you can use shift operators << >>.

Example:

1<<8 = 256 or 0x100 (0x means hexadecimal, duh!)

So to to get 0.5, divide 256 by 2 (>>=1) = 128 (0x80)

54 of 90

Bro! Do you even FIXED POINT MATH?

Pick a precision that works for the problem that you are trying to solve, and is best for your processor.

55 of 90

Bro! Do you even FIXED POINT MATH?

Pick a precision that works for the problem that you are trying to solve, and is best for your processor.

If your values only go 0 to 1, then you can use the entire precision; all the bits!

56 of 90

Bro! Do you even FIXED POINT MATH?

Pick a precision that works for the problem that you are trying to solve, and is best for your processor.

If your values only go 0 to 1, then you can use the entire precision; all the bits!

If you need negative numbers, leave a bit at the top.

57 of 90

Bro! Do you even FIXED POINT MATH?

Pick a precision that works for the problem that you are trying to solve, and is best for your processor.

If your values only go 0 to 1, then you can use the entire precision; all the bits!

If you need negative numbers, leave a bit at the top.

Don’t forget to leave overflow precision to do math on stuff when multiplying.

58 of 90

Bro! Do you even FIXED POINT MATH?

Pick a precision that works for the problem that you are trying to solve, and is best for your processor.

If your values only go 0 to 1, then you can use the entire precision; all the bits!

If you need negative numbers, leave a bit at the top.

Don’t forget to leave overflow precision to do math on stuff when multiplying. Sometimes do math in a higher precision space than you store if necessary.

59 of 90

Bro! Do you even FIXED POINT MATH?

Pick a precision that works for the problem that you are trying to solve, and is best for your processor.

If your values only go 0 to 1, then you can use the entire precision; all the bits!

If you need negative numbers, leave a bit at the top.

Don’t forget to leave overflow precision to do math on stuff when multiplying. Sometimes do math in a higher precision space than you store if necessary.

Don’t forget to shift right after a multiplication!

60 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

61 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

We want to allow fade to 0.

62 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

We want to allow fade to 0. So volume is also level 0-255.

63 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

We want to allow fade to 0. So volume is also level 0-255.

Give ourselves 16 bits for math. Easy in C (uint16_t).

64 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

We want to allow fade to 0. So volume is also level 0-255.

Give ourselves 16 bits for math. Easy in C (uint16_t).

Multiple the two values together.

65 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

We want to allow fade to 0. So volume is also level 0-255.

Give ourselves 16 bits for math. Easy in C (uint16_t).

Multiple the two values together.

Shift right 8 bits to cancel out the 8 bits we added with the volume multiply.

66 of 90

Fixed point math example: Volume

Let’s say the sample is 8 bits, 0 to 255 (0x00 to 0xFF).

We want to allow fade to 0. So volume is also level 0-255.

Give ourselves 16 bits for math. Easy in C (uint16_t).

Multiple the two values together.

Shift right 8 bits to cancel out the 8 bits we added with the volume multiply.

Result is the new output sample.

67 of 90

This sounds boring.

68 of 90

This sounds boring.

Let’s make it interesting.

69 of 90

Use two or more oscillators

Options:

  • Detune the pitch slightly between the oscillators.

70 of 90

Use two or more oscillators

Options:

  • Detune the pitch slightly between the oscillators.
  • Multiply the output; that’s a ring modulator.

71 of 90

Use two or more oscillators

Options:

  • Detune the pitch slightly between the oscillators.
  • Multiply them; that’s a ring modulator.
  • Restart one based on the other; that’s sync.

72 of 90

Use two or more oscillators

Options:

  • Detune the pitch slightly between the oscillators.
  • Multiply them; that’s a ring modulator.
  • Restart one based on the other; that’s sync.
  • Use frequency of one to to modulate parameters; that is an LFO or Low Frequency Oscillator.
    • Pitch (aka vibrato)
    • Volume (tremelo)
    • Phase (phase distortion)
    • Filter
    • Pulse Width (pulse width modulation, or PWM)
    • etc.

73 of 90

Use envelopes

Envelope is change in value of a parameter over time.

74 of 90

Use envelopes

Envelope is change in value of a parameter over time.

Apply to volume, pitch, filter, any parameter… go wild!

75 of 90

Use envelopes

Envelope is change in value of a parameter over time.

Apply to volume, pitch, filter, any parameter… go wild!

It’s a state machine, you are programmers, figure it out!

76 of 90

You keep mentioning “Filters”...

77 of 90

You keep mentioning “Filters”...

WTF is a “Filter”?

78 of 90

WTF is a Filter?

Reduces harmonic content of a signal.

79 of 90

WTF is a Filter?

Reduces harmonic content of a signal.

Sounds cool when you sweep it with an envelope or LFO!

80 of 90

WTF is a Filter?

Reduces harmonic content of a signal.

Sounds cool when you sweep it with an envelope or LFO!

Low-pass is most common, but high-pass and band-pass are also used.

81 of 90

WTF is a Filter?

Reduces harmonic content of a signal.

Sounds cool when you sweep it with an envelope or LFO!

Low-pass is most common, but high-pass and band-pass are also used.

Go Google some algorithms!

feedbackAmount = resonance + resonance/(1.0 - cutoff);

buf0 += cutoff * (inputValue - buf0 + feedbackAmount * (buf0 - buf1));

buf2 += cutoff * (buf1 - buf2);

buf3 += cutoff * (buf2 - buf3);

switch (mode) {

case FILTER_MODE_LOWPASS:

return buf3;

case FILTER_MODE_HIGHPASS:

return inputValue - buf3;

case FILTER_MODE_BANDPASS:

return buf0 - buf3;

default:

return 0.0;

82 of 90

Play notes via MIDI!

MIDI is dirt simple.

83 of 90

Play notes via MIDI!

MIDI is dirt simple.

Serial at 31250 bits per second with start and stop bits.

84 of 90

Play notes via MIDI!

MIDI is dirt simple.

Serial at 31250 bits per second with start and stop bits.

If high bit is set, is a command. Otherwise last command stands.

85 of 90

Play notes via MIDI!

MIDI is dirt simple.

Serial at 31250 bits per second with start and stop bits.

If high bit is set, is a command. Otherwise last command stands.

High nybble is command (0x9X = note on, 0x80 = note off)

Low nybble is MIDI channel.

86 of 90

Play notes via MIDI!

MIDI is dirt simple.

Serial at 31250 bits per second with start and stop bits.

If high bit is set, is a command. Otherwise last command stands.

High nybble is command (0x9X = note on, 0x80 = note off)

Low nybble is MIDI channel.

Data for Note On / Off is two bytes: key # and velocity.

87 of 90

Play notes via MIDI!

Just use the default Arduino library from �Forty Seven Effects at https://github.com/FortySevenEffects/arduino_midi_library .

Install via Arduino Library Manager.

88 of 90

Play notes via MIDI!

Just use the default Arduino library from �Forty Seven Effects at https://github.com/FortySevenEffects/arduino_midi_library .

Install via Arduino Library Manager.

PJRC Teensy gives you MIDI over USB for free via bootloader options!

89 of 90

Play notes via MIDI!

Just use the default Arduino library from �Forty Seven Effects at https://github.com/FortySevenEffects/arduino_midi_library .

Install via Arduino Library Manager.

PJRC Teensy gives you MIDI over USB for free via bootloader options!

If your keyboard has knobs and / or sliders you can adjust parameters via CC messages; no UI necessary!

90 of 90

How to build a digital music synthesizer

The End