mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-18 00:18:22 +00:00
Some fixes to EQ.
This commit is contained in:
parent
902c92acfc
commit
31249ab9da
@ -18,7 +18,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../fft/fft.c"
|
||||
#include "fft/fft.c"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
@ -30,13 +30,13 @@
|
||||
|
||||
struct eq_data
|
||||
{
|
||||
rarch_fft_t *fft;
|
||||
fft_t *fft;
|
||||
float buffer[8 * 1024];
|
||||
|
||||
float *save;
|
||||
float *block;
|
||||
rarch_fft_complex_t *filter;
|
||||
rarch_fft_complex_t *fftblock;
|
||||
fft_complex_t *filter;
|
||||
fft_complex_t *fftblock;
|
||||
unsigned block_size;
|
||||
unsigned block_ptr;
|
||||
};
|
||||
@ -53,7 +53,7 @@ static void eq_free(void *data)
|
||||
if (!eq)
|
||||
return;
|
||||
|
||||
rarch_fft_free(eq->fft);
|
||||
fft_free(eq->fft);
|
||||
free(eq->save);
|
||||
free(eq->block);
|
||||
free(eq->fftblock);
|
||||
@ -92,10 +92,10 @@ static void eq_process(void *data, struct dspfilter_output *output,
|
||||
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
rarch_fft_process_forward(eq->fft, eq->fftblock, eq->block + c, 2);
|
||||
fft_process_forward(eq->fft, eq->fftblock, eq->block + c, 2);
|
||||
for (i = 0; i < 2 * eq->block_size; i++)
|
||||
eq->fftblock[i] = rarch_fft_complex_mul(eq->fftblock[i], eq->filter[i]);
|
||||
rarch_fft_process_inverse(eq->fft, out + c, eq->fftblock, 2);
|
||||
eq->fftblock[i] = fft_complex_mul(eq->fftblock[i], eq->filter[i]);
|
||||
fft_process_inverse(eq->fft, out + c, eq->fftblock, 2);
|
||||
}
|
||||
|
||||
// Overlap add method, so add in saved block now.
|
||||
@ -124,7 +124,7 @@ static int gains_cmp(const void *a_, const void *b_)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void generate_response(rarch_fft_complex_t *response,
|
||||
static void generate_response(fft_complex_t *response,
|
||||
const struct eq_gain *gains, unsigned num_gains, unsigned samples)
|
||||
{
|
||||
unsigned i;
|
||||
@ -223,7 +223,7 @@ static void create_filter(struct eq_data *eq, unsigned size_log2,
|
||||
int half_block_size = eq->block_size >> 1;
|
||||
double window_mod = 1.0 / kaiser_window(0.0, beta);
|
||||
|
||||
rarch_fft_t *fft = rarch_fft_new(size_log2);
|
||||
fft_t *fft = fft_new(size_log2);
|
||||
float *time_filter = (float*)calloc(eq->block_size * 2, sizeof(*time_filter));
|
||||
if (!fft || !time_filter)
|
||||
goto end;
|
||||
@ -235,7 +235,7 @@ static void create_filter(struct eq_data *eq, unsigned size_log2,
|
||||
generate_response(eq->filter, gains, num_gains, half_block_size);
|
||||
|
||||
// Get equivalent time-domain filter.
|
||||
rarch_fft_process_inverse(fft, time_filter, eq->filter, 1);
|
||||
fft_process_inverse(fft, time_filter, eq->filter, 1);
|
||||
|
||||
// ifftshift() to create the correct linear phase filter.
|
||||
// The filter response was designed with zero phase, which won't work unless we compensate
|
||||
@ -268,10 +268,10 @@ static void create_filter(struct eq_data *eq, unsigned size_log2,
|
||||
#endif
|
||||
|
||||
// Padded FFT to create our FFT filter.
|
||||
rarch_fft_process_forward(eq->fft, eq->filter, time_filter, 1);
|
||||
fft_process_forward(eq->fft, eq->filter, time_filter, 1);
|
||||
|
||||
end:
|
||||
rarch_fft_free(fft);
|
||||
fft_free(fft);
|
||||
free(time_filter);
|
||||
}
|
||||
|
||||
@ -307,7 +307,7 @@ static void *eq_init(const struct dspfilter_info *info,
|
||||
|
||||
for (i = 0; i < num_gain; i++)
|
||||
{
|
||||
gains[i].freq = 0.5f * frequencies[i] / info->input_rate;
|
||||
gains[i].freq = frequencies[i] / (0.5f * info->input_rate);
|
||||
gains[i].gain = pow(10.0, gain[i] / 20.0);
|
||||
}
|
||||
config->free(frequencies);
|
||||
@ -317,12 +317,12 @@ static void *eq_init(const struct dspfilter_info *info,
|
||||
|
||||
eq->save = (float*)calloc( size, 2 * sizeof(*eq->save));
|
||||
eq->block = (float*)calloc(2 * size, 2 * sizeof(*eq->block));
|
||||
eq->fftblock = (rarch_fft_complex_t*)calloc(2 * size, sizeof(*eq->fftblock));
|
||||
eq->filter = (rarch_fft_complex_t*)calloc(2 * size, sizeof(*eq->filter));
|
||||
eq->fftblock = (fft_complex_t*)calloc(2 * size, sizeof(*eq->fftblock));
|
||||
eq->filter = (fft_complex_t*)calloc(2 * size, sizeof(*eq->filter));
|
||||
|
||||
// Use an FFT which is twice the block size with zero-padding
|
||||
// to make circular convolution => proper convolution.
|
||||
eq->fft = rarch_fft_new(size_log2 + 1);
|
||||
eq->fft = fft_new(size_log2 + 1);
|
||||
|
||||
if (!eq->fft || !eq->fftblock || !eq->save || !eq->block || !eq->filter)
|
||||
goto error;
|
||||
|
@ -21,10 +21,10 @@
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
struct rarch_fft
|
||||
struct fft
|
||||
{
|
||||
rarch_fft_complex_t *interleave_buffer;
|
||||
rarch_fft_complex_t *phase_lut;
|
||||
fft_complex_t *interleave_buffer;
|
||||
fft_complex_t *phase_lut;
|
||||
unsigned *bitinverse_buffer;
|
||||
unsigned size;
|
||||
};
|
||||
@ -46,13 +46,13 @@ static void build_bitinverse(unsigned *bitinverse, unsigned size_log2)
|
||||
bitinverse[i] = bitswap(i, size_log2);
|
||||
}
|
||||
|
||||
static rarch_fft_complex_t exp_imag(double phase)
|
||||
static fft_complex_t exp_imag(double phase)
|
||||
{
|
||||
rarch_fft_complex_t out = { cos(phase), sin(phase) };
|
||||
fft_complex_t out = { cos(phase), sin(phase) };
|
||||
return out;
|
||||
}
|
||||
|
||||
static void build_phase_lut(rarch_fft_complex_t *out, int size)
|
||||
static void build_phase_lut(fft_complex_t *out, int size)
|
||||
{
|
||||
int i;
|
||||
out += size;
|
||||
@ -61,7 +61,7 @@ static void build_phase_lut(rarch_fft_complex_t *out, int size)
|
||||
}
|
||||
|
||||
static void interleave_complex(const unsigned *bitinverse,
|
||||
rarch_fft_complex_t *out, const rarch_fft_complex_t *in,
|
||||
fft_complex_t *out, const fft_complex_t *in,
|
||||
unsigned samples, unsigned step)
|
||||
{
|
||||
unsigned i;
|
||||
@ -70,7 +70,7 @@ static void interleave_complex(const unsigned *bitinverse,
|
||||
}
|
||||
|
||||
static void interleave_float(const unsigned *bitinverse,
|
||||
rarch_fft_complex_t *out, const float *in,
|
||||
fft_complex_t *out, const float *in,
|
||||
unsigned samples, unsigned step)
|
||||
{
|
||||
unsigned i;
|
||||
@ -82,7 +82,7 @@ static void interleave_float(const unsigned *bitinverse,
|
||||
}
|
||||
}
|
||||
|
||||
static void resolve_float(float *out, const rarch_fft_complex_t *in, unsigned samples,
|
||||
static void resolve_float(float *out, const fft_complex_t *in, unsigned samples,
|
||||
float gain, unsigned step)
|
||||
{
|
||||
unsigned i;
|
||||
@ -90,17 +90,17 @@ static void resolve_float(float *out, const rarch_fft_complex_t *in, unsigned sa
|
||||
*out = gain * in->real;
|
||||
}
|
||||
|
||||
rarch_fft_t *rarch_fft_new(unsigned block_size_log2)
|
||||
fft_t *fft_new(unsigned block_size_log2)
|
||||
{
|
||||
rarch_fft_t *fft = (rarch_fft_t*)calloc(1, sizeof(*fft));
|
||||
fft_t *fft = (fft_t*)calloc(1, sizeof(*fft));
|
||||
if (!fft)
|
||||
return NULL;
|
||||
|
||||
unsigned size = 1 << block_size_log2;
|
||||
|
||||
fft->interleave_buffer = (rarch_fft_complex_t*)calloc(size, sizeof(*fft->interleave_buffer));
|
||||
fft->interleave_buffer = (fft_complex_t*)calloc(size, sizeof(*fft->interleave_buffer));
|
||||
fft->bitinverse_buffer = (unsigned*)calloc(size, sizeof(*fft->bitinverse_buffer));
|
||||
fft->phase_lut = (rarch_fft_complex_t*)calloc(2 * size + 1, sizeof(*fft->phase_lut));
|
||||
fft->phase_lut = (fft_complex_t*)calloc(2 * size + 1, sizeof(*fft->phase_lut));
|
||||
|
||||
if (!fft->interleave_buffer || !fft->bitinverse_buffer || !fft->phase_lut)
|
||||
goto error;
|
||||
@ -112,11 +112,11 @@ rarch_fft_t *rarch_fft_new(unsigned block_size_log2)
|
||||
return fft;
|
||||
|
||||
error:
|
||||
rarch_fft_free(fft);
|
||||
fft_free(fft);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rarch_fft_free(rarch_fft_t *fft)
|
||||
void fft_free(fft_t *fft)
|
||||
{
|
||||
if (!fft)
|
||||
return;
|
||||
@ -127,15 +127,15 @@ void rarch_fft_free(rarch_fft_t *fft)
|
||||
free(fft);
|
||||
}
|
||||
|
||||
static void butterfly(rarch_fft_complex_t *a, rarch_fft_complex_t *b, rarch_fft_complex_t mod)
|
||||
static void butterfly(fft_complex_t *a, fft_complex_t *b, fft_complex_t mod)
|
||||
{
|
||||
mod = rarch_fft_complex_mul(mod, *b);
|
||||
*b = rarch_fft_complex_sub(*a, mod);
|
||||
*a = rarch_fft_complex_add(*a, mod);
|
||||
mod = fft_complex_mul(mod, *b);
|
||||
*b = fft_complex_sub(*a, mod);
|
||||
*a = fft_complex_add(*a, mod);
|
||||
}
|
||||
|
||||
static void butterflies(rarch_fft_complex_t *butterfly_buf,
|
||||
const rarch_fft_complex_t *phase_lut,
|
||||
static void butterflies(fft_complex_t *butterfly_buf,
|
||||
const fft_complex_t *phase_lut,
|
||||
int phase_dir, unsigned step_size, unsigned samples)
|
||||
{
|
||||
unsigned i, j;
|
||||
@ -147,8 +147,8 @@ static void butterflies(rarch_fft_complex_t *butterfly_buf,
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_fft_process_forward_complex(rarch_fft_t *fft,
|
||||
rarch_fft_complex_t *out, const rarch_fft_complex_t *in, unsigned step)
|
||||
void fft_process_forward_complex(fft_t *fft,
|
||||
fft_complex_t *out, const fft_complex_t *in, unsigned step)
|
||||
{
|
||||
unsigned step_size;
|
||||
unsigned samples = fft->size;
|
||||
@ -162,8 +162,8 @@ void rarch_fft_process_forward_complex(rarch_fft_t *fft,
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_fft_process_forward(rarch_fft_t *fft,
|
||||
rarch_fft_complex_t *out, const float *in, unsigned step)
|
||||
void fft_process_forward(fft_t *fft,
|
||||
fft_complex_t *out, const float *in, unsigned step)
|
||||
{
|
||||
unsigned step_size;
|
||||
unsigned samples = fft->size;
|
||||
@ -177,8 +177,8 @@ void rarch_fft_process_forward(rarch_fft_t *fft,
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_fft_process_inverse(rarch_fft_t *fft,
|
||||
float *out, const rarch_fft_complex_t *in, unsigned step)
|
||||
void fft_process_inverse(fft_t *fft,
|
||||
float *out, const fft_complex_t *in, unsigned step)
|
||||
{
|
||||
unsigned step_size;
|
||||
unsigned samples = fft->size;
|
@ -16,19 +16,19 @@
|
||||
#ifndef RARCH_FFT_H__
|
||||
#define RARCH_FFT_H__
|
||||
|
||||
typedef struct rarch_fft rarch_fft_t;
|
||||
typedef struct fft fft_t;
|
||||
|
||||
// C99 <complex.h> would be nice.
|
||||
typedef struct
|
||||
{
|
||||
float real;
|
||||
float imag;
|
||||
} rarch_fft_complex_t;
|
||||
} fft_complex_t;
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_mul(rarch_fft_complex_t a,
|
||||
rarch_fft_complex_t b)
|
||||
static inline fft_complex_t fft_complex_mul(fft_complex_t a,
|
||||
fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
fft_complex_t out = {
|
||||
a.real * b.real - a.imag * b.imag,
|
||||
a.imag * b.real + a.real * b.imag,
|
||||
};
|
||||
@ -37,10 +37,10 @@ static inline rarch_fft_complex_t rarch_fft_complex_mul(rarch_fft_complex_t a,
|
||||
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_add(rarch_fft_complex_t a,
|
||||
rarch_fft_complex_t b)
|
||||
static inline fft_complex_t fft_complex_add(fft_complex_t a,
|
||||
fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
fft_complex_t out = {
|
||||
a.real + b.real,
|
||||
a.imag + b.imag,
|
||||
};
|
||||
@ -49,10 +49,10 @@ static inline rarch_fft_complex_t rarch_fft_complex_add(rarch_fft_complex_t a,
|
||||
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_sub(rarch_fft_complex_t a,
|
||||
rarch_fft_complex_t b)
|
||||
static inline fft_complex_t fft_complex_sub(fft_complex_t a,
|
||||
fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
fft_complex_t out = {
|
||||
a.real - b.real,
|
||||
a.imag - b.imag,
|
||||
};
|
||||
@ -61,27 +61,27 @@ static inline rarch_fft_complex_t rarch_fft_complex_sub(rarch_fft_complex_t a,
|
||||
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_conj(rarch_fft_complex_t a)
|
||||
static inline fft_complex_t fft_complex_conj(fft_complex_t a)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
fft_complex_t out = {
|
||||
a.real, -a.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
rarch_fft_t *rarch_fft_new(unsigned block_size_log2);
|
||||
fft_t *fft_new(unsigned block_size_log2);
|
||||
|
||||
void rarch_fft_free(rarch_fft_t *fft);
|
||||
void fft_free(fft_t *fft);
|
||||
|
||||
void rarch_fft_process_forward_complex(rarch_fft_t *fft,
|
||||
rarch_fft_complex_t *out, const rarch_fft_complex_t *in, unsigned step);
|
||||
void fft_process_forward_complex(fft_t *fft,
|
||||
fft_complex_t *out, const fft_complex_t *in, unsigned step);
|
||||
|
||||
void rarch_fft_process_forward(rarch_fft_t *fft,
|
||||
rarch_fft_complex_t *out, const float *in, unsigned step);
|
||||
void fft_process_forward(fft_t *fft,
|
||||
fft_complex_t *out, const float *in, unsigned step);
|
||||
|
||||
void rarch_fft_process_inverse(rarch_fft_t *fft,
|
||||
float *out, const rarch_fft_complex_t *in, unsigned step);
|
||||
void fft_process_inverse(fft_t *fft,
|
||||
float *out, const fft_complex_t *in, unsigned step);
|
||||
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user