orth4

4x4 fixed orthogonal matrix
Author: Smashed Transistors
License: LGPL
Github: tiar/FDN/orth4.axo

Inlets

frac32buffer in0

frac32buffer in1

frac32buffer in2

frac32buffer in3

Outlets

frac32buffer out0

frac32buffer out1

frac32buffer out2

frac32buffer out3

Attributes

text rotations

Declaration
// local
static const int N = 4;
int32_t M[N][N];
int32_t tmp[N][N];
int32_t R[N][N];

int32_t sin2t_q27(uint32_t p) {
  int32_t a = (p & ((1 << 20) - 1)) << 8; // q28
  uint32_t i = p >> 20;
  return ___SMMLA(a, sine2t[i + 1] - sine2t[i], sine2t[i] >> 4);
}
int32_t cos2t_q27(uint32_t p) { return sin2t_q27(p + (1UL << 30)); }
// M q27;
void setR(int axis1, int axis2, uint32_t ia) {
  for (int j = 0; j < N; j++) {
    for (int i = 0; i < N; i++) {
      R[j][i] = i == j ? 1 << 27 : 0;
    }
  }
  int32_t c = cos2t_q27(ia);
  int32_t s = sin2t_q27(ia);
  R[axis1][axis1] = c;
  R[axis1][axis2] = -s;
  R[axis2][axis1] = s;
  R[axis2][axis2] = c;
}
void setR(int axis1, int axis2, float angle) {
  setR(axis1, axis2, (uint32_t)(angle * 11930464.71f)); // (2^32)/360
}

void MxR(void) {
  for (int j = 0; j < N; j++) {
    for (int i = 0; i < N; i++) {
      tmp[j][i] = M[j][i];
    }
  }
  for (int j = 0; j < N; j++) {
    for (int i = 0; i < N; i++) {
      M[j][i] = 0;
      for (int k = 0; k < N; k++) {
        M[j][i] += ___SMMUL(tmp[j][k], R[k][i]) << 5;
      }
    }
  }
}
void rot(int axis1, int axis2, float angle) {
  setR(axis1 % N, axis2 % N, angle);
  MxR();
}
void negLine(int j) {
  for (int i = 0; i < N; i++) {
    M[j][i] = -M[j][i];
  }
}
void negCol(int i) {
  for (int j = 0; j < N; j++) {
    M[j][i] = -M[j][i];
  }
}
void randR(uint32_t seed) {
  uint32_t r = seed * 69069 + 1;
  for (int k = 0; k < 4; k++) {
    for (int j = 0; j < N; j++) {
      for (int i = j + 1; i < N; i++) {
        setR(i, j, r = r * 69069 + 1);
        MxR();
      }
    }
  }
}
void randO(uint32_t seed) {
  uint32_t r = seed * 69069 + 1;
  for (int k = 0; k < 4; k++) {
    for (int j = 0; j < N; j++) {
      for (int i = j + 1; i < N; i++) {
        setR(i, j, r = r * 69069 + 1);
        MxR();
      }
      r = r * 69069 + 1;
      negLine((r >> 24) % N);
    }
  }
}
void transpose(void) {
  for (int j = 0; j < N; j++) {
    for (int i = 0; i < N; i++) {
      tmp[j][i] = M[j][i];
    }
  }
  for (int j = 0; j < N; j++) {
    for (int i = 0; i < N; i++) {
      M[j][i] = tmp[i][j];
    }
  }
}
Init
for (int j = 0; j < N; j++) {
  for (int i = 0; i < N; i++) {
    M[j][i] = (i == j) ? 1 << 27 : 0;
  }
}
{ attr_rotations }
Control Rate
int32_t *m;
int32_t m0, m1, m2, m3;
m = M[0];
m0 = m[0];
m1 = m[1];
m2 = m[2];
m3 = m[3];
for (int i = 0; i < BUFSIZE; i++) {
  outlet_out0[i] =
      ___SMMLA(inlet_in0[i], m0,
               ___SMMLA(inlet_in1[i], m1,
                        ___SMMLA(inlet_in2[i], m2, ___SMMUL(inlet_in3[i], m3))))
      << 5;
}
m = M[1];
m0 = m[0];
m1 = m[1];
m2 = m[2];
m3 = m[3];
for (int i = 0; i < BUFSIZE; i++) {
  outlet_out1[i] =
      ___SMMLA(inlet_in0[i], m0,
               ___SMMLA(inlet_in1[i], m1,
                        ___SMMLA(inlet_in2[i], m2, ___SMMUL(inlet_in3[i], m3))))
      << 5;
}
m = M[2];
m0 = m[0];
m1 = m[1];
m2 = m[2];
m3 = m[3];
for (int i = 0; i < BUFSIZE; i++) {
  outlet_out2[i] =
      ___SMMLA(inlet_in0[i], m0,
               ___SMMLA(inlet_in1[i], m1,
                        ___SMMLA(inlet_in2[i], m2, ___SMMUL(inlet_in3[i], m3))))
      << 5;
}
m = M[3];
m0 = m[0];
m1 = m[1];
m2 = m[2];
m3 = m[3];
for (int i = 0; i < BUFSIZE; i++) {
  outlet_out3[i] =
      ___SMMLA(inlet_in0[i], m0,
               ___SMMLA(inlet_in1[i], m1,
                        ___SMMLA(inlet_in2[i], m2, ___SMMUL(inlet_in3[i], m3))))
      << 5;
}

Privacy

© 2024 Zrna Research