public void fir_mem_up(final float[] x,
                         final float[] a,
                         final float[] y,
                         final int N,
                         final int M,
                         final float[] mem)
  {
    int i, j;

    for (i=0; i<N/2; i++)
      xx[2*i] = x[N/2-1-i];
    for (i=0; i<M-1; i+=2)
      xx[N+i] = mem[i+1];

    for (i=0; i<N; i+=4) {
      float y0, y1, y2, y3, x0;
      y0 = y1 = y2 = y3 = 0.f;
      x0 = xx[N-4-i];
      for (j=0; j<M; j+=4) {
        float x1, a0, a1;
        a0 = a[j];
        a1 = a[j+1];
        x1 = xx[N-2+j-i];
        y0 += a0 * x1;
        y1 += a1 * x1;
        y2 += a0 * x0;
        y3 += a1 * x0;
        a0 = a[j+2];
        a1 = a[j+3];
        x0 = xx[N+j-i];
        y0 += a0 * x0;
        y1 += a1 * x0;
        y2 += a0 * x1;
        y3 += a1 * x1;
      }
      y[i] = y0;
      y[i+1] = y1;
      y[i+2] = y2;
      y[i+3] = y3;
    }
    for (i=0; i<M-1; i+=2)
      mem[i+1] = xx[i];
  }