(UNO)フーリエ変換(fix_fft.h)で遊ぶ(2)




参考

https://qiita.com/caa45040/items/e07580fe226ff510b635

フーリエ変換以降の処理


結果

![o_coq330.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/06e2c091-a84e-f95a-f61a-55a328e21deb.jpeg)







プログラム



```c++



//インクルド
#include "Arduino.h"
//#include "fix_fft.h"                  // 8-bit FFT library modified for Arduino


//初期化
void setup() {

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println();
  Serial.println("START");
  Serial.println();

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

}//setup


//メインループ
// the loop function runs over and over again forever
void loop() {

  //fix_fftr(data_a, 6, 0);

  //0 1 2 3 4 5 6 7 8 9 A B C D E F
  char buff_a[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    };

  char data_a[64] = {
    //1  2  3  4   5  6  7  8
    -1, 0, 0, 0, -44, -1, -1, 0, //1
    0, 0, -1, -1,  0, -1, -1, 0, //2
    -1, 0, 0, 0, 44, -1, -1, 0, //3
    -2, 0, -1, -1, -2, -1, -1, -2, //4
    -1, -2, -2, -1, 106, 0, 0, 0, //5
    -2, 0, 0, -1, -1, 0, 0, 0, //6
    -1, 0, 0, -1, 18, 0, 0, 0, //7
    0, 0, 0, -1,  1, 0, 0, 0 //8
  };

  //int8_t reordered[32];
  char reordered[32];
  for (int i = 0; i < 32; i++) {
    if (i % 2 != 0) {
      //奇数の時は、後半
      reordered[i] = data_a[i / 2 + 16];
    } else {
      //偶数の時は、前半
      reordered[i] = data_a[i / 2];
    }//if
  }//for

  //データにコピーする
  for (int i = 0; i < 32; i++) {
    data_a[i] = reordered[i];
  }//for

#define TIME_FACTOR             2
#define SCALE_FACTOR            8

  const float coeff = 1. / TIME_FACTOR;
  const float anti_coeff = (TIME_FACTOR - 1.) / TIME_FACTOR;

  for (int count = 0; count < 32; count++) {

    //0より小さい時は、0でそれ以外は、8倍する。
    if (data_a[count] < 0) {
      data_a[count] = 0;
    } else {
      data_a[count] *= SCALE_FACTOR; // x(8)
    }//if

    //　1/2にする
    //                                        0.5                                 0.5
    data_a[count] = (float) buff_a[count] * anti_coeff + (float) data_a[count] * coeff;
    buff_a[count] = data_a[count];

    if (data_a[count] > 63) {
      data_a[count] = 63;
    }//if

  }//for

  //結果の表示
  Serial.println(">>>");
  int uu = 1;
  for (int i = 0; i < 32; i++) {

    //printf("%d,",data_a[i]);
    Serial.print((int)data_a[i]);
    Serial.print(',');

    uu++;
    if (uu > 8) {
      uu = 1;
      //printf("\n");
      Serial.println();
    }//if
  }//for
  Serial.println("<<<");

  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);  // wait for a second

}//loop



```


-------------------------------------------


●おまけ

------------------------------------------

https://github.com/colonelwatch/attiny85-spectrum


後半の処理の元


buff[] は、空
anti_coeff　は、0.5
coeffは、0.5
SCALE_FACTOR は、8
LOG_OUTPUT は、空

```c++


  fix_fftr(data, 6, 0);                             // Performing real FFT

  // Reordering the data so that the left/right halves become odd/even, based on apparent fix_fftr output
  // Seems to make it more accurate (proper response to a frequency sweep with some aliasing)
  {int8_t reordered[32];  // <-- This array as a global variable causes instablity, so it's declared in a minimal scope
    for(int i = 0; i < 32; i++){
    if(i % 2 != 0) reordered[i] = data[i/2+16];
    else reordered[i] = data[i/2];
  }for(int i = 0; i < 32; i++) data[i] = reordered[i];}
  
  // Time smoothing by user-determined factor and user-determined scaling
  for(int count = 0; count < 32; count++){
  if(data[count] < 0) data[count] = 0;                                          // Eliminating negative output of fix_fftr
  #ifdef LOG_OUTPUT
  else data[count] = log_scale*log((float)(data[count]+1));                     // Logarithmic function equivalent to SCALING_FACTOR*log2(x+1)
  #else
  else data[count] *= SCALE_FACTOR;                                             // Linear scaling up according to SCALE_FACTOR
  #endif
  data[count] = (float)buff[count] * anti_coeff + (float)data[count] * coeff;   // Smoothing by factoring in past data
  buff[count] = data[count];                                                    // Storing current output as next frame's past data
  if(data[count] > 63) data[count] = 63;                                        // Capping output at screen height
  }


```