| Mozzi version v1.1.0 sound synthesis library for Arduino |

PDResonant.h
1 /*
2 * PDResonant.h
3 *
4 * This implementation copyright 2012 Tim Barrass.
5 *
6 * This file is part of Mozzi.
7 *
8 * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9 *
10 */
11
12
13
14 #include <mozzi_midi.h>
15 #include <ADSR.h>
16 #include <Oscil.h>
17 #include <Phasor.h>
18 // wavetable for oscillator:
19 #include <tables/sin2048_int8.h>
20
21 /**
22 PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on
23 https://en.wikipedia.org/wiki/Phase_distortion_synthesis.
24
25 The class shows how the Mozzi Phasor class
26 can be used to generate an index into a wavetable, and an ADSR
27 is used to modulate the effect by modifying the Phasor frequency and sync.
28 More complex phase distortion effects could be developed by using
29 precalculated tables, or calcuating tables on the fly using a double buffer,
30 or a line-breakpoint model, a sort of hybridPhasor-Line object.
31 */
32
33 class PDResonant
34 {
35
36 public:
37
38 /** Constructor.
39 */
40 PDResonant():
41 PDM_SCALE(0.05)
42 {
43 aOsc.setTable(SIN2048_DATA);
44 aAmpEnv.setADLevels(255, 255);
45 aAmpEnv.setTimes(50, 300, 60000, 1000);
46 kResonantFreqEnv.setADLevels(255,100);
47 }
48
49 /** Play a note in response to midi input. Params copied from MIDI library HandleNoteOn().
50 @param channel is the midi channel
51 @param pitch is the frequency in Hz
52 @param velocity you know what it is
53 */
54 void noteOn(byte channel, byte pitch, byte velocity)
55 {
56 kResonantFreqEnv.noteOn();
57 aAmpEnv.noteOn();
58 freq = mtof(pitch);
59 aBaseCounter.setFreq(freq); // gets modulated in updateControl()
60 aResonanceFreqCounter.setFreq(freq);
61 }
62
63
64 /** Stop a note in response to midi input. Params copied from MIDI library HandleNoteOff()
65 @param channel is the midi channel
66 @param pitch is the frequency in Hz
67 @param velocity you know what it is
68 */
69 void noteOff(byte channel, byte pitch, byte velocity)
70 {
71 aAmpEnv.noteOff();
72 kResonantFreqEnv.noteOff();
73 }
74
75
76 /** Set the resonant filter sweep parameters.
77 @param attack ADSR attack
78 @param decay ADSR decay
79 */
80 void setPDEnv(int attack, int decay)
81 {
82 // sustain and release timesare hardcoded here but don't need to be
83 kResonantFreqEnv.setTimes(attack, decay, 60000, 1000);
84 kResonantFreqEnv.update();
85
86 float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
87 aResonanceFreqCounter.setFreq(resonance_freq);
88 }
89
90
91 /** Update the filter sweep. Use this in updateControl().
92 */
93 void update()
94 {
95 aAmpEnv.update();
96 kResonantFreqEnv.update();
97 // change freq of resonant freq counter, following the envelope
98 float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
99 aResonanceFreqCounter.setFreq(resonance_freq);
100 }
101
102 /** Produce the audio output. This goes in updateAudio().
103 */
104 int next()
105 {
106 static byte previous_base_counter;
107 byte base_counter = aBaseCounter.next()>>24;
108
109 // reset resonance counter (wiki b.)
110 if (base_counter<previous_base_counter) aResonanceFreqCounter.set(0);
111 previous_base_counter= base_counter;
112
113 // index (phase) needs to end up as 11bit to match 2048 wavetable size
114 unsigned int index = aResonanceFreqCounter.next()>>21; // 11 bits fits 2048 cell sin table
115
116 // amp ramp smooths the jump when aResonanceFreqCounter is reset (wiki d.)
117 byte amp_ramp = 255-base_counter;
118
119 // wiki e., with amp envelope added
120 return ((long)aAmpEnv.next() * amp_ramp * aOsc.atIndex(index))>>16;
121
122 // return ((index>>3)*amp_ramp)>>8; // this also sounds good - squelchy sawtooth
123 }
124
125
126 private:
127 const float PDM_SCALE;
128 byte amp;
129 int freq;
130
131 Phasor <AUDIO_RATE> aBaseCounter;
132 Phasor <AUDIO_RATE> aResonanceFreqCounter;
133
134 Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aOsc;
135 ADSR <CONTROL_RATE, AUDIO_RATE> aAmpEnv;
136 ADSR <CONTROL_RATE, CONTROL_RATE> kResonantFreqEnv;
137
138 };
PDResonant::next
int next()
Produce the audio output.
Definition: PDResonant.h:104
Oscil
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:62
PDResonant::PDResonant
PDResonant()
Constructor.
Definition: PDResonant.h:40
AUDIO_RATE
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:62
PDResonant::update
void update()
Update the filter sweep.
Definition: PDResonant.h:93
PDResonant
PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter...
Definition: PDResonant.h:33
PDResonant::noteOn
void noteOn(byte channel, byte pitch, byte velocity)
Play a note in response to midi input.
Definition: PDResonant.h:54
Phasor
Phasor repeatedly generates a high resolution ramp at a variable frequency.
Definition: Phasor.h:32
PDResonant::setPDEnv
void setPDEnv(int attack, int decay)
Set the resonant filter sweep parameters.
Definition: PDResonant.h:80
PDResonant::noteOff
void noteOff(byte channel, byte pitch, byte velocity)
Stop a note in response to midi input.
Definition: PDResonant.h:69