22 #include "MozziGuts.h"
23 #include "mozzi_fixmath.h"
24 #include <util/atomic.h>
27 #ifdef OSCIL_DITHER_PHASE
28 #include "mozzi_rand.h"
32 #define OSCIL_F_BITS 16
33 #define OSCIL_F_BITS_AS_MULTIPLIER 65536
36 #define OSCIL_PHMOD_BITS 16
64 template <u
int16_t NUM_TABLE_CELLS, u
int16_t UPDATE_RATE>
75 Oscil(
const int8_t * TABLE_NAME):table(TABLE_NAME)
118 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
120 phase_fractional = (
unsigned long)phase << OSCIL_F_BITS;
133 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
135 phase_fractional = phase;
145 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
147 return phase_fractional;
167 return (int8_t)pgm_read_byte_near(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
180 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
186 phase_increment_fractional = ((
unsigned long)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
199 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
201 phase_increment_fractional = (
unsigned long)((((
float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * OSCIL_F_BITS_AS_MULTIPLIER);
217 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
220 phase_increment_fractional = (((((
unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
221 << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
225 if ((256UL*NUM_TABLE_CELLS) >= UPDATE_RATE) {
226 phase_increment_fractional = ((
unsigned long)frequency) * ((256UL*NUM_TABLE_CELLS)/UPDATE_RATE);
228 phase_increment_fractional = ((
unsigned long)frequency) / (UPDATE_RATE/(256UL*NUM_TABLE_CELLS));
246 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
253 if (NUM_TABLE_CELLS >= UPDATE_RATE) {
254 phase_increment_fractional = ((
unsigned long)frequency) * (NUM_TABLE_CELLS/UPDATE_RATE);
256 phase_increment_fractional = ((
unsigned long)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS);
275 return (int8_t)pgm_read_byte_near(table + (index & (NUM_TABLE_CELLS - 1)));
296 return ((
unsigned long)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
306 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
308 phase_increment_fractional = phaseinc_fractional;
319 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
325 void incrementPhase()
328 phase_fractional += phase_increment_fractional;
337 #ifdef OSCIL_DITHER_PHASE
338 return (int8_t)pgm_read_byte_near(table + (((phase_fractional + ((
int)(
xorshift96()>>16))) >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
340 return (int8_t)pgm_read_byte_near(table + ((phase_fractional >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
346 unsigned long phase_fractional;
347 volatile unsigned long phase_increment_fractional;
351 const int8_t * table;
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
unsigned long getPhaseFractional()
Get the phase of the Oscil in fractional format.
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
const unsigned long phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
void setFreq(int frequency)
Set the oscillator frequency with an unsigned int.
void setPhaseFractional(unsigned long phase)
Set the phase of the Oscil.
void setPhase(unsigned int phase)
Set the phase of the Oscil.
int8_t phMod(Q15n16 phmod_proportion)
Returns the next sample given a phase modulation value.
Oscil(const int8_t *TABLE_NAME)
Constructor.
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
void setFreq(float frequency)
Set the oscillator frequency with a float.
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
unsigned long xorshift96()
Random number generator.
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
void setFreq_Q16n16(Q16n16 frequency)
Set the frequency using Q16n16 fixed-point number format.
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.