Wave3b

Diff polynomial Wavetable with phase modulation. Experimental. Note: - hard coded pre integrated table (see Local Data) - optimizations (more or less dirty) - should be oversampled x2 or x4 - tried 2nd order with 32bits ->KO
Author: Smashed Transistors
License: LGPL
Github: tiar/osc/Wave3b.axo

Inlets

frac32.bipolar pitch

frac32buffer.bipolar m

frac32.positive mEnv

Outlets

frac32buffer.bipolar selfPM wave

Parameters

frac32.s.map.pitch pitch

frac32.u.map I1

frac32.u.map I0

Declaration
// _____________________________________________________________________
const int32_t *table_dv_q20(void) {
  static const int32_t dv[] = {
      341270,  293052,  214566,  130383,  59189,   8646,    -22360,  -38891,
      -46224,  -48113,  -46441,  -41505,  -32547,  -18451,  1347,    25778,
      51101,   70452,   74881,   56674,   14201,   -44947,  -106115, -154580,
      -182276, -189636, -182696, -168813, -153723, -140485, -129654, -119973,
      -109280, -95565,  -77974,  -57272,  -35219,  -12971,  10392,   37737,
      71697,   111739,  152890,  187564,  209394,  216147,  209859,  194666,
      174201,  149890,  120490,  82761,   33197,   -29238,  -100133, -168374,
      -218951, -239722, -227925, -191189, -142375, -92968,  -49664,  -14725,
      12158,   32437,   48089,   61406,   74779,   90374,   109670,  132828,
      157819,  179489,  189315,  177198,  136199,  68565,   -11773,  -84294,
      -132125, -149526, -141598, -118530, -89908,  -61992,  -37601,  -17067,
      743,     17689,   35835,   56951,   81818,   109192,  134493,  148901,
      140401,  98459,   21648,   -76927,  -172884, -242400, -273781, -270153,
      -243551, -206983, -169647, -135977, -106831, -81204,  -57761,  -35991,
      -16840,  -2516,   4697,    4268,    -1128,   -5620,   -2111,   14378,
      43709,   80157,   115241,  142015,  157859,  164394,  165468,  164886,
      164886,  165468,  164394,  157859,  142015,  115241,  80157,   43709,
      14378,   -2111,   -5620,   -1128,   4268,    4697,    -2516,   -16840,
      -35991,  -57761,  -81204,  -106831, -135977, -169647, -206983, -243551,
      -270153, -273781, -242400, -172884, -76927,  21648,   98459,   140401,
      148901,  134493,  109192,  81818,   56951,   35835,   17689,   743,
      -17067,  -37601,  -61992,  -89908,  -118530, -141598, -149526, -132125,
      -84294,  -11773,  68565,   136199,  177198,  189315,  179489,  157819,
      132828,  109670,  90374,   74779,   61406,   48089,   32437,   12158,
      -14725,  -49664,  -92968,  -142375, -191189, -227925, -239722, -218951,
      -168374, -100133, -29238,  33197,   82761,   120490,  149890,  174201,
      194666,  209859,  216147,  209394,  187564,  152890,  111739,  71697,
      37737,   10392,   -12971,  -35219,  -57272,  -77974,  -95565,  -109280,
      -119973, -129654, -140485, -153723, -168813, -182696, -189636, -182276,
      -154580, -106115, -44947,  14201,   56674,   74881,   70452,   51101,
      25778,   1347,    -18451,  -32547,  -41505,  -46441,  -48113,  -46224,
      -38891,  -22360,  8646,    59189,   130383,  214566,  293052,  341270};
  return dv;
}
// _____________________________________________________________________
// Info: max/MAX_VALUE=0.015891638%
const int32_t *table_v_q20(void) {
  static const int32_t v[] = {
      0,        341270,   634322,   848888,   979271,   1038460,  1047106,
      1024746,  985854,   939630,   891517,   845075,   803570,   771023,
      752572,   753919,   779697,   830799,   901251,   976132,   1032806,
      1047007,  1002059,  895944,   741363,   559088,   369452,   186756,
      17943,    -135780,  -276265,  -405918,  -525891,  -635171,  -730736,
      -808710,  -865982,  -901201,  -914172,  -903780,  -866043,  -794347,
      -682607,  -529718,  -342153,  -132759,  83388,    293247,   487912,
      662113,   812003,   932493,   1015253,  1048450,  1019212,  919079,
      750705,   531755,   292033,   64108,    -127081,  -269456,  -362424,
      -412088,  -426813,  -414655,  -382218,  -334128,  -272723,  -197943,
      -107569,  2101,     134929,   292748,   472236,   661551,   838750,
      974949,   1043514,  1031741,  947446,   815322,   665795,   524197,
      405667,   315759,   253767,   216166,   199100,   199843,   217532,
      253367,   310318,   392136,   501327,   635820,   784721,   925122,
      1023581,  1045229,  968302,   795418,   553018,   279237,   9084,
      -234467,  -441450,  -611097,  -747074,  -853905,  -935108,  -992869,
      -1028860, -1045700, -1048216, -1043518, -1039250, -1040378, -1045998,
      -1048109, -1033730, -990021,  -909864,  -794623,  -652608,  -494749,
      -330354,  -164886,  0,        164886,   330354,   494749,   652608,
      794623,   909864,   990021,   1033730,  1048109,  1045998,  1040378,
      1039250,  1043518,  1048216,  1045700,  1028860,  992869,   935108,
      853905,   747074,   611097,   441450,   234467,   -9084,    -279237,
      -553018,  -795418,  -968302,  -1045229, -1023581, -925122,  -784721,
      -635820,  -501327,  -392136,  -310318,  -253367,  -217532,  -199843,
      -199100,  -216166,  -253767,  -315759,  -405667,  -524197,  -665795,
      -815322,  -947446,  -1031741, -1043514, -974949,  -838750,  -661551,
      -472236,  -292748,  -134929,  -2101,    107569,   197943,   272723,
      334128,   382218,   414655,   426813,   412088,   362424,   269456,
      127081,   -64108,   -292033,  -531755,  -750705,  -919079,  -1019212,
      -1048450, -1015253, -932493,  -812003,  -662113,  -487912,  -293247,
      -83388,   132759,   342153,   529718,   682607,   794347,   866043,
      903780,   914172,   901201,   865982,   808710,   730736,   635171,
      525891,   405918,   276265,   135780,   -17943,   -186756,  -369452,
      -559088,  -741363,  -895944,  -1002059, -1047007, -1032806, -976132,
      -901251,  -830799,  -779697,  -753919,  -752572,  -771023,  -803570,
      -845075,  -891517,  -939630,  -985854,  -1024746, -1047106, -1038460,
      -979271,  -848888,  -634322,  -341270};
  return v;
}
// Info: max/MAX_VALUE=0.048822273%
// _____________________________________________________________________
const int32_t *table_Iv_q20(void) {
  static const int32_t Iv[] = {
      -19987852, -19817216, -19329420, -18587815, -17673735, -16664869,
      -15622086, -14586160, -13580860, -12618118, -11702545, -10834249,
      -10009926, -9222630,  -8460832,  -7707587,  -6940778,  -6135530,
      -5269505,  -4330814,  -3326345,  -2286438,  -1261905,  -312904,
      505750,    1155976,   1620246,   1898350,   2000700,   1941781,
      1735759,   1394667,   928763,    348232,    -334722,   -1104445,
      -1941791,  -2825383,  -3733069,  -4642045,  -5526957,  -6357152,
      -7095629,  -7701791,  -8137727,  -8375183,  -8399869,  -8211552,
      -7820972,  -7245959,  -6508901,  -5636653,  -4662780,  -3630928,
      -2597097,  -1627952,  -793059,   -151829,   260065,    438135,
      406649,    208381,    -107559,   -494815,   -914266,   -1335000,
      -1733436,  -2091610,  -2395035,  -2630368,  -2783124,  -2835859,
      -2767344,  -2553506,  -2171014,  -1604120,  -853969,   52880,
      1062111,   2099738,   3089332,   3970716,   4711274,   5306270,
      5771202,   6131916,   6416679,   6651646,   6859279,   7058750,
      7267437,   7502887,   7784730,   8135957,   8582688,   9151262,
      9861533,   10716454,  11690806,  12725211,  13731976,  14613836,
      15288054,  15704181,  15848342,  15735651,  15397693,  14871420,
      14192334,  13391845,  12497339,  11533350,  10522486,  9485206,
      8438249,   7392382,   6350998,   5311184,   4267997,   3220943,
      2180024,   1168148,   218205,    -634039,   -1357654,  -1931332,
      -2343884,  -2591504,  -2673947,  -2591504,  -2343884,  -1931332,
      -1357654,  -634039,   218205,    1168148,   2180024,   3220943,
      4267997,   5311184,   6350998,   7392382,   8438249,   9485206,
      10522486,  11533350,  12497339,  13391845,  14192334,  14871420,
      15397693,  15735651,  15848342,  15704181,  15288054,  14613836,
      13731976,  12725211,  11690806,  10716454,  9861533,   9151262,
      8582688,   8135957,   7784730,   7502887,   7267437,   7058750,
      6859279,   6651646,   6416679,   6131916,   5771202,   5306270,
      4711274,   3970716,   3089332,   2099738,   1062111,   52880,
      -853969,   -1604120,  -2171014,  -2553506,  -2767344,  -2835859,
      -2783124,  -2630368,  -2395035,  -2091610,  -1733436,  -1335000,
      -914266,   -494815,   -107559,   208381,    406649,    438135,
      260065,    -151829,   -793059,   -1627952,  -2597097,  -3630928,
      -4662780,  -5636653,  -6508901,  -7245959,  -7820972,  -8211552,
      -8399869,  -8375183,  -8137727,  -7701791,  -7095629,  -6357152,
      -5526957,  -4642045,  -3733069,  -2825383,  -1941791,  -1104445,
      -334722,   348232,    928763,    1394667,   1735759,   1941781,
      2000700,   1898350,   1620246,   1155976,   505750,    -312904,
      -1261905,  -2286438,  -3326345,  -4330814,  -5269505,  -6135530,
      -6940778,  -7707587,  -8460832,  -9222630,  -10009926, -10834249,
      -11702545, -12618118, -13580860, -14586160, -15622086, -16664869,
      -17673735, -18587815, -19329420, -19817216};
  return Iv;
}
// _____________________________________________________________________
// Info: max/MAX_VALUE=0.93075687%
uint32_t p; // phase
int32_t dp; // delta phase aka freq
int32_t x0, x1, I1_0, I1_1;
int32_t kMI;      // Modulation Index
int32_t aMI, dMI; // interp Modulation Index

// _____________________________________________________________________
Init
// _____________________________________________________________________
p = 0;
dp = 1;
x0 = 0;
x1 = 1;
I1_0 = I1_1 = 0;
aMI = dMI = kMI = 0;
// _____________________________________________________________________
Control Rate
// _____________________________________________________________________
MTOFEXTENDED(param_pitch + inlet_pitch, dp);
dp >>= 4; // p is uq28 to let room for phase modulation
          // (need to calculate x0 - x1 even with over modulation)
// _____________________________________________________________________
// Modulation Index (ie modulation depth)
// mEnv control [0 64] -> [I0 I1]
kMI = ___SMMUL(param_I1 << 2, inlet_mEnv << 4);
kMI = ___SMMLA(param_I0 << 2, (((1 << 27) - 1) - inlet_mEnv) << 4, kMI);
dMI = (kMI - aMI) >> 4; // for arate interpolation
// _____________________________________________________________________
//                                                     Audio rate loops
for (int j = 0; j < BUFSIZE; j++) {
  p += dp; // phase increment
  if (p >= 0x40000000) {
    p -= 0x10000000;
    x0 -= 0x10000000; // p, xO and x1 must be consistent
  }
  x1 = x0;
  I1_1 = I1_0;
  x0 = p + (___SMMUL(inlet_m[j], aMI) << 5);
  x1 += (x0 == x1) ? 1 : 0; // avoids ill case

  // differentiation part 1/3
  // we launch the float div here (14 cycles !!)
  // so that integer ops executes in parallel :D
  float inv = ((float)(1 << 27)) / ((float)(x0 - x1));

  // Now we do as many int ops as we can to fill ~14 cycles

  // the interpolation coefficient
  int32_t a = (x0 & 0x000FFFFF) << 11; // 0 -> 1 q31

  // the segment number
  uint32_t i = (x0 & 0x0FF00000) >> 20; // [0 255]

  // polynomial calc of the integrand on segment i at position a
  // the polynomial is
  // I1_0 = Iv + a * v + (a^2/2) dv
  // it is the integrand of v + a*dv

  // a^2/2  q31
  int32_t a2_2 = ___SMMUL(a, a);
  I1_0 = ___SMMUL(table_v_q20()[i], a);
  I1_0 = ___SMMLA(table_dv_q20()[i], a2_2, I1_0);
  I1_0 = table_Iv_q20()[i] + (I1_0 << 1);

  // we differentiate the integrand in the interval
  // x0 x1: ie in the interval between now and the preceding
  // input.

  // differentiation part 2/3
  int32_t diff = I1_0 - I1_1;

  aMI += dMI; // Modulation Index interpolation for next iteration

  // now, the result of our float division should be available.
  // we haven't wasted our time waiting for it.

  // differentiation part 3/3
  outlet_wave[j] = (int32_t)(diff * inv);
}
// _____________________________________________________________________

Privacy

© 2024 Zrna Research