|
| 1 | +/* Example of Self Modulation synthesis, |
| 2 | + using Mozzi sonification library. |
| 3 | +
|
| 4 | + Demonstrates the use of Oscil::phMod to modulate an Oscillator by itself. |
| 5 | + Self Modulation is a part of frequency modulation synthesis (FM). |
| 6 | + Compared to "standard" FM where one oscillator modulates another |
| 7 | + in Self 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 Self Modulation, one oscillator modulating himself. |
| 12 | + The equivalent diagram is: |
| 13 | +
|
| 14 | + _____ |
| 15 | + \/ | |
| 16 | + |----| | |
| 17 | + | 1 | | |
| 18 | + |----| | |
| 19 | + |_____| |
| 20 | +
|
| 21 | + Circuit: Audio output on digital pin 9 on a Uno or similar, or |
| 22 | + DAC/A14 on Teensy 3.1, or |
| 23 | + check the README or http://sensorium.github.io/Mozzi/ |
| 24 | +
|
| 25 | + Mozzi documentation/API |
| 26 | + https://sensorium.github.io/Mozzi/doc/html/index.html |
| 27 | +
|
| 28 | + Mozzi help/discussion/announcements: |
| 29 | + https://groups.google.com/forum/#!forum/mozzi-users |
| 30 | +
|
| 31 | + Copyright 2012-2024 Tim Barrass and the Mozzi Team |
| 32 | +
|
| 33 | + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. |
| 34 | +*/ |
| 35 | + |
| 36 | + |
| 37 | +#include <Mozzi.h> |
| 38 | +#include <Oscil.h> // oscillator template |
| 39 | +#include <tables/sin2048_int8.h> // sine table for oscillator |
| 40 | +#include <EventDelay.h> |
| 41 | +#include <Smooth.h> |
| 42 | +#include <mozzi_rand.h> |
| 43 | +#include <mozzi_midi.h> |
| 44 | + |
| 45 | +EventDelay kModulationChangeDelay; // to change the modulation amount |
| 46 | +EventDelay kChangeNoteDelay; // to change the base note |
| 47 | +Smooth<uint8_t> kSmoothModulation(0.99f); |
| 48 | +Oscil<SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA); |
| 49 | + |
| 50 | +uint8_t self_mod_amount, smoothed_self_mod_amount; |
| 51 | + |
| 52 | +UFix<8, 0> notes[4] = { 40 - 12, 52 - 12, 28 - 12, 30 - 12 }; // note played. Because of the Modulation the oscillator is called *two times* |
| 53 | + // hence produces a note is which an octave to high, so we compensate for that here (12 midi notes makes an octave). |
| 54 | + |
| 55 | + |
| 56 | +void setup() { |
| 57 | + kModulationChangeDelay.set(2000); |
| 58 | + kChangeNoteDelay.set(300); |
| 59 | + startMozzi(); // :) |
| 60 | + aSin.setFreq(mtof(notes[0])); // set the frequency |
| 61 | +} |
| 62 | + |
| 63 | + |
| 64 | +void updateControl() { |
| 65 | + if (kModulationChangeDelay.ready()) { |
| 66 | + self_mod_amount = rand(255); // next target value of modulation |
| 67 | + kModulationChangeDelay.start(); |
| 68 | + } |
| 69 | + smoothed_self_mod_amount = kSmoothModulation(self_mod_amount); // smoothing of the modulation |
| 70 | + |
| 71 | + if (kChangeNoteDelay.ready()) { |
| 72 | + aSin.setFreq(mtof(notes[rand(4)])); |
| 73 | + kChangeNoteDelay.start(); |
| 74 | + } |
| 75 | +} |
| 76 | + |
| 77 | + |
| 78 | +AudioOutput updateAudio() { |
| 79 | + return MonoOutput::from8Bit(aSin.phMod((int32_t(aSin.next()) * smoothed_self_mod_amount) << 4)); |
| 80 | +} |
| 81 | + |
| 82 | + |
| 83 | +void loop() { |
| 84 | + audioHook(); // required here |
| 85 | +} |
0 commit comments