convolution

Convolution - applies an impulse response as a filter to a signal. Table should contain the impulse response, and should be a "table/alloc 16b", not the sdram type (for performance). A 1024 sample impulse response results in 66% load!
Author: Johannes Taelman
License: BSD
Github: filter/convolution.axo

Inlets

frac32buffer input

Outlets

frac32buffer output

Attributes

combo attenuation

spinner length

objref table

Declaration
static const int length = attr_length;
static const int pad = 16;
int16_t circbuf[(length + pad) * 2];
int writeindex = length;
Init
int i;
for (i = 0; i < length * 2; i++) {
  circbuf[i] = 0;
}
Control Rate
if (writeindex == 0)
  writeindex = length + pad;

int i;
for (i = 0; i < BUFSIZE;) {
  int v = inlet_in[i++] >> 12;
  writeindex--;
  circbuf[writeindex] = v;
  circbuf[writeindex + length + pad] = v;
  v = inlet_in[i++] >> 12;
  writeindex--;
  circbuf[writeindex] = v;
  circbuf[writeindex + length + pad] = v;
}

for (i = 0; i < BUFSIZE;) {
  q31_t x0, x1, x2, x3;
  q31_t c0;
  q63_t sum0, sum1, sum2, sum3;
  sum0 = sum1 = sum2 = sum3 = 0;
  q31_t *coeffPtr = (q31_t *)&attr_table.array[length - 2];
  q15_t *statePtr = (q15_t *)(&circbuf[length + writeindex + pad - 2 - i]);
  x0 = *(q31_t *)(statePtr--);
  x1 = *(q31_t *)(statePtr--);
  int j = (length >> 2);
  if (j)
    do {
      c0 = *(q31_t *)(coeffPtr--);
      x2 = *(q31_t *)(statePtr--);
      x3 = *(q31_t *)(statePtr--);
      sum0 = __SMLALD(x0, c0, sum0);
      // sum0 = x0*c0 + x1*c1
      sum1 = __SMLALD(x1, c0, sum1);
      // sum1 = x1*c0 + x2*c1
      sum2 = __SMLALD(x2, c0, sum2);
      // sum2 = x2*c0 + x3*c1
      sum3 = __SMLALD(x3, c0, sum3);
      // sum3 = x3*c0 + x4*c1
      c0 = *(q31_t *)(coeffPtr--);
      x0 = *(q31_t *)(statePtr--);
      x1 = *(q31_t *)(statePtr--);
      sum0 = __SMLALD(x2, c0, sum0);
      // sum0 = x0*c0 + x1*c1 + x2*c2 + x3*c3
      sum1 = __SMLALD(x3, c0, sum1);
      // sum1 = x1*c0 + x2*c1 + x3*c2 + x4*c3
      sum2 = __SMLALD(x0, c0, sum2);
      // sum2 = x2*c0 + x3*c1 + x4*c2 + x5*c3
      sum3 = __SMLALD(x1, c0, sum3);
      // sum3 = x3*c0 + x4*c1 + x5*c2 + x6*c3
    } while (--j);

  outlet_out[i++] = (sum0 >> attr_attenuation);
  outlet_out[i++] = (sum1 >> attr_attenuation);
  outlet_out[i++] = (sum2 >> attr_attenuation);
  outlet_out[i++] = (sum3 >> attr_attenuation);
}

Privacy

© 2024 Zrna Research