17 #include "MozziGuts.h"
18 #include "mozzi_fixmath.h"
19 #include <util/atomic.h>
22 #define SAMPLE_F_BITS 16
23 #define SAMPLE_F_BITS_AS_MULTIPLIER 65536
27 #define SAMPLE_PHMOD_BITS 16
29 enum interpolation {INTERP_NONE, INTERP_LINEAR};
49 template <
unsigned int NUM_TABLE_CELLS,
unsigned int UPDATE_RATE, u
int8_t INTERP=INTERP_NONE>
61 Sample(
const int8_t * TABLE_NAME):table(TABLE_NAME),endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS)
73 Sample():endpos_fractional(4294967295UL)
96 startpos_fractional = (
unsigned long) startpos << SAMPLE_F_BITS;
106 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
108 phase_fractional = startpos_fractional;
130 endpos_fractional = (
unsigned long) end << SAMPLE_F_BITS;
139 startpos_fractional = 0;
140 endpos_fractional = (
unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS;
173 if (phase_fractional>endpos_fractional){
175 phase_fractional = startpos_fractional + (phase_fractional - endpos_fractional);
181 if(INTERP==INTERP_LINEAR){
183 unsigned int index = phase_fractional >> SAMPLE_F_BITS;
184 out = (int8_t)pgm_read_byte_near(table + index);
185 int8_t difference = (int8_t)pgm_read_byte_near((table + 1) + index) - out;
186 int8_t diff_fraction = (int8_t)(((((
unsigned int) phase_fractional)>>8)*difference)>>8);
187 out += diff_fraction;
189 out = (int8_t)pgm_read_byte_near(table + (phase_fractional >> SAMPLE_F_BITS));
201 return phase_fractional<endpos_fractional;
232 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
234 phase_increment_fractional = ((((
unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
247 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
249 phase_increment_fractional = (
unsigned long)((((
float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * SAMPLE_F_BITS_AS_MULTIPLIER);
265 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
268 phase_increment_fractional = (((((
unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
269 << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
281 return (int8_t)pgm_read_byte_near(table + index);
298 return (((
unsigned long)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << SAMPLE_F_BITS;
308 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
310 phase_increment_fractional = phaseinc_fractional;
320 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
326 void incrementPhase()
328 phase_fractional += phase_increment_fractional;
332 volatile unsigned long phase_fractional;
333 volatile unsigned long phase_increment_fractional;
334 const int8_t * table;
336 unsigned long startpos_fractional, endpos_fractional;
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
void setLoopingOn()
Turns looping on.
void setFreq(int frequency)
Set the oscillator frequency with an unsigned int.
void setEnd(unsigned int end)
Sets the end position in samples from the beginning of the sound.
Sample(const int8_t *TABLE_NAME)
Constructor.
void rangeWholeSample()
Sets the start and end points to include the range of the whole sound table.
unsigned long phaseIncFromFreq(unsigned int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
void setStart(unsigned int startpos)
Sets the starting position in samples.
void start(unsigned int startpos)
Sets a new start position plays the sample from that position.
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Sample.
int8_t next()
Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots the...
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
boolean isPlaying()
Checks if the sample is playing by seeing if the phase is within the limits of its end position...
void start()
Resets the phase (the playhead) to the start position, which will be 0 unless set to another value wi...
void setFreq(float frequency)
Set the sample frequency with a float.
Sample is like Oscil, it plays a wavetable.
void setLoopingOff()
Turns looping off.