frac32 phase
frac32.bipolar pwm
frac32buffer.bipolar sine wave
frac32.u.map phase
frac32.s.map pwm
objref Table containing the amplitudes (32bit)
objref Tuning table
class osc {
public:
void init();
};
class osc_one : public osc {
public:
int32_t prev1;
int32_t prev2;
void init() {
prev1 = 0;
prev2 = 0;
}
void render(int32_t *pOut, int32_t amp, uint32_t freq, uint32_t phase,
uint32_t pw, float invfreq) {
// pOut: pointer to s32 output buffer, adds values
// amp: s32 amplitude
int32_t a = (int)(invfreq * amp);
int32_t _prev1 = ___SMMUL(phase - freq, phase - freq);
int32_t _prev2 = ___SMMUL(phase - freq + pw, phase - freq + pw);
int i = BUFSIZE;
while (i--) {
int32_t out = *pOut;
int32_t v1 = ___SMMUL(phase, phase);
int32_t d1 = (v1 - _prev1);
out = __SMMLA(d1, a, out);
_prev1 = v1;
int32_t phase2 = phase + pw;
int32_t v2 = ___SMMUL(phase2, phase2);
int32_t d2 = (v2 - _prev2);
out = ___SMMLS(d2, a, out);
_prev2 = v2;
phase += freq;
*pOut++ = out;
}
prev1 = _prev1;
prev2 = _prev2;
}
};
static const int n_octaves = 8;
class chroma {
int phase;
public:
osc_one octaves[n_octaves];
void init() {
phase = 0;
int i;
for (i = 0; i < n_octaves; i++) {
octaves[i].init();
}
};
void render(int freq, int32_t *pOut, int32_t *amp, uint32_t x, int32_t pwm) {
amp += 24;
phase += freq << 4;
uint32_t p = phase;
uint32_t f = freq;
float invfreq = (1 << 25) / (float)freq;
int i;
for (i = 0; i < n_octaves; i++) {
octaves[i].render(pOut, *amp, f, p + x, pwm, invfreq);
amp += 12;
p = p << 1;
f = f << 1;
invfreq = invfreq * 0.5f;
}
}
};
chroma chromas[12];
int i;
for (i = 0; i < 12; i++) {
chromas[i].init();
}
int i;
// clear
for (i = 0; i < BUFSIZE; i++) {
outlet_wave[i] = 0;
}
// sum into output buffer
for (i = 0; i < 12; i++) {
chromas[i].render(attr_tuning.array[i] >> 3, &outlet_wave[0],
&attr_amplitudes.array[i], (param_phase + inlet_phase) << 5,
0x80000000 + ((inlet_pwm + param_pwm) << 4));
}
// output gain
for (i = 0; i < BUFSIZE; i++) {
outlet_wave[i] = outlet_wave[i] << 2;
}