pinebuds/services/multimedia/speech/inc/ext_fft_f32.h

138 lines
3.3 KiB
C

/***************************************************************************
*
* Copyright 2015-2019 BES.
* All rights reserved. All unpublished rights reserved.
*
* No part of this work may be used or reproduced in any form or by any
* means, or stored in a database or retrieval system, without prior written
* permission of BES.
*
* Use of this work is governed by a license granted by BES.
* This work contains confidential and proprietary information of
* BES. which is protected by copyright, trade secret,
* trademark and other intellectual property rights.
*
****************************************************************************/
#include "arm_math.h"
#ifndef VQE_SIMULATE
#include "hal_trace.h"
#else
#define ASSERT(cond, str, ...) { if (!(cond)) { fprintf(stderr, str, ##__VA_ARGS__); while(1); } }
#define TRACE(str, ...) do { fprintf(stdout, str, ##__VA_ARGS__); fprintf(stdout, "\n"); } while (0)
#endif
// Enable this MACRO, Get same data with speex fft
// Some case can disable this MACRO to reduce MIPS
// #define _FFT_PRECISION
struct ext_f32_config {
float *in;
float *out;
arm_rfft_fast_instance_f32 fft;
int32_t N;
int32_t mode;
};
static void *ext_f32_fft_init(int32_t size, int32_t mode, void *ext_malloc(int))
{
arm_status status;
struct ext_f32_config *st = ext_malloc(1 * sizeof(struct ext_f32_config));
st->mode = mode;
st->in = ext_malloc(size * sizeof(float));
if (st->mode)
{
st->out = ext_malloc(size * sizeof(float));
}
else
{
st->out = NULL;
}
status = arm_rfft_fast_init_f32(&(st->fft), size);
ASSERT(status == ARM_MATH_SUCCESS, "FFTWRAP: arm cmsis f32 fft init error %d", status);
st->N = size;
return st;
}
static void ext_f32_fft_destroy(void *table, void ext_free(void *))
{
struct ext_f32_config *st = (struct ext_f32_config *)table;
ext_free(st->in);
if (st->mode) {
ext_free(st->out);
}
ext_free(st);
}
static POSSIBLY_UNUSED void ext_f32_fft(void *table, float *in, float *out)
{
struct ext_f32_config *st = (struct ext_f32_config *)table;
const int32_t N = st->N;
float *iptr = st->in;
float *optr = NULL;
if (st->mode)
{
optr = st->out;
}
else
{
optr = out;
}
/* We need to make a copy as fft modify input data */
for (int32_t i = 0; i < N; i++)
iptr[i] = in[i];
arm_rfft_fast_f32(&(st->fft), iptr, optr, 0);
if (st->mode)
{
out[0] = optr[0];
for (int32_t i = 1; i < N - 1; i++) {
out[i] = optr[i + 1];
}
out[N - 1] = optr[1];
}
#if defined(_FFT_PRECISION)
for (int32_t i = 0; i < N; i++)
out[i] = out[i] / N;
#endif
}
static POSSIBLY_UNUSED void ext_f32_ifft(void *table, float *in, float *out)
{
struct ext_f32_config *st = (struct ext_f32_config *)table;
const int32_t N = st->N;
float *iptr = st->in;
#if defined(_FFT_PRECISION)
for (int32_t i = 0; i < N; i++) {
in[i] = in[i] * N;
}
#endif
if (st->mode)
{
iptr[0] = in[0];
iptr[1] = in[N - 1];
for (int32_t i = 1; i < N - 1; i++) {
iptr[i + 1] = in[i];
}
}
else
{
iptr = in;
}
arm_rfft_fast_f32(&(st->fft), iptr, out, 1);
}