fftanalyser

extra big spectral analyzer display using 512 input points fft
Author: Remco van der Most
License: BSD
Github: sss/disp/fftanalyser.axo

Inlets

frac32buffer input

bool32 hold

Outlets

None

Displays

frac4ubyte.vbar v0

frac4ubyte.vbar v1

frac4ubyte.vbar v2

frac4ubyte.vbar v3

frac4ubyte.vbar v4

frac4ubyte.vbar v5

frac4ubyte.vbar v6

frac4ubyte.vbar v7

frac4ubyte.vbar v8

frac4ubyte.vbar v9

frac4ubyte.vbar v10

frac4ubyte.vbar v11

frac4ubyte.vbar v12

frac4ubyte.vbar v13

frac4ubyte.vbar v14

frac4ubyte.vbar v15

frac4ubyte.vbar v16

frac4ubyte.vbar v17

frac4ubyte.vbar v18

frac4ubyte.vbar v19

frac4ubyte.vbar v20

frac4ubyte.vbar v21

frac4ubyte.vbar v22

frac4ubyte.vbar v23

frac4ubyte.vbar v24

frac4ubyte.vbar v25

frac4ubyte.vbar v26

frac4ubyte.vbar v27

frac4ubyte.vbar v28

frac4ubyte.vbar v29

frac4ubyte.vbar v30

frac4ubyte.vbar v31

frac4ubyte.vbar v32

frac4ubyte.vbar v33

frac4ubyte.vbar v34

frac4ubyte.vbar v35

frac4ubyte.vbar v36

frac4ubyte.vbar v37

frac4ubyte.vbar v38

frac4ubyte.vbar v39

frac4ubyte.vbar v40

frac4ubyte.vbar v41

frac4ubyte.vbar v42

frac4ubyte.vbar v43

frac4ubyte.vbar v44

frac4ubyte.vbar v45

frac4ubyte.vbar v46

frac4ubyte.vbar v47

frac4ubyte.vbar v48

frac4ubyte.vbar v49

frac4ubyte.vbar v50

frac4ubyte.vbar v51

frac4ubyte.vbar v52

frac4ubyte.vbar v53

frac4ubyte.vbar v54

frac4ubyte.vbar v55

frac4ubyte.vbar v56

frac4ubyte.vbar v57

frac4ubyte.vbar v58

frac4ubyte.vbar v59

frac4ubyte.vbar v60

frac4ubyte.vbar v61

frac4ubyte.vbar v62

frac4ubyte.vbar v63

vscale dB

Declaration
static const int size1 = 512;
static const int size2 = 1024;
int32_t inbuf[size1];
int32_t outbuf[size1];
int32_t fftbuf[size2];
int32_t hanning_q31[size1];
arm_rfft_instance_q31 rfft;
arm_cfft_radix4_instance_q31 cfft;
int32_t state;
msg_t ThreadX2() {
  int i;
  int n = size1;
  arm_rfft_init_q31(&rfft, size1, 0, 1);
  for (i = 0; i < n; i++) {
    hanning_q31[i] =
        (int32_t)(0.5f * 2147483647.0f * (1.0f - cosf(2.0f * PI * i / n)));
  }
  while (!chThdShouldTerminate()) {
    chThdSleepMilliseconds(20);
    if (state == size1) {
      arm_mult_q31(hanning_q31, &inbuf[0], &inbuf[0], n);
      arm_rfft_q31(&rfft, &inbuf[0], &fftbuf[0]);
      arm_cmplx_mag_q31(&fftbuf[0], outbuf, n / 2);
      // reduce to packed 8bit
      for (i = 0; i < n / 8; i++) {
        int32_t ni;
        uint8_t *nc;
        nc = (uint8_t *)&ni;
        nc[0] = 0xFF & (outbuf[i * 4] >> 19);
        nc[1] = 0xFF & (outbuf[i * 4 + 1] >> 19);
        nc[2] = 0xFF & (outbuf[i * 4 + 2] >> 19);
        nc[3] = 0xFF & (outbuf[i * 4 + 3] >> 19);
        outbuf[i] = ni;
      }
      state = size1 + 1;
    }
  }
}
static msg_t ThreadX(void *arg) { ((attr_parent *)arg)->ThreadX2(); }
WORKING_AREA(waThreadX, 16384);
Thread *Thd;
Init
int i;
for (i = 0; i < size1; i++)
  inbuf[i] = 0;
for (i = 0; i < size1; i++)
  outbuf[i] = 0;
state = 0;
Thd = chThdCreateStatic(waThreadX, sizeof(waThreadX), NORMALPRIO, ThreadX,
                        (void *)this);
Control Rate
if (state < size1) {
  int i;
  for (i = 0; i < 16; i++)
    inbuf[state++] = inlet_in[i];
} else if (state == (size1 + 1)) {
  state = 0;
  if (!inlet_hold) {
    disp_v0 = outbuf[0] << 1;
    disp_v1 = outbuf[1] << 1;
    disp_v2 = outbuf[2] << 1;
    disp_v3 = outbuf[3] << 1;
    disp_v4 = outbuf[4] << 1;
    disp_v5 = outbuf[5] << 1;
    disp_v6 = outbuf[6] << 1;
    disp_v7 = outbuf[7] << 1;
    disp_v8 = outbuf[8] << 1;
    disp_v9 = outbuf[9] << 1;
    disp_v10 = outbuf[10] << 1;
    disp_v11 = outbuf[11] << 1;
    disp_v12 = outbuf[12] << 1;
    disp_v13 = outbuf[13] << 1;
    disp_v14 = outbuf[14] << 1;
    disp_v15 = outbuf[15] << 1;
    disp_v16 = outbuf[16] << 1;
    disp_v17 = outbuf[17] << 1;
    disp_v18 = outbuf[18] << 1;
    disp_v19 = outbuf[19] << 1;
    disp_v20 = outbuf[20] << 1;
    disp_v21 = outbuf[21] << 1;
    disp_v22 = outbuf[22] << 1;
    disp_v23 = outbuf[23] << 1;
    disp_v24 = outbuf[24] << 1;
    disp_v25 = outbuf[25] << 1;
    disp_v26 = outbuf[26] << 1;
    disp_v27 = outbuf[27] << 1;
    disp_v28 = outbuf[28] << 1;
    disp_v29 = outbuf[29] << 1;
    disp_v30 = outbuf[30] << 1;
    disp_v31 = outbuf[31] << 1;
    disp_v32 = outbuf[32] << 1;
    disp_v33 = outbuf[33] << 1;
    disp_v34 = outbuf[34] << 1;
    disp_v35 = outbuf[35] << 1;
    disp_v36 = outbuf[36] << 1;
    disp_v37 = outbuf[37] << 1;
    disp_v38 = outbuf[38] << 1;
    disp_v39 = outbuf[39] << 1;
    disp_v40 = outbuf[40] << 1;
    disp_v41 = outbuf[41] << 1;
    disp_v42 = outbuf[42] << 1;
    disp_v43 = outbuf[43] << 1;
    disp_v44 = outbuf[44] << 1;
    disp_v45 = outbuf[45] << 1;
    disp_v46 = outbuf[46] << 1;
    disp_v47 = outbuf[47] << 1;
    disp_v48 = outbuf[48] << 1;
    disp_v49 = outbuf[49] << 1;
    disp_v50 = outbuf[50] << 1;
    disp_v51 = outbuf[51] << 1;
    disp_v52 = outbuf[52] << 1;
    disp_v53 = outbuf[53] << 1;
    disp_v54 = outbuf[54] << 1;
    disp_v55 = outbuf[55] << 1;
    disp_v56 = outbuf[56] << 1;
    disp_v57 = outbuf[57] << 1;
    disp_v58 = outbuf[58] << 1;
    disp_v59 = outbuf[59] << 1;
    disp_v60 = outbuf[60] << 1;
    disp_v61 = outbuf[61] << 1;
    disp_v62 = outbuf[62] << 1;
    disp_v63 = outbuf[63] << 1;
  }
}
Dispose
chThdTerminate(Thd);

Privacy

© 2024 Zrna Research