InDev8

Author: Smashed Transistors
License: LGPL
Github: tiar/dev/InDev8.axo

Inlets

frac32.bipolar vib0

frac32.bipolar vib1

frac32.bipolar vib2

frac32.bipolar L2 A

frac32.bipolar L4 A

frac32.bipolar L8 A

frac32.bipolar AL A

frac32.bipolar AH A

frac32.bipolar R A

frac32.bipolar Rev L A

frac32.bipolar Rev R A

frac32.bipolar L2 B

frac32.bipolar L4 B

frac32.bipolar D B

Outlets

frac32buffer.bipolar outA

frac32buffer.bipolar outB

Declaration
class Blit {
public:
  float ctrlAmpA[8]; // amp from control
  float ampA[8];     // amp for a complete cycle
  float ctrlAmpB[8]; // amp from control
  float ampB[8];     // amp for a complete cycle

  float period; // period in sample
  float fPeriod;
  int32_t iPeriod;
  uint32_t nextSpl;

  float subSpl;
  uint32_t cpt; // step counter

  void setF(float f) {
    period = 48000.0f / f;
    iPeriod = (int32_t)period;
    fPeriod = period - iPeriod;
  }
  void init(float f) {
    setF(f);
    for (int i = 0; i < 8; i++) {
      ctrlAmpA[i] = 0.0f;
      ampA[i] = 0.0f;
      ctrlAmpB[i] = 0.0f;
      ampB[i] = 0.0f;
    }
  }
};

uint32_t spl = 0;
uint32_t kcpt = 0;
Blit blits[12];
float z0A = 0, z1A = 0, ZA = 0, DCZA = 0;
float y0A = 0, y1A = 0, YA = 0, DCYA = 0;
float z0B = 0, z1B = 0, ZB = 0, DCZB = 0;
float y0B = 0, y1B = 0, YB = 0, DCYB = 0;

int8_t gates[128];
int8_t trigs[128];
int32_t envsA[8 * 12];
int32_t envcA[8 * 12];
int32_t A_A[25];
int32_t envsB[8 * 12];
int32_t envcB[8 * 12];
float totAmpA_16 = 0;
float totAmpB_16 = 0;
Init
float f = 2.0f * 4186.009f * 1.059463094f;
for (int i = 0; i < 12; i++) {
  blits[i].init(f);
  f *= 1.059463094f;
}

for (int i = 0; i < 128; i++) {
  gates[i] = 0;
  trigs[i] = 0;
}
for (int i = 0; i < 8 * 12; i++) {
  envsA[i] = envcA[i] = 0;
  envsB[i] = envcB[i] = 0;
}
Control Rate
float vib0 = inlet_vib0 * 1e-10f;
float vib1 = inlet_vib1 * 1e-10f;
float vib2 = inlet_vib2 * 1e-10f;
// C#
float sqr12 = 1.059463094f;
float f = 2.0f * 4186.009f * sqr12;
blits[0].setF(f *vib0 + f);
f *= sqr12;
blits[1].setF(0.7f * f * vib0 + f);
f *= sqr12;
blits[2].setF(-f *vib0 + f);
f *= sqr12;
blits[3].setF(f *vib1 + f);
f *= sqr12;
blits[4].setF(-f *vib1 + f);
f *= sqr12;
blits[5].setF(-f *vib2 + f);
f *= sqr12;
blits[6].setF(0.9f * f * vib2 + f);
f *= sqr12;
blits[7].setF(-0.9f * f * vib1 + f);
f *= sqr12;
blits[8].setF(f *vib1 + f);
f *= sqr12;
blits[9].setF(-f *vib0 + f);
f *= sqr12;
blits[10].setF(0.7f * f * vib2 + f);
f *= sqr12;
blits[11].setF(0.8f * f * vib2 + f);
if ((kcpt & 1) == 0) {
  int32_t L2_A = inlet_L2_space_A >> 3;
  int32_t L4_A = inlet_L4_space_A >> 3;
  int32_t L8_A = inlet_L8_space_A >> 3;

  int32_t AH_A = ((inlet_AH_space_A * 3) >> 1) - (36 << 21);
  int32_t AL_A = ((inlet_AL_space_A * 3) >> 1) - (36 << 21);

  for (int i = 0; i < 24; i++) {
    int32_t a = i * (0x3FFFFFFF / 24);
    a = ___SMMLA(a, AH_A - AL_A, AL_A >> 2) << 2;
    int32_t tmp;
    MTOFEXTENDED(-a, tmp);
    A_A[i] = tmp;
  }
  int32_t tmp;
  MTOFEXTENDED(-AH_A, tmp);
  A_A[24] = tmp;

  int32_t R_A;
  {
    int32_t tmp = ((inlet_R_space_A * 5) >> 2) - (18 << 21);
    MTOFEXTENDED(-tmp, R_A);
  }
  R_A = 0x7FFFFFFF - R_A;

  int32_t Rev_R_A;
  MTOFEXTENDED(-inlet_Rev_space_R_space_A, Rev_R_A);
  Rev_R_A = 0x7FFFFFFF - Rev_R_A;

  int32_t cA;
  float envTotA = 0;
  cA = A_A[0];
  for (int i = 0; i <= 25; i++) {
    int32_t b = envsA[i];
    if (gates[13 + i] > 10)
      envsA[i] = ___SMMLA(cA, (1 << 27) - b, b >> 1) << 1; // ascending
    else if (envsA[i] > inlet_Rev_space_L_space_A)
      envsA[i] = ___SMMUL(b, R_A) << 1;
    else
      envsA[i] = ___SMMUL(b, Rev_R_A) << 1;
    envTotA += envsA[i];
  }
  for (int i = 26; i < 49; i++) {
    int32_t b = envsA[i];
    if (gates[13 + i] > 10)
      envsA[i] = ___SMMLA(A_A[i - 25], (1 << 27) - b, b >> 1) << 1; // ascending
    else if (envsA[i] > inlet_Rev_space_L_space_A)
      envsA[i] = ___SMMUL(b, R_A) << 1;
    else
      envsA[i] = ___SMMUL(b, Rev_R_A) << 1;
    envTotA += envsA[i];
  }
  cA = A_A[24];
  for (int i = 49; i < 8 * 12; i++) {
    int32_t b = envsA[i];
    if (gates[13 + i] > 10)
      envsA[i] = ___SMMLA(cA, (1 << 27) - b, b >> 1) << 1; // ascending
    else if (envsA[i] > inlet_Rev_space_L_space_A)
      envsA[i] = ___SMMUL(b, R_A) << 1;
    else
      envsA[i] = ___SMMUL(b, Rev_R_A) << 1;
    envTotA += envsA[i];
  }

  // ponder envTotA with L2_A L4_A and L8_A
  envTotA *= (L2_A + L4_A + L8_A) * (1.0f / (1 << 27));

  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  // compression and combination
  int32_t compA = arm::float_to_q(10000000 / sqrtf(envTotA + (1 << 27)), 27);

  for (int i = 0; i < 12; i++) {
    envcA[i] =
        ___SMMUL(___SMMLA(envsA[i], L4_A, ___SMMUL(envsA[i + 12], L8_A)), compA)
        << 5;
  }
  for (int i = 12; i < 8 * 12 - 12; i++) {
    envcA[i] = ___SMMUL(___SMMLA(envsA[i], L4_A,
                                 ___SMMLA(envsA[i + 12], L8_A,
                                          ___SMMUL(envsA[i - 12], L2_A))),
                        compA)
               << 5;
  }
  for (int i = 8 * 12 - 12; i < 8 * 12; i++) {
    envcA[i] =
        ___SMMUL(___SMMLA(envsA[i], L4_A, ___SMMUL(envsA[i - 12], L2_A)), compA)
        << 5;
  }
  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  // offset used to stabilize the output integrator
  totAmpA_16 = 0;
  for (int i = 0; i < 12; i++) {
    for (int oct = 0; oct < 8; oct++) {
      totAmpA_16 +=
          (blits[i].ctrlAmpA[oct] = arm::q_to_float(envcA[i + 12 * oct], 27));
    }
  }
  totAmpA_16 *= 1 / 16.0f;

} else {

  // _____________________________________________________________________

  int32_t L2_B = inlet_L2_space_B >> 3;
  int32_t L4_B = inlet_L4_space_B >> 3;
  int32_t D_B;
  {
    int32_t tmp = ((inlet_D_space_B * 5) >> 2) - (18 << 21);
    MTOFEXTENDED(-tmp, D_B);
  }
  D_B = 0x7FFFFFFF - D_B;

  float envTotB = 0;

  for (int i = 0; i < 8 * 12; i++) {
    if (trigs[13 + i] > 10)
      envsB[i] = 1 << 27;
    else
      envsB[i] = ___SMMUL(envsB[i], D_B) << 1;
    envTotB += envsB[i];
  }
  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  // compression and combination
  envTotB *= (L2_B + L4_B) * (1.0f / (1 << 27));

  int32_t compB = arm::float_to_q(10000000 / sqrtf(envTotB + (1 << 27)), 27);
  for (int i = 0; i < 12; i++) {
    envcB[i] = ___SMMUL(___SMMUL(envsB[i], L4_B), compB) << 5;
  }
  for (int i = 12; i < 8 * 12; i++) {
    envcB[i] =
        ___SMMUL(___SMMLA(envsB[i], L4_B, ___SMMUL(envsB[i - 12], L2_B)), compB)
        << 5;
  }
  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  // offset used to stabilize the output integrator
  totAmpB_16 = 0;
  for (int i = 0; i < 12; i++) {
    for (int oct = 0; oct < 8; oct++) {
      totAmpB_16 +=
          (blits[i].ctrlAmpB[oct] = arm::q_to_float(envcB[i + 12 * oct], 27));
    }
  }
  totAmpB_16 *= 1 / 16.0f;
  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

  for (int i = 0; i < 128; i++) {
    trigs[i] = 0;
  }
}
kcpt++;
// _____________________________________________________________________
Audio Rate
for (int nBlit = 0; nBlit < 12; nBlit++) {
  Blit *blit = blits + nBlit;
  if (spl == blit->nextSpl) {
    float *ampA = blit->ampA;
    float *ampB = blit->ampB;
    float gyA = 0, gzA = 0, gyB = 0, gzB = 0;
    float coefZ = (1.0f / 128.0f) / blit->period;
    uint16_t cpt = blit->cpt;

    //  \                     \
    //  | \                   | \
    //  |   \_________________|   \_________________

    uint16_t c = cpt;
    uint16_t m = 4 * 128 * 2;
    uint16_t p = 256;
    for (int oct = 0; oct < 8; oct++) {
      m >>= 1;
      if (c >= m)
        c -= m;
      // 0
      if (c == 0) {
        float a = (ampA[oct] = blit->ctrlAmpA[oct]);
        gyA += a;
        gzA -= a * coefZ;
        a = (ampB[oct] = blit->ctrlAmpB[oct]);
        gyB += a;
        gzB -= a * coefZ;
      }
      // 1
      p >>= 1;
      if (c == p) { // slope change
        gzA += ampA[oct] * coefZ;
        gzB += ampB[oct] * coefZ;
      }
      coefZ *= 2;
    }
    cpt++;
    if (cpt >= 512)
      cpt -= 512;
    float a = blit->subSpl;
    float _a = 1 - a;
    y0A += gyA * a;
    y1A += gyA * _a;
    z0A += gzA * a;
    z1A += gzA * _a;
    y0B += gyB * a;
    y1B += gyB * _a;
    z0B += gzB * a;
    z1B += gzB * _a;
    blit->nextSpl += blit->iPeriod;
    blit->subSpl += blit->fPeriod;
    if (blit->subSpl >= 1) {
      blit->subSpl -= 1;
      blit->nextSpl++;
    }
    blit->cpt = cpt;
  }
}
//__________________________________________________
// double integration to get outA
ZA = (ZA + z1A - 0.0001f * DCZA);
z1A = z0A;
z0A = 0;

YA = (YA * 0.999999f + y1A + ZA - DCZA);
DCZA += 0.01f * (y1A + ZA - DCZA);

float outA = YA - totAmpA_16;
DCYA += 0.0001f * (outA - DCYA);

y1A = y0A;
y0A = 0;

outlet_outA = arm::float_to_q(outA - DCYA, 30);

//__________________________________________________
// double integration to get outB
ZB = (ZB + z1B - 0.0001f * DCZB);
z1B = z0B;
z0B = 0;

YB = (YB * 0.999999f + y1B + ZB - DCZB);
DCZB += 0.01f * (y1B + ZB - DCZB);

float outB = YB - totAmpB_16;
DCYB += 0.0001f * (outB - DCYB);

y1B = y0B;
y0B = 0;

outlet_outB = arm::float_to_q(outB - DCYB, 30);

spl++;
Midi Handler
if (status == MIDI_NOTE_ON + attr_midichannel) {
  gates[data1 & 0x7F] = data2 ? 100 : 0;
  trigs[data1 & 0x7F] = data2 ? 100 : 0;
} else if (status == MIDI_NOTE_OFF + attr_midichannel) {
  gates[data1 & 0x7F] = 0;
} else if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
           (data1 == MIDI_C_ALL_NOTES_OFF)) {
  for (int i = 0; i < 128; i++)
    gates[data1 & 0x7F] = 0;
}

Privacy

© 2024 Zrna Research