mirror of
https://github.com/libretro/RetroArch
synced 2025-04-09 21:45:45 +00:00
Update audio resampler
This commit is contained in:
parent
84e6c2a185
commit
dce610747b
@ -81,10 +81,10 @@ typedef struct rarch_sinc_resampler
|
|||||||
/* A buffer for phase_table, buffer_l and buffer_r
|
/* A buffer for phase_table, buffer_l and buffer_r
|
||||||
* are created in a single calloc().
|
* are created in a single calloc().
|
||||||
* Ensure that we get as good cache locality as we can hope for. */
|
* Ensure that we get as good cache locality as we can hope for. */
|
||||||
void *main_buffer;
|
float *main_buffer;
|
||||||
void *phase_table;
|
float *phase_table;
|
||||||
void *buffer_l;
|
float *buffer_l;
|
||||||
void *buffer_r;
|
float *buffer_r;
|
||||||
} rarch_sinc_resampler_t;
|
} rarch_sinc_resampler_t;
|
||||||
|
|
||||||
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
|
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
|
||||||
@ -105,8 +105,8 @@ static void resampler_sinc_process_neon(void *re_, struct resampler_data *data)
|
|||||||
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
||||||
|
|
||||||
uint32_t ratio = phases / data->ratio;
|
uint32_t ratio = phases / data->ratio;
|
||||||
const float *input = (const float*)data->data_in;
|
const float *input = data->data_in;
|
||||||
float *output = (float*)data->data_out;
|
float *output = data->data_out;
|
||||||
size_t frames = data->input_frames;
|
size_t frames = data->input_frames;
|
||||||
size_t out_frames = 0;
|
size_t out_frames = 0;
|
||||||
|
|
||||||
@ -114,21 +114,18 @@ static void resampler_sinc_process_neon(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = (float*)resamp->buffer_l;
|
|
||||||
float *buffer_r = (float*)resamp->buffer_r;
|
|
||||||
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,8 +156,8 @@ static void resampler_sinc_process_avx(void *re_, struct resampler_data *data)
|
|||||||
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
||||||
|
|
||||||
uint32_t ratio = phases / data->ratio;
|
uint32_t ratio = phases / data->ratio;
|
||||||
const float *input = (const float*)data->data_in;
|
const float *input = data->data_in;
|
||||||
float *output = (float*)data->data_out;
|
float *output = data->data_out;
|
||||||
size_t frames = data->input_frames;
|
size_t frames = data->input_frames;
|
||||||
size_t out_frames = 0;
|
size_t out_frames = 0;
|
||||||
|
|
||||||
@ -170,21 +167,18 @@ static void resampler_sinc_process_avx(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = resamp->buffer_l;
|
|
||||||
float *buffer_r = resamp->buffer_r;
|
|
||||||
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,20 +236,18 @@ static void resampler_sinc_process_avx(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = (float*)resamp->buffer_l;
|
|
||||||
float *buffer_r = (float*)resamp->buffer_r;
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,8 +306,8 @@ static void resampler_sinc_process_sse(void *re_, struct resampler_data *data)
|
|||||||
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
||||||
|
|
||||||
uint32_t ratio = phases / data->ratio;
|
uint32_t ratio = phases / data->ratio;
|
||||||
const float *input = (const float*)data->data_in;
|
const float *input = data->data_in;
|
||||||
float *output = (float*)data->data_out;
|
float *output = data->data_out;
|
||||||
size_t frames = data->input_frames;
|
size_t frames = data->input_frames;
|
||||||
size_t out_frames = 0;
|
size_t out_frames = 0;
|
||||||
|
|
||||||
@ -325,18 +317,16 @@ static void resampler_sinc_process_sse(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = (float*)resamp->buffer_l;
|
|
||||||
float *buffer_r = (float*)resamp->buffer_r;
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
@ -346,11 +336,11 @@ static void resampler_sinc_process_sse(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
__m128 sum;
|
__m128 sum;
|
||||||
const float *buffer_l = (const float*)resamp->buffer_l + resamp->ptr;
|
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||||
const float *buffer_r = (const float*)resamp->buffer_r + resamp->ptr;
|
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||||
unsigned taps = resamp->taps;
|
unsigned taps = resamp->taps;
|
||||||
unsigned phase = resamp->time >> resamp->subphase_bits;
|
unsigned phase = resamp->time >> resamp->subphase_bits;
|
||||||
float *phase_table = (float*)resamp->phase_table + phase * taps * 2;
|
float *phase_table = resamp->phase_table + phase * taps * 2;
|
||||||
float *delta_table = phase_table + taps;
|
float *delta_table = phase_table + taps;
|
||||||
__m128 delta = _mm_set1_ps((float)
|
__m128 delta = _mm_set1_ps((float)
|
||||||
(resamp->time & resamp->subphase_mask) * resamp->subphase_mod);
|
(resamp->time & resamp->subphase_mask) * resamp->subphase_mod);
|
||||||
@ -406,19 +396,16 @@ static void resampler_sinc_process_sse(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = (float*)resamp->buffer_l;
|
|
||||||
float *buffer_r = (float*)resamp->buffer_r;
|
|
||||||
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
@ -428,11 +415,11 @@ static void resampler_sinc_process_sse(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
__m128 sum;
|
__m128 sum;
|
||||||
const float *buffer_l = (const float*)resamp->buffer_l + resamp->ptr;
|
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||||
const float *buffer_r = (const float*)resamp->buffer_r + resamp->ptr;
|
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||||
unsigned taps = resamp->taps;
|
unsigned taps = resamp->taps;
|
||||||
unsigned phase = resamp->time >> resamp->subphase_bits;
|
unsigned phase = resamp->time >> resamp->subphase_bits;
|
||||||
float *phase_table = (float*)resamp->phase_table + phase * taps;
|
float *phase_table = resamp->phase_table + phase * taps;
|
||||||
|
|
||||||
__m128 sum_l = _mm_setzero_ps();
|
__m128 sum_l = _mm_setzero_ps();
|
||||||
__m128 sum_r = _mm_setzero_ps();
|
__m128 sum_r = _mm_setzero_ps();
|
||||||
@ -488,8 +475,8 @@ static void resampler_sinc_process_c(void *re_, struct resampler_data *data)
|
|||||||
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
|
||||||
|
|
||||||
uint32_t ratio = phases / data->ratio;
|
uint32_t ratio = phases / data->ratio;
|
||||||
const float *input = (const float*)data->data_in;
|
const float *input = data->data_in;
|
||||||
float *output = (float*)data->data_out;
|
float *output = data->data_out;
|
||||||
size_t frames = data->input_frames;
|
size_t frames = data->input_frames;
|
||||||
size_t out_frames = 0;
|
size_t out_frames = 0;
|
||||||
|
|
||||||
@ -499,19 +486,16 @@ static void resampler_sinc_process_c(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = (float*)resamp->buffer_l;
|
|
||||||
float *buffer_r = (float*)resamp->buffer_r;
|
|
||||||
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
@ -522,12 +506,12 @@ static void resampler_sinc_process_c(void *re_, struct resampler_data *data)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
float sum_l = 0.0f;
|
float sum_l = 0.0f;
|
||||||
float sum_r = 0.0f;
|
float sum_r = 0.0f;
|
||||||
const float *buffer_l = (const float*)resamp->buffer_l + resamp->ptr;
|
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||||
const float *buffer_r = (const float*)resamp->buffer_r + resamp->ptr;
|
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||||
unsigned taps = resamp->taps;
|
unsigned taps = resamp->taps;
|
||||||
unsigned phase = resamp->time >> resamp->subphase_bits;
|
unsigned phase = resamp->time >> resamp->subphase_bits;
|
||||||
float *phase_table = (float*)resamp->phase_table + phase * taps * 2;
|
float *phase_table = resamp->phase_table + phase * taps * 2;
|
||||||
float *delta_table = (float*)phase_table + taps;
|
float *delta_table = phase_table + taps;
|
||||||
float delta = (float)
|
float delta = (float)
|
||||||
(resamp->time & resamp->subphase_mask) * resamp->subphase_mod;
|
(resamp->time & resamp->subphase_mask) * resamp->subphase_mod;
|
||||||
|
|
||||||
@ -555,21 +539,18 @@ static void resampler_sinc_process_c(void *re_, struct resampler_data *data)
|
|||||||
{
|
{
|
||||||
while (frames && resamp->time >= phases)
|
while (frames && resamp->time >= phases)
|
||||||
{
|
{
|
||||||
float *buffer_l = (float*)resamp->buffer_l;
|
|
||||||
float *buffer_r = (float*)resamp->buffer_r;
|
|
||||||
|
|
||||||
/* Push in reverse to make filter more obvious. */
|
/* Push in reverse to make filter more obvious. */
|
||||||
if (!resamp->ptr)
|
if (!resamp->ptr)
|
||||||
resamp->ptr = resamp->taps;
|
resamp->ptr = resamp->taps;
|
||||||
resamp->ptr--;
|
resamp->ptr--;
|
||||||
|
|
||||||
buffer_l[resamp->ptr + resamp->taps] =
|
resamp->buffer_l[resamp->ptr + resamp->taps] =
|
||||||
buffer_l[resamp->ptr] = *input++;
|
resamp->buffer_l[resamp->ptr] = *input++;
|
||||||
|
|
||||||
buffer_r[resamp->ptr + resamp->taps] =
|
resamp->buffer_r[resamp->ptr + resamp->taps] =
|
||||||
buffer_r[resamp->ptr] = *input++;
|
resamp->buffer_r[resamp->ptr] = *input++;
|
||||||
|
|
||||||
resamp->time -= phases;
|
resamp->time -= phases;
|
||||||
frames--;
|
frames--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,11 +559,11 @@ static void resampler_sinc_process_c(void *re_, struct resampler_data *data)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
float sum_l = 0.0f;
|
float sum_l = 0.0f;
|
||||||
float sum_r = 0.0f;
|
float sum_r = 0.0f;
|
||||||
const float *buffer_l = (const float*)resamp->buffer_l + resamp->ptr;
|
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||||
const float *buffer_r = (const float*)resamp->buffer_r + resamp->ptr;
|
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||||
unsigned taps = resamp->taps;
|
unsigned taps = resamp->taps;
|
||||||
unsigned phase = resamp->time >> resamp->subphase_bits;
|
unsigned phase = resamp->time >> resamp->subphase_bits;
|
||||||
float *phase_table = (float*)resamp->phase_table + phase * taps;
|
float *phase_table = resamp->phase_table + phase * taps;
|
||||||
|
|
||||||
for (i = 0; i < taps; i++)
|
for (i = 0; i < taps; i++)
|
||||||
{
|
{
|
||||||
@ -616,13 +597,12 @@ static void resampler_sinc_free(void *data)
|
|||||||
|
|
||||||
static void sinc_init_table_kaiser(rarch_sinc_resampler_t *resamp,
|
static void sinc_init_table_kaiser(rarch_sinc_resampler_t *resamp,
|
||||||
double cutoff,
|
double cutoff,
|
||||||
void *phase_table, int phases, int taps, bool calculate_delta)
|
float *phase_table, int phases, int taps, bool calculate_delta)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
double window_mod = kaiser_window_function(0.0, resamp->kaiser_beta); /* Need to normalize w(0) to 1.0. */
|
double window_mod = kaiser_window_function(0.0, resamp->kaiser_beta); /* Need to normalize w(0) to 1.0. */
|
||||||
int stride = calculate_delta ? 2 : 1;
|
int stride = calculate_delta ? 2 : 1;
|
||||||
double sidelobes = taps / 2.0;
|
double sidelobes = taps / 2.0;
|
||||||
float *phase_table_f = (float*)phase_table;
|
|
||||||
|
|
||||||
for (i = 0; i < phases; i++)
|
for (i = 0; i < phases; i++)
|
||||||
{
|
{
|
||||||
@ -636,21 +616,22 @@ static void sinc_init_table_kaiser(rarch_sinc_resampler_t *resamp,
|
|||||||
sinc_phase = sidelobes * window_phase;
|
sinc_phase = sidelobes * window_phase;
|
||||||
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
||||||
kaiser_window_function(window_phase, resamp->kaiser_beta) / window_mod;
|
kaiser_window_function(window_phase, resamp->kaiser_beta) / window_mod;
|
||||||
phase_table_f[i * stride * taps + j] = val;
|
phase_table[i * stride * taps + j] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calculate_delta)
|
if (calculate_delta)
|
||||||
{
|
{
|
||||||
int phase, p;
|
int phase;
|
||||||
|
int p;
|
||||||
|
|
||||||
for (p = 0; p < phases - 1; p++)
|
for (p = 0; p < phases - 1; p++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < taps; j++)
|
for (j = 0; j < taps; j++)
|
||||||
{
|
{
|
||||||
float delta = phase_table_f[(p + 1) * stride * taps + j] -
|
float delta = phase_table[(p + 1) * stride * taps + j] -
|
||||||
phase_table_f[p * stride * taps + j];
|
phase_table[p * stride * taps + j];
|
||||||
phase_table_f[(p * stride + 1) * taps + j] = delta;
|
phase_table[(p * stride + 1) * taps + j] = delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,21 +647,19 @@ static void sinc_init_table_kaiser(rarch_sinc_resampler_t *resamp,
|
|||||||
|
|
||||||
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
||||||
kaiser_window_function(window_phase, resamp->kaiser_beta) / window_mod;
|
kaiser_window_function(window_phase, resamp->kaiser_beta) / window_mod;
|
||||||
delta = (val - phase_table_f[phase * stride * taps + j]);
|
delta = (val - phase_table[phase * stride * taps + j]);
|
||||||
phase_table_f[(phase * stride + 1) * taps + j] = delta;
|
phase_table[(phase * stride + 1) * taps + j] = delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sinc_init_table_lanczos(rarch_sinc_resampler_t *resamp,
|
static void sinc_init_table_lanczos(rarch_sinc_resampler_t *resamp, double cutoff,
|
||||||
double cutoff,
|
float *phase_table, int phases, int taps, bool calculate_delta)
|
||||||
void *_phase_table, int phases, int taps, bool calculate_delta)
|
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
double window_mod = lanzcos_window_function(0.0); /* Need to normalize w(0) to 1.0. */
|
double window_mod = lanzcos_window_function(0.0); /* Need to normalize w(0) to 1.0. */
|
||||||
int stride = calculate_delta ? 2 : 1;
|
int stride = calculate_delta ? 2 : 1;
|
||||||
double sidelobes = taps / 2.0;
|
double sidelobes = taps / 2.0;
|
||||||
float *phase_table_f = (float*)_phase_table;
|
|
||||||
|
|
||||||
for (i = 0; i < phases; i++)
|
for (i = 0; i < phases; i++)
|
||||||
{
|
{
|
||||||
@ -694,7 +673,7 @@ static void sinc_init_table_lanczos(rarch_sinc_resampler_t *resamp,
|
|||||||
sinc_phase = sidelobes * window_phase;
|
sinc_phase = sidelobes * window_phase;
|
||||||
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
||||||
lanzcos_window_function(window_phase) / window_mod;
|
lanzcos_window_function(window_phase) / window_mod;
|
||||||
phase_table_f[i * stride * taps + j] = val;
|
phase_table[i * stride * taps + j] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,9 +686,9 @@ static void sinc_init_table_lanczos(rarch_sinc_resampler_t *resamp,
|
|||||||
{
|
{
|
||||||
for (j = 0; j < taps; j++)
|
for (j = 0; j < taps; j++)
|
||||||
{
|
{
|
||||||
float delta = phase_table_f[(p + 1) * stride * taps + j] -
|
float delta = phase_table[(p + 1) * stride * taps + j] -
|
||||||
phase_table_f[p * stride * taps + j];
|
phase_table[p * stride * taps + j];
|
||||||
phase_table_f[(p * stride + 1) * taps + j] = delta;
|
phase_table[(p * stride + 1) * taps + j] = delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,14 +698,14 @@ static void sinc_init_table_lanczos(rarch_sinc_resampler_t *resamp,
|
|||||||
float val, delta;
|
float val, delta;
|
||||||
double sinc_phase;
|
double sinc_phase;
|
||||||
int n = j * phases + (phase + 1);
|
int n = j * phases + (phase + 1);
|
||||||
double window_phase = (double)n / (phases * taps); /* ( 0, 1]. */
|
double window_phase = (double)n / (phases * taps); /* (0, 1]. */
|
||||||
window_phase = 2.0 * window_phase - 1.0; /* (-1, 1] */
|
window_phase = 2.0 * window_phase - 1.0; /* (-1, 1] */
|
||||||
sinc_phase = sidelobes * window_phase;
|
sinc_phase = sidelobes * window_phase;
|
||||||
|
|
||||||
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
||||||
lanzcos_window_function(window_phase) / window_mod;
|
lanzcos_window_function(window_phase) / window_mod;
|
||||||
delta = (val - phase_table_f[phase * stride * taps + j]);
|
delta = (val - phase_table[phase * stride * taps + j]);
|
||||||
phase_table_f[(phase * stride + 1) * taps + j] = delta;
|
phase_table[(phase * stride + 1) * taps + j] = delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -833,17 +812,17 @@ static void *resampler_sinc_new(const struct resampler_config *config,
|
|||||||
memset(re->main_buffer, 0, sizeof(float) * elems);
|
memset(re->main_buffer, 0, sizeof(float) * elems);
|
||||||
|
|
||||||
re->phase_table = re->main_buffer;
|
re->phase_table = re->main_buffer;
|
||||||
re->buffer_l = (float*)re->main_buffer + phase_elems;
|
re->buffer_l = re->main_buffer + phase_elems;
|
||||||
re->buffer_r = (float*)re->buffer_l + 2 * re->taps;
|
re->buffer_r = re->buffer_l + 2 * re->taps;
|
||||||
|
|
||||||
switch (re->window_type)
|
switch (re->window_type)
|
||||||
{
|
{
|
||||||
case SINC_WINDOW_LANCZOS:
|
case SINC_WINDOW_LANCZOS:
|
||||||
sinc_init_table_lanczos(re, cutoff, (float*)re->phase_table,
|
sinc_init_table_lanczos(re, cutoff, re->phase_table,
|
||||||
1 << re->phase_bits, re->taps, false);
|
1 << re->phase_bits, re->taps, false);
|
||||||
break;
|
break;
|
||||||
case SINC_WINDOW_KAISER:
|
case SINC_WINDOW_KAISER:
|
||||||
sinc_init_table_kaiser(re, cutoff, (float*)re->phase_table,
|
sinc_init_table_kaiser(re, cutoff, re->phase_table,
|
||||||
1 << re->phase_bits, re->taps, true);
|
1 << re->phase_bits, re->taps, true);
|
||||||
break;
|
break;
|
||||||
case SINC_WINDOW_NONE:
|
case SINC_WINDOW_NONE:
|
||||||
|
@ -67,8 +67,8 @@ typedef unsigned resampler_simd_mask_t;
|
|||||||
|
|
||||||
struct resampler_data
|
struct resampler_data
|
||||||
{
|
{
|
||||||
const void *data_in;
|
const float *data_in;
|
||||||
void *data_out;
|
float *data_out;
|
||||||
|
|
||||||
size_t input_frames;
|
size_t input_frames;
|
||||||
size_t output_frames;
|
size_t output_frames;
|
||||||
|
18
retroarch.c
18
retroarch.c
@ -3201,8 +3201,8 @@ static float audio_driver_rate_control_delta = 0.0f;
|
|||||||
static float audio_driver_input = 0.0f;
|
static float audio_driver_input = 0.0f;
|
||||||
static float audio_driver_volume_gain = 0.0f;
|
static float audio_driver_volume_gain = 0.0f;
|
||||||
|
|
||||||
static void *audio_driver_input_data = NULL;
|
static float *audio_driver_input_data = NULL;
|
||||||
static void *audio_driver_output_samples_buf = NULL;
|
static float *audio_driver_output_samples_buf = NULL;
|
||||||
|
|
||||||
static double audio_source_ratio_original = 0.0f;
|
static double audio_source_ratio_original = 0.0f;
|
||||||
static double audio_source_ratio_current = 0.0f;
|
static double audio_source_ratio_current = 0.0f;
|
||||||
@ -18756,7 +18756,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
|||||||
{
|
{
|
||||||
unsigned new_rate = 0;
|
unsigned new_rate = 0;
|
||||||
float *aud_inp_data = NULL;
|
float *aud_inp_data = NULL;
|
||||||
void *samples_buf = NULL;
|
float *samples_buf = NULL;
|
||||||
int16_t *rewind_buf = NULL;
|
int16_t *rewind_buf = NULL;
|
||||||
size_t max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2;
|
size_t max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2;
|
||||||
settings_t *settings = configuration_settings;
|
settings_t *settings = configuration_settings;
|
||||||
@ -18880,7 +18880,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
|||||||
if (!aud_inp_data)
|
if (!aud_inp_data)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
audio_driver_input_data = (float*)aud_inp_data;
|
audio_driver_input_data = aud_inp_data;
|
||||||
audio_driver_data_ptr = 0;
|
audio_driver_data_ptr = 0;
|
||||||
|
|
||||||
retro_assert(settings->uints.audio_out_rate <
|
retro_assert(settings->uints.audio_out_rate <
|
||||||
@ -18953,10 +18953,10 @@ static void audio_driver_flush(const int16_t *data, size_t samples,
|
|||||||
src_data.data_out = NULL;
|
src_data.data_out = NULL;
|
||||||
src_data.output_frames = 0;
|
src_data.output_frames = 0;
|
||||||
|
|
||||||
convert_s16_to_float((float*)audio_driver_input_data, data, samples,
|
convert_s16_to_float(audio_driver_input_data, data, samples,
|
||||||
audio_volume_gain);
|
audio_volume_gain);
|
||||||
|
|
||||||
src_data.data_in = (float*)audio_driver_input_data;
|
src_data.data_in = audio_driver_input_data;
|
||||||
src_data.input_frames = samples >> 1;
|
src_data.input_frames = samples >> 1;
|
||||||
|
|
||||||
/* TODO/FIXME - not available in fixed integer mode */
|
/* TODO/FIXME - not available in fixed integer mode */
|
||||||
@ -18969,7 +18969,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples,
|
|||||||
dsp_data.output = NULL;
|
dsp_data.output = NULL;
|
||||||
dsp_data.output_frames = 0;
|
dsp_data.output_frames = 0;
|
||||||
|
|
||||||
dsp_data.input = (float*)audio_driver_input_data;
|
dsp_data.input = audio_driver_input_data;
|
||||||
dsp_data.input_frames = (unsigned)(samples >> 1);
|
dsp_data.input_frames = (unsigned)(samples >> 1);
|
||||||
|
|
||||||
retro_dsp_filter_process(audio_driver_dsp, &dsp_data);
|
retro_dsp_filter_process(audio_driver_dsp, &dsp_data);
|
||||||
@ -18981,7 +18981,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src_data.data_out = (float*)audio_driver_output_samples_buf;
|
src_data.data_out = audio_driver_output_samples_buf;
|
||||||
|
|
||||||
if (audio_driver_control)
|
if (audio_driver_control)
|
||||||
{
|
{
|
||||||
@ -19028,7 +19028,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples,
|
|||||||
(audio_driver_mixer_volume_gain != 1.0f) ? true : false;
|
(audio_driver_mixer_volume_gain != 1.0f) ? true : false;
|
||||||
float mixer_gain = !audio_driver_mixer_mute_enable ?
|
float mixer_gain = !audio_driver_mixer_mute_enable ?
|
||||||
audio_driver_mixer_volume_gain : 0.0f;
|
audio_driver_mixer_volume_gain : 0.0f;
|
||||||
audio_mixer_mix((float*)audio_driver_output_samples_buf,
|
audio_mixer_mix(audio_driver_output_samples_buf,
|
||||||
src_data.output_frames, mixer_gain, override);
|
src_data.output_frames, mixer_gain, override);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user