mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 19:20:35 +00:00
Begin implementing EQ.
This commit is contained in:
parent
8f913e8e9b
commit
ce14f2f517
@ -18,7 +18,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
struct rarch_fft
|
||||
@ -126,42 +126,11 @@ void rarch_fft_free(rarch_fft_t *fft)
|
||||
free(fft);
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t complex_mul(rarch_fft_complex_t a, rarch_fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real * b.real - a.imag * b.imag,
|
||||
a.imag * b.real + a.real * b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t complex_add(rarch_fft_complex_t a, rarch_fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real + b.real,
|
||||
a.imag + b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t complex_sub(rarch_fft_complex_t a, rarch_fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real - b.real,
|
||||
a.imag - b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly(rarch_fft_complex_t *a, rarch_fft_complex_t *b, rarch_fft_complex_t mod)
|
||||
{
|
||||
mod = complex_mul(mod, *b);
|
||||
*b = complex_sub(*a, mod);
|
||||
*a = complex_add(*a, mod);
|
||||
mod = rarch_fft_complex_mul(mod, *b);
|
||||
*b = rarch_fft_complex_sub(*a, mod);
|
||||
*a = rarch_fft_complex_add(*a, mod);
|
||||
}
|
||||
|
||||
static void butterflies(rarch_fft_complex_t *butterfly_buf,
|
||||
@ -221,6 +190,6 @@ void rarch_fft_process_inverse(rarch_fft_t *fft,
|
||||
1, step_size, samples);
|
||||
}
|
||||
|
||||
resolve_float(out, fft->interleave_buffer, fft->size, 1.0f / fft->size);
|
||||
resolve_float(out, fft->interleave_buffer, samples, 1.0f / samples);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,51 @@ typedef struct
|
||||
float imag;
|
||||
} rarch_fft_complex_t;
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_mul(rarch_fft_complex_t a,
|
||||
rarch_fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real * b.real - a.imag * b.imag,
|
||||
a.imag * b.real + a.real * b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_add(rarch_fft_complex_t a,
|
||||
rarch_fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real + b.real,
|
||||
a.imag + b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_sub(rarch_fft_complex_t a,
|
||||
rarch_fft_complex_t b)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real - b.real,
|
||||
a.imag - b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
static inline rarch_fft_complex_t rarch_fft_complex_conj(rarch_fft_complex_t a)
|
||||
{
|
||||
rarch_fft_complex_t out = {
|
||||
a.real, -a.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
rarch_fft_t *rarch_fft_new(unsigned block_size_log2);
|
||||
|
||||
void rarch_fft_free(rarch_fft_t *fft);
|
||||
|
105
audio/filters/eq.c
Normal file
105
audio/filters/eq.c
Normal file
@ -0,0 +1,105 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dspfilter.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../fft/fft.c"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
struct eq_data
|
||||
{
|
||||
rarch_fft_t *fft;
|
||||
float buffer[8 * 1024];
|
||||
|
||||
float *save;
|
||||
float *block;
|
||||
rarch_fft_complex_t *filter;
|
||||
unsigned block_size;
|
||||
unsigned block_ptr;
|
||||
};
|
||||
|
||||
static void eq_free(void *data)
|
||||
{
|
||||
struct eq_data *eq = (struct eq_data*)data;
|
||||
if (!eq)
|
||||
return;
|
||||
|
||||
rarch_fft_free(eq->fft);
|
||||
free(eq->save);
|
||||
free(eq->block);
|
||||
free(eq->filter);
|
||||
free(eq);
|
||||
}
|
||||
|
||||
static void eq_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
struct eq_data *eq = (struct eq_data*)data;
|
||||
}
|
||||
|
||||
static void *eq_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
struct eq_data *eq = (struct eq_data*)calloc(1, sizeof(*eq));
|
||||
if (!eq)
|
||||
return NULL;
|
||||
|
||||
unsigned size_log2 = 8;
|
||||
unsigned size = 1 << size_log2;
|
||||
|
||||
eq->block_size = size;
|
||||
|
||||
eq->save = (float*)calloc(2 * size, sizeof(*eq->save));
|
||||
eq->block = (float*)calloc(2 * size, 2 * sizeof(*eq->block));
|
||||
eq->filter = (rarch_fft_complex_t*)calloc(2 * size, sizeof(*eq->filter));
|
||||
eq->fft = rarch_fft_new(size_log2 + 1);
|
||||
|
||||
if (!eq->fft || !eq->save || !eq->block || !eq->filter)
|
||||
goto error;
|
||||
|
||||
return eq;
|
||||
|
||||
error:
|
||||
eq_free(eq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct dspfilter_implementation eq_plug = {
|
||||
eq_init,
|
||||
eq_process,
|
||||
eq_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Linear-Phase FFT Equalizer",
|
||||
"eq",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation eq_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *eq_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &eq_plug;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
Loading…
x
Reference in New Issue
Block a user