Skip to content

Commit e1c88eb

Browse files
committed
Better RingModulator example
1 parent ec5c3d9 commit e1c88eb

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

examples/06.Synthesis/RingModulator/RingModulator.ino

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
1-
/* Example playing a sinewave at a set frequency,
1+
/* Example of Ring Modulation synthesis,
22
using Mozzi sonification library.
33
4-
Demonstrates the use of Oscil to play a wavetable.
4+
Demonstrates the use of Oscil::phMod to modulate an Oscillator by itself: a ring modulator.
5+
Ring Modulation is a part of frequency modulation synthesis (FM).
6+
Compared to "standard" FM where one oscillator modulates another
7+
in Ring Modulation the output of one oscillator is used to modulate
8+
itself, directly, of after further modulation, or to modulate one of its
9+
modulator (looking at the DX7 diagram is probably clearer).
10+
11+
Here we demonstrate the simple case of RM, one oscillator modulating himself.
12+
The equivalent diagram is:
13+
14+
_____
15+
\/ |
16+
|----| |
17+
| 1 | |
18+
|----| |
19+
|_____|
520
621
Circuit: Audio output on digital pin 9 on a Uno or similar, or
722
DAC/A14 on Teensy 3.1, or
@@ -25,39 +40,43 @@
2540
#include <EventDelay.h>
2641
#include <Smooth.h>
2742
#include <mozzi_rand.h>
43+
#include <mozzi_midi.h>
2844

29-
EventDelay kModulationChangeDelay;
30-
Smooth<uint8_t> kSmoothModulation(0.9f);
31-
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
45+
EventDelay kModulationChangeDelay; // to change the modulation amount
46+
EventDelay kChangeNoteDelay; // to change the base note
47+
Smooth<uint8_t> kSmoothModulation(0.99f);
3248
Oscil<SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA);
33-
//Oscil <SIN2048_NUM_CELLS, MOZZI_CONTROL_RATE> aSin2(SIN2048_DATA); // controls the amount of Ring Modulation
3449

35-
int8_t prev_sample = 0;
36-
uint8_t ring_mod, smoothed_ring_mod;
50+
uint8_t ring_mod_amount, smoothed_ring_mod_amount;
51+
52+
UFix<8, 0> notes[4] = { 40 - 12, 52 - 12, 28 - 12, 30 - 12 }; // note played. Because of the ringModulation the oscillator is called *two times*
53+
// hence produces a note which an octave to high, so we compensate for that here (12 midi notes makes an octave).
54+
3755

3856
void setup() {
39-
Serial.begin(115200);
4057
kModulationChangeDelay.set(2000);
41-
startMozzi(); // :)
42-
aSin.setFreq(64); // set the frequency
58+
kChangeNoteDelay.set(300);
59+
startMozzi(); // :)
60+
aSin.setFreq(mtof(notes[0])); // set the frequency
4361
}
4462

4563

4664
void updateControl() {
47-
//ring_mod_amount = int(aSin2.next() + 128);
48-
//Serial.println(ring_mod_amount);
49-
//ring_mod_amount = 255;
5065
if (kModulationChangeDelay.ready()) {
51-
ring_mod = rand(150);
66+
ring_mod_amount = rand(255); // next target value of modulation
5267
kModulationChangeDelay.start();
5368
}
54-
smoothed_ring_mod = kSmoothModulation(ring_mod);
69+
smoothed_ring_mod_amount = kSmoothModulation(ring_mod_amount); // smoothing of the modulation
70+
71+
if (kChangeNoteDelay.ready()) {
72+
aSin.setFreq(mtof(notes[rand(4)]));
73+
kChangeNoteDelay.start();
74+
}
5575
}
5676

5777

5878
AudioOutput updateAudio() {
59-
prev_sample = aSin.phMod(int32_t(prev_sample) * smoothed_ring_mod);
60-
return MonoOutput::from8Bit(prev_sample); // return an int signal centred around 0
79+
return MonoOutput::from8Bit(aSin.phMod((int32_t(aSin.next()) * smoothed_ring_mod_amount) << 4));
6180
}
6281

6382

0 commit comments

Comments
 (0)