frac32 master osc pitch
frac32 slave osc pitch
bool32.rising hard reset both oscillators (non bandlimited)
frac32buffer o1
frac32buffer o2
frac32.s.map.pitch master osc pitch
frac32.s.map.pitch slave osc pitch
uint32_t p1 = 0;
uint32_t p2 = 0;
bool rtrig = 0;
static const int blepvoices = 4;
int16_t *oscp[blepvoices];
int32_t vgain[blepvoices];
uint32_t nextvoice = 0;
for (int j = 0; j < blepvoices; j++) {
oscp[j] = &blept[BLEPSIZE - 1];
vgain[j] = 0;
}
int32_t f1;
int32_t f2;
MTOFEXTENDED(inlet_master + param_master, f1);
MTOFEXTENDED(inlet_slave + param_slave, f2);
int16_t *lastblep = &blept[BLEPSIZE - 1];
if (inlet_reset && !rtrig) {
rtrig = 1;
p1 = 0;
p2 = 0;
} else if (!inlet_reset) {
rtrig = 0;
}
/*
*
* /|
* / |
* / sum1
* / |
* /_______| d1
* /| | a = -----------
* / | | sum1 + d1
* / | |
* / d1 |
* / | |
* / | |
* /______a_____|__1-a___|
*/
// here i do some geometry, trying to avoid irregular phase resets
// p1 and p2 are unsigned 32 bit int variables.. You can see from simplicity
// them as going from 0 (0x00000000) to 1 (0xFFFFFFFF)
uint32_t sum1 = p1 + f1; // integrating frequency in phasor 1
uint32_t sum2 = p2 + f2; // integrating frequency in phasor 2
uint32_t d1 = 0xFFFFFFFF - p1; // distance between p1 (not integrated) and 1
uint32_t sum1_d1 = sum1 + d1; // distance between p1 (integrated) and 0 . This
// is a positive number and makes sense only if the
// phasor has reset (by overflowing the variable)
int32_t a =
134217728.f *
((float)d1 / (float)sum1_d1); // this is a variable that goes from 0 to 2^27
// (i'm confortable working with Q27) and tells
// you where the reset exactly happens
int32_t a_compl = (1 << 27) - a; // 1-a
uint32_t d2 = ___SMMUL(a_compl << 4, f2 << 1); // see the triangle
int32_t ampl;
SINE2TINTERP(sum2 - d2,
ampl); // i'll use sine2t not interpolated.. trying to save some
// energies. If it does not work i'll switch to SINE2TINTERP
if (sum1 < p1) // some blitwork has to be dnoe
{
p2 = d2;
nextvoice = (nextvoice + 1) & (blepvoices - 1);
oscp[nextvoice] = &blept[a_compl >> 21];
vgain[nextvoice] = ampl >> 18;
} else {
p2 = sum2;
}
p1 = sum1;
int32_t r1;
int32_t r2;
SINE2TINTERP(p1, r1);
SINE2TINTERP(p2, r2);
int32_t sum = 0;
for (int i = 0; i < blepvoices; i++) { // sample
int16_t *t = oscp[i];
sum += (16384 - (*t)) * vgain[i]; // t points to the blep table
t += 64;
if (t >= lastblep)
t = lastblep;
oscp[i] = t;
}
outlet_o1 = r1 >> 4;
outlet_o2 = (r2 >> 4) + sum;