InDev2

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

Inlets

frac32.bipolar vib0

frac32.bipolar vib1

frac32.bipolar vib2

Outlets

frac32buffer.bipolar out

Parameters

frac32.s.map.kdecaytime.exp A

frac32.s.map.kdecaytime.exp R1

frac32.s.map.kdecaytime.exp R2

frac32.u.map L

Declaration
class Blit {
public:
  float ctrlAmp[8]; // amp from control
  float amp[8];     // amp for a complete cycle

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

  float subSpl;
  uint16_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++) {
      ctrlAmp[i] = 0.0f;
      amp[i] = 0.0f;
    }
  }
};

uint32_t spl = 0;
Blit blits[12];
float z0 = 0;
float z1 = 0;
float Z = 0;
float y0 = 0;
float y1 = 0;
float Y = 0;
float DCY = 0;
float DCZ = 0;

int8_t gates[128];
int32_t envs[8 * 12];
int32_t envc[8 * 12];
Init
float f = 4186.009f * 2;
for (int i = 0; i < 12; i++) {
  blits[i].init(f);
  f *= 1.059463094f;
}

for (int i = 0; i < 128; i++) {
  gates[i] = 0;
}
for (int i = 0; i < 8 * 12; i++) {
  envs[i] = 0;
  envc[i] = 0;
}
Control Rate
float vib0 = inlet_vib0 * 1e-10f;
float vib1 = inlet_vib1 * 1e-10f;
float vib2 = inlet_vib2 * 1e-10f;
// C#
float f = 4186.009f * 1.059463094f;
blits[0].setF(f *vib0 + f);
f *= 1.059463094f;
blits[1].setF(0.5f * f * vib0 + f);
f *= 1.059463094f;
blits[2].setF(-f *vib0 + f);
f *= 1.059463094f;
blits[3].setF(f *vib1 + f);
f *= 1.059463094f;
blits[4].setF(-f *vib1 + f);
f *= 1.059463094f;
blits[5].setF(-f *vib2 + f);
f *= 1.059463094f;
blits[6].setF(0.9f * f * vib2 + f);
f *= 1.059463094f;
blits[7].setF(-0.9f * f * vib1 + f);
f *= 1.059463094f;
blits[8].setF(f *vib1 + f);
f *= 1.059463094f;
blits[9].setF(-f *vib0 + f);
f *= 1.059463094f;
blits[10].setF(0.7f * f * vib2 + f);
f *= 1.059463094f;
blits[11].setF(0.5f * f * vib2 + f);

float envTot = 0;
for (int i = 0; i < 8 * 12; i++) {
  int32_t b = envs[i];
  if (gates[13 + i] > 10)
    envs[i] = ___SMMLA(0x7FFFFFFF - param_A, (100 << 20) - b, b >> 1)
              << 1; // ascending
  else if (b > param_L)
    envs[i] = ___SMMUL(b, param_R1) << 1;
  else
    envs[i] = ___SMMUL(b, param_R2) << 1;
  envTot += envs[i];
}
int32_t comp = arm::float_to_q(10000000 / sqrtf(envTot + (1 << 27)), 27);
for (int i = 0; i < 8 * 12; i++) {
  envc[i] = ___SMMUL(envs[i], comp);
}
float totAmp = 0;
for (int i = 0; i < 12; i++) {
  for (int oct = 0; oct < 8; oct++) {
    totAmp += (blits[i].ctrlAmp[oct] = arm::q_to_float(envc[i + 12 * oct], 27));
  }
}
Audio Rate
for (int nBlit = 0; nBlit < 12; nBlit++) {
  Blit *blit = blits + nBlit;
  if (spl == blit->nextSpl) {
    float *amp = blit->amp;
    float gy = 0;
    float gz = 0;
    float coefZ = 1.0f / blit->period;
    uint16_t cpt = blit->cpt;

    if ((cpt & 1) == 0) {
      float a = (amp[7] = blit->ctrlAmp[7]);
      gy += a;
      gz -= a * coefZ;
    } else {
      gy += 0.2f * amp[7];
      gz += amp[7] * coefZ;
    }
    coefZ *= 0.5f;
    if ((cpt & 3) == 0) {
      float a = (amp[6] = blit->ctrlAmp[6]);
      gy += a;
      gz -= a * coefZ;
    } else if ((cpt & 3) == 2) {
      gy += 0.2f * amp[6];
      gz += amp[6] * coefZ;
    }
    coefZ *= 0.5f;
    if ((cpt & 7) == 0) {
      float a = (amp[5] = blit->ctrlAmp[5]);
      gy += a;
      gz -= a * coefZ;
    } else if ((cpt & 7) == 4) {
      gy += 0.2f * amp[5];
      gz += amp[5] * coefZ;
    }
    coefZ *= 0.5f;
    if ((cpt & 15) == 0) {
      float a = (amp[4] = blit->ctrlAmp[4]);
      gy += a;
      gz -= a * coefZ;
    } else if ((cpt & 15) == 8) {
      gy += 0.2f * amp[4];
      gz += amp[4] * coefZ;
    }
    coefZ *= 0.5f;
    if ((cpt & 31) == 0) {
      float a = (amp[3] = blit->ctrlAmp[3]);
      gy += a;
      gz -= a * coefZ;
    } else if ((cpt & 31) == 16) {
      gy += 0.2f * amp[3];
      gz += amp[3] * coefZ;
    }
    coefZ *= 0.5f;
    if ((cpt & 63) == 0) {
      float a = (amp[2] = blit->ctrlAmp[2]);
      gy += a;
      gz -= a * coefZ;
    } else if ((cpt & 63) == 32) {
      gy += 0.2f * amp[2];
      gz += amp[2] * coefZ;
    }
    coefZ *= 0.5f;
    if ((cpt & 127) == 0) {
      float a = (amp[1] = blit->ctrlAmp[1]);
      gy += a;
      gz -= a * coefZ;
    } else if ((cpt & 127) == 64) {
      gy += 0.2f * amp[1];
      gz += amp[1] * coefZ;
    }
    coefZ *= 0.5f;

    y0 += gy * (blit->subSpl);
    y1 += gy * (1 - blit->subSpl);
    z0 += gz * (blit->subSpl);
    z1 += gz * (1 - blit->subSpl);
    blit->nextSpl += blit->iPeriod;
    blit->subSpl += blit->fPeriod;
    if (blit->subSpl >= 1) {
      blit->subSpl -= 1;
      blit->nextSpl++;
    }
    blit->cpt++;
  }
}

Z = (Z + z1 - 0.0001f * DCZ);
z1 = z0;
z0 = 0;

DCZ += 0.01f * (y1 + Z - DCZ);

Y = (Y * 0.999999f + y1 + Z - DCZ);
float out = Y - totAmp * 0.125f;
DCY += 0.0001f * (out - DCY);

y1 = y0;
y0 = 0;

outlet_out = arm::float_to_q(out - DCY, 30);

spl++;
Midi Handler
if (status == MIDI_NOTE_ON + attr_midichannel) {
  gates[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