Mozzi  version 2016-12-11-17:03
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 
34 {
35 
36 public:
37 
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 
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 
69  void noteOff(byte channel, byte pitch, byte velocity)
70  {
71  aAmpEnv.noteOff();
72  kResonantFreqEnv.noteOff();
73  }
74 
75 
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 
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 
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 
136  ADSR <CONTROL_RATE, CONTROL_RATE> kResonantFreqEnv;
137 
138 };
unsigned char next()
Advances one audio step along the ADSR and returns the level.
Definition: ADSR.h:164
void setFreq(int frequency)
Set the Phasor frequency with an unsigned int.
Definition: Phasor.h:76
int next()
Produce the audio output.
Definition: PDResonant.h:104
float mtof(float midival)
Converts midi note number to frequency.
Definition: mozzi_midi.cpp:17
void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
Set the attack, decay and release times of the ADSR in milliseconds.
Definition: ADSR.h:346
PDResonant()
Constructor.
Definition: PDResonant.h:40
void noteOff()
Start the release phase of the ADSR.
Definition: ADSR.h:187
void update()
Update the filter sweep.
Definition: PDResonant.h:93
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
Definition: Oscil.h:103
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Oscil.h:275
PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter...
Definition: PDResonant.h:33
void set(unsigned long value)
Set the current value of the phasor.
Definition: Phasor.h:64
void noteOn(byte channel, byte pitch, byte velocity)
Play a note in response to midi input.
Definition: PDResonant.h:54
unsigned long next()
Increments one step along the phase.
Definition: Phasor.h:51
void update()
Updates the internal controls of the ADSR.
Definition: ADSR.h:131
void setADLevels(byte attack, byte decay)
Set the attack and decay levels of the ADSR.
Definition: ADSR.h:248
void noteOn()
Start the attack phase of the ADSR.
Definition: ADSR.h:176
void setPDEnv(int attack, int decay)
Set the resonant filter sweep parameters.
Definition: PDResonant.h:80
void noteOff(byte channel, byte pitch, byte velocity)
Stop a note in response to midi input.
Definition: PDResonant.h:69