multi

Morphing saw - square - sine oscillator, low cpu load, low aliasing
Author: Sputnki
License: BSD
Github: sptnk/osc/multi.axo

Inlets

frac32 pitch of the oscillator

frac32 morph between saw (0) and square (64)

frac32 smooth the output

Outlets

frac32buffer out

Parameters

frac32.s.map.pitch pitch of the oscillator

frac32.s.map morph between saw (0) and square (64)

frac32.u.map smooth the output

Declaration
uint32_t phase = 0;
int32_t state = 0;
Control Rate
int32_t f;
int32_t pitch = inlet_pitch + param_pitch;
int32_t shape = __SSAT(inlet_shape + param_shape, 28);
int32_t filter = (1 << 27) - __USAT(inlet_soften + param_soften, 27);

MTOFEXTENDED(inlet_pitch + param_pitch, f);

// calculating feedback coefficients in order to reduce aliasing and
// instabilities
int32_t shape_abs = shape > 0 ? shape : -shape;
int32_t parabola =
    ___SMMLA(shape_abs << 2, shape_abs << 3, (1 << 27) - shape_abs);
parabola = ___SMMUL(parabola << 2, parabola << 3);

uint32_t modamt =
    ___SMMUL((1 << 27) - (pitch > 0 ? pitch : 0) << 2, parabola << 3);
modamt = ___SMMUL(modamt << 3, filter << 2);
Audio Rate
phase += f;

int32_t sine_mod = sine2t[((1 << 24) + ___SMMUL(phase, shape) >> 15) &
                          0XFFF]; // amplitude modulation signal (cosine)
int32_t a_per_b = ___SMMUL(state, sine_mod); // amplitude modulated feedback
int32_t phase_mod = ___SMMUL(modamt, a_per_b)
                    << 5; // phase modulation signal to put inside "carrier"

state = sine2t[(phase + phase_mod >> 20) & 0XFFF]; // magic happens here

outlet_out = state >> 4;

// the basic idea was:
// y(t) = sin(wt + A*y(t)*cos(w(t))
// (you can put it in wolfram alpha and see what it does! just set w to some
// value and A to 1, in my object A is set to fix aliasing and instabilities,
// and it's set in k-rate

Privacy

© 2024 Zrna Research