/************************************************************

	周波数領域信号処理サンプルプログラム
	FFT→逆FFT

 ************************************************************/
#include "iolib.h"
#include <trans.h>

/* FFT点数 */
#define FFTLEN  256
/* FFTと逆FFT */
#define fft rfft256
#define ifft ifft256


/**** 入出力バッファ ****/
/* 入出力用と信号処理用の2組 */
float inbuf[2][FFTLEN];			/* 入力バッファ */
float outbuf[2][FFTLEN];		/* 出力バッファ */
int buf_io = 0;				/* 入出力に使うバッファ */
int buf_proc = 0;			/* 信号処理に使うバッファ */
int buf_full = 0;			/* バッファに信号が溜ったら1 */
int count = 0;				/* 入出力用のカウンタ */

/**** FFT用の配列 ****/
float in_r[FFTLEN], in_i[FFTLEN];	/* 周波数領域の入力 */
float out_r[FFTLEN], out_i[FFTLEN];	/* 周波数領域の出力 */
float out_t[FFTLEN];			/* 時間領域の出力虚数部 */

/**** 割り込み処理 ****/
/* 入力信号があれば割り込みがかかり、実行される */
/* rx_buf[1]とrx_buf[2]が入力信号 */
/* tx_buf[1]とtx_buf[2]が出力信号 */
void process_input(int irq)
{
  /* 入力信号をバッファに格納 */
  inbuf[buf_io][count] = rx_buf[1];

  /* バッファから出力信号を取り出す */
  tx_buf[1] = tx_buf[2] = outbuf[buf_io][count];

  /* バッファがいっぱいになったかどうか調べる */
  count++;
  if (count == FFTLEN) {
    buf_full = 1;
    buf_io = 1 - buf_io;
    count = 0;
  }
}

void main(void)
{
  /* スケーリング (FFT点数で割らないといけない) */
  float scale = (1.0 / FFTLEN);
  int i;

  /* 出力バッファを初期化 */
  for (i = 0; i < FFTLEN; i++) {
    outbuf[0][i] = 0.0;
    outbuf[1][i] = 0.0;
  }

  /* DSPとA/D, D/Aの初期化 */
  init_21k();
  init_1847(SAMPLE8000, 0);

  /* メイン: 無限ループ */
  for(;;) {
    /* 入力信号が溜るまで待つ */
    while (!buf_full)
      idle();
    buf_full = 0;

    /* FFTで周波数領域に */
    fft(inbuf[buf_proc], in_r, in_i);

    /* 単に入力を出力にコピー */
    /* スケーリングを忘れずに */
    for (i = 0; i < FFTLEN; i++) {
      out_r[i] = scale * in_r[i];
      out_i[i] = scale * in_i[i];
    }

    /* 逆FFTで時間領域に */
    ifft(out_r, out_i, outbuf[buf_proc], out_t);

    /* バッファの切り替え */
    buf_proc = 1 - buf_proc;
  }
}