#include <filter.h>
#include <math.h>
-typedef struct {
- UZURA uzura;
- uint8_t effect;
- int volume;
- char volmsg[9];
-} work_t;
-
/**
* @brief FFT calculation size.
* @details LCD\82É\82Í0\81`12kHz\82Ü\82Å\82Ì\91Ñ\88æ\82ð\95\\8e¦
*/
#define FFT_SIZE (32)
-static fract16 window_func[FFT_SIZE];
-static fract16 fft_input_buf[FFT_SIZE];
-static complex_fract16 fft_output_buf[FFT_SIZE];
-static complex_fract16 fft_twiddle[FFT_SIZE / 2];
+/**
+ * @brief FFT calculation data structure.
+ */
+typedef struct {
+ fract16 window[FFT_SIZE];
+ fract16 input[FFT_SIZE];
+ complex_fract16 output[FFT_SIZE];
+ complex_fract16 twiddle[FFT_SIZE / 2];
+} fft_t;
+
+typedef struct {
+ UZURA uzura;
+ uint8_t effect;
+ int volume;
+ char volmsg[9];
+ fft_t fft;
+} work_t;
static void update_volmsg(work_t *w, const int vol)
{
int block_exp;
/*
+ * Get the user data from the UZURA framework.
+ */
+ work_t *w = (work_t *)UZURA_USER_DATA(p);
+ fract16 *window = w->fft.window;
+ fract16 *input = w->fft.input;
+ complex_fract16 *output = w->fft.output;
+ complex_fract16 *twiddle = w->fft.twiddle;
+
+ /*
* Copy data to the destination buffer.
*/
effect_through(p, src, des, count);
* The destination data bit width is 16bit.
*/
for (lc = 0, ld = 0; lc < FFT_SIZE; lc++, ld += 2) {
- fft_input_buf[lc] = lrmix(src[ld], src[ld + 1], window_func[lc]);
+ input[lc] = lrmix(src[ld], src[ld + 1], window[lc]);
}
/*
* 16bit\8eÀ\90\94FFT
*/
- rfft_fr16(fft_input_buf, fft_output_buf, fft_twiddle, 1, FFT_SIZE, &block_exp, 1);
+ rfft_fr16(input, output, twiddle, 1, FFT_SIZE, &block_exp, 1);
}
static void system_speana(UZURA *p)
int32_t level;
static int32_t refresh_count = 0;
+ /*
+ * Get the user data from the UZURA framework.
+ */
+ work_t *w = (work_t *)UZURA_USER_DATA(p);
+ complex_fract16 *output = w->fft.output;
+
if ((refresh_count++) > 10) {
refresh_count = 0;
lcd_goto(0, 0);
for (lc = 0; lc < 8; lc++) {
- // \95ª\82©\82è\82â\82·\82\82·\82é\82½\82ß\81A\82±\82±\82Ì\8cv\8eZ\82Í\95\82\93®\8f¬\90\94\93_\82É\82Ä\8cv\8eZ
- // \95K\97v\82É\89\9e\82¶\82Ä\8cÅ\92è\8f¬\90\94\93_\89\89\8eZ\82É\95Ï\8a·
-
- // \83p\83\8f\81[\83X\83y\83N\83g\83\8b\82ð\8eZ\8fo
- re = (float)fft_output_buf[lc].re / (float)32768;
- im = (float)fft_output_buf[lc].im / (float)32768;
+ /*
+ * \95ª\82©\82è\82â\82·\82\82·\82é\82½\82ß\81A\82±\82±\82Ì\8cv\8eZ\82Í\95\82\93®\8f¬\90\94\93_\82É\82Ä\8cv\8eZ
+ * \95K\97v\82É\89\9e\82¶\82Ä\8cÅ\92è\8f¬\90\94\93_\89\89\8eZ\82É\95Ï\8a·
+ */
+
+ /*
+ * \83p\83\8f\81[\83X\83y\83N\83g\83\8b\82ð\8eZ\8fo
+ */
+ re = (float)output[lc].re / (float)32768;
+ im = (float)output[lc].im / (float)32768;
ps = sqrtf(re * re + im * im);
- // \94Í\88Í\82ð\8c\88\82ß\82é\82½\82ß\82É\94÷\8f¬\92l\82Í2^-15\82É\90Ø\82è\8fã\82°
+ /*
+ * \94Í\88Í\82ð\8c\88\82ß\82é\82½\82ß\82É\94÷\8f¬\92l\82Í2^-15\82É\90Ø\82è\8fã\82°
+ */
ps = fmax(ps, 0.000030517578125);
- // dB\82É\95Ï\8a·\82µ\81A-10.4\81`0.35\82Ì\8bæ\8aÔ\82É\90³\8bK\89»
+ /*
+ * dB\82É\95Ï\8a·\82µ\81A-10.4\81`0.35\82Ì\8bæ\8aÔ\82É\90³\8bK\89»
+ */
ps = (float)(20.0 / 8.7) * log10f(ps);
- // 0\81`8\82Ì\94Í\88Í\82É\95Ï\8a·
+ /*
+ * 0\81`8\82Ì\94Í\88Í\82É\95Ï\8a·
+ */
level = (int32_t)ps + 8;
if(level < 0) level = 0;
- // LCD\82É\83p\83\8f\81[\82ð\95\\8e¦
+ /*
+ * LCD\82É\83p\83\8f\81[\82ð\95\\8e¦
+ */
lcd_putc(0x08 + level);
}
} else {
w.volume = 100;
strcpy(w.volmsg, "VOL: 100");
- // \91\8b\8aÖ\90\94\82ð\8dì\90¬
- // gen_hamming_fr16(window_func, 1, FFT_SIZE); // \83n\83~\83\93\83O\91\8b
- // gen_rectangular_fr16(window_func, 1, FFT_SIZE); // \92Z\8ca\91\8b
- gen_hanning_fr16(window_func, 1, FFT_SIZE); // \83n\83j\83\93\83O\91\8b
+ /*
+ * \91\8b\8aÖ\90\94\82ð\8dì\90¬
+ */
+ gen_hamming_fr16(w.fft.window, 1, FFT_SIZE); // \83n\83~\83\93\83O\91\8b
+ gen_rectangular_fr16(w.fft.window, 1, FFT_SIZE); // \92Z\8ca\91\8b
+ gen_hanning_fr16(w.fft.window, 1, FFT_SIZE); // \83n\83j\83\93\83O\91\8b
- // \89ñ\93]\88ö\8eq\83e\81[\83u\83\8b\82ð\8dì\90¬
- twidfftrad2_fr16(fft_twiddle, FFT_SIZE);
+ /*
+ * \89ñ\93]\88ö\8eq\83e\81[\83u\83\8b\82ð\8dì\90¬
+ */
+ twidfftrad2_fr16(w.fft.twiddle, FFT_SIZE);
effect_param_init();
uzura_init(&w.uzura, &w);