sine sync cheap

Dual sine oscillator. Slave osc (o2) is hardsynced to master osc (o1). Both oscillators can be phase-reset
Author: Sputnki
License: BSD
Github: sptnk/osc/sine sync cheap.axo

Inlets

bool32.rising hard reset inlet

frac32 master osc pitch

frac32 slave osc pitch

Outlets

frac32buffer master osc

frac32buffer slave osc

Parameters

frac32.s.map.pitch master osc pitch

frac32.s.map.pitch slave osc pitch

Declaration
uint32_t p1 = 0;
uint32_t p2 = 0;

bool rtrig = 0;
Control Rate
int32_t f1;
int32_t f2;
MTOFEXTENDED(inlet_master + param_master, f1);
MTOFEXTENDED(inlet_slave + param_slave, f2);

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___|
 */
Audio Rate
// 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

if (sum1 < p1) {
  p2 = d2;
} else {
  p2 = sum2;
}

p1 = sum1;

int32_t r1;
int32_t r2;

SINE2TINTERP(p1, r1);
SINE2TINTERP(p2, r2);

outlet_o1 = r1 >> 4;
outlet_o2 = r2 >> 4;

Privacy

© 2024 Zrna Research