(Resampler code) Cleanups

This commit is contained in:
twinaphex 2014-09-26 15:50:24 +02:00
parent 6cb07c02ab
commit 9abaa15873
4 changed files with 54 additions and 39 deletions

View File

@ -68,13 +68,15 @@ typedef struct rarch_CC_resampler
static void *memalign_alloc__(size_t boundary, size_t size) static void *memalign_alloc__(size_t boundary, size_t size)
{ {
uintptr_t addr;
void **place;
void *ptr = malloc(boundary + size + sizeof(uintptr_t)); void *ptr = malloc(boundary + size + sizeof(uintptr_t));
if (!ptr) if (!ptr)
return NULL; return NULL;
uintptr_t addr = ((uintptr_t)ptr + addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary)
sizeof(uintptr_t) + boundary) & ~(boundary - 1); & ~(boundary - 1);
void **place = (void**)addr; place = (void**)addr;
place[-1] = ptr; place[-1] = ptr;
return (void*)addr; return (void*)addr;
@ -89,14 +91,14 @@ static void memalign_free__(void *ptr)
#ifdef _MIPS_ARCH_ALLEGREX #ifdef _MIPS_ARCH_ALLEGREX
static void resampler_CC_process(void *re_, struct resampler_data *data) static void resampler_CC_process(void *re_, struct resampler_data *data)
{ {
(void)re_;
float ratio, fraction; float ratio, fraction;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*) audio_frame_float_t *inp_max = (audio_frame_float_t*)
(inp + data->input_frames); (inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
(void)re_;
__asm__ ( __asm__ (
".set push\n" ".set push\n"
".set noreorder\n" ".set noreorder\n"
@ -214,6 +216,7 @@ static void *resampler_CC_init(double bandwidth_mod)
static void resampler_CC_downsample(void *re_, struct resampler_data *data) static void resampler_CC_downsample(void *re_, struct resampler_data *data)
{ {
__m128 vec_previous, vec_current;
float ratio, b; float ratio, b;
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
@ -224,8 +227,8 @@ static void resampler_CC_downsample(void *re_, struct resampler_data *data)
ratio = 1.0 / data->ratio; ratio = 1.0 / data->ratio;
b = data->ratio; /* cutoff frequency. */ b = data->ratio; /* cutoff frequency. */
__m128 vec_previous = _mm_loadu_ps((float*)&re->buffer[0]); vec_previous = _mm_loadu_ps((float*)&re->buffer[0]);
__m128 vec_current = _mm_loadu_ps((float*)&re->buffer[2]); vec_current = _mm_loadu_ps((float*)&re->buffer[2]);
while (inp != inp_max) while (inp != inp_max)
{ {
@ -299,6 +302,7 @@ static void resampler_CC_downsample(void *re_, struct resampler_data *data)
static void resampler_CC_upsample(void *re_, struct resampler_data *data) static void resampler_CC_upsample(void *re_, struct resampler_data *data)
{ {
__m128 vec_previous, vec_current;
float b, ratio; float b, ratio;
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
@ -309,10 +313,8 @@ static void resampler_CC_upsample(void *re_, struct resampler_data *data)
b = min(data->ratio, 1.00); /* cutoff frequency. */ b = min(data->ratio, 1.00); /* cutoff frequency. */
ratio = 1.0 / data->ratio; ratio = 1.0 / data->ratio;
__m128 vec_previous = _mm_loadu_ps((float*)&re->buffer[0]); vec_previous = _mm_loadu_ps((float*)&re->buffer[0]);
__m128 vec_current = _mm_loadu_ps((float*)&re->buffer[2]); vec_current = _mm_loadu_ps((float*)&re->buffer[2]);
while (inp != inp_max) while (inp != inp_max)
{ {
@ -394,12 +396,14 @@ size_t resampler_CC_upsample_neon (float *outp, const float *inp,
static void resampler_CC_downsample(void *re_, struct resampler_data *data) static void resampler_CC_downsample(void *re_, struct resampler_data *data)
{ {
data->output_frames = resampler_CC_downsample_neon(data->data_out, data->data_in, re_, data->input_frames, data->ratio); data->output_frames = resampler_CC_downsample_neon(
data->data_out, data->data_in, re_, data->input_frames, data->ratio);
} }
static void resampler_CC_upsample(void *re_, struct resampler_data *data) static void resampler_CC_upsample(void *re_, struct resampler_data *data)
{ {
data->output_frames = resampler_CC_upsample_neon(data->data_out, data->data_in, re_, data->input_frames, data->ratio); data->output_frames = resampler_CC_upsample_neon(
data->data_out, data->data_in, re_, data->input_frames, data->ratio);
} }
#else #else
@ -448,7 +452,8 @@ static void resampler_CC_downsample(void *re_, struct resampler_data *data)
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames); audio_frame_float_t *inp_max = (audio_frame_float_t*)
(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
ratio = 1.0 / data->ratio; ratio = 1.0 / data->ratio;
@ -487,7 +492,8 @@ static void resampler_CC_upsample(void *re_, struct resampler_data *data)
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames); audio_frame_float_t *inp_max = (audio_frame_float_t*)
(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out; audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
b = min(data->ratio, 1.00); /* cutoff frequency. */ b = min(data->ratio, 1.00); /* cutoff frequency. */
@ -555,7 +561,7 @@ static void *resampler_CC_init(double bandwidth_mod)
RARCH_LOG("Convoluted Cosine resampler (" CC_RESAMPLER_IDENT ") - precision = %i : ", CC_RESAMPLER_PRECISION); RARCH_LOG("Convoluted Cosine resampler (" CC_RESAMPLER_IDENT ") - precision = %i : ", CC_RESAMPLER_PRECISION);
/* variations of data->ratio around 0.75 are safer /* Variations of data->ratio around 0.75 are safer
* than around 1.0 for both up/downsampler. */ * than around 1.0 for both up/downsampler. */
if (bandwidth_mod < 0.75) if (bandwidth_mod < 0.75)
{ {

View File

@ -20,22 +20,23 @@ typedef struct rarch_nearest_resampler
float fraction; float fraction;
} rarch_nearest_resampler_t; } rarch_nearest_resampler_t;
static void resampler_nearest_process(void *re_, static void resampler_nearest_process(
struct resampler_data *data) void *re_, struct resampler_data *data)
{ {
float ratio;
rarch_nearest_resampler_t *re = (rarch_nearest_resampler_t*)re_; rarch_nearest_resampler_t *re = (rarch_nearest_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in; audio_frame_float_t *inp_max = (audio_frame_float_t*)inp + data->input_frames;
audio_frame_float_t *inp_max = inp + data->input_frames; audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
float ratio = ratio = 1.0/data->ratio; ratio = 1.0 / data->ratio;
while(inp != inp_max) while(inp != inp_max)
{ {
while(re->fraction > 1) while(re->fraction > 1)
{ {
*outp++=*inp; *outp++ = *inp;
re->fraction-=ratio; re->fraction -= ratio;
} }
re->fraction++; re->fraction++;
inp++; inp++;

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - Daniel De Matteis
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * 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- * of the GNU General Public License as published by the Free Software Found-
@ -27,7 +28,7 @@
#include "../../boolean.h" #include "../../boolean.h"
#ifndef M_PI #ifndef M_PI
/* M_PI is left out of ISO C99 :( */ /* M_PI is left out of ISO C99 */
#define M_PI 3.14159265358979323846264338327 #define M_PI 3.14159265358979323846264338327
#endif #endif
@ -44,7 +45,7 @@ struct resampler_data
typedef struct rarch_resampler typedef struct rarch_resampler
{ {
/* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsamling. /* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsampling.
* Corresponds to expected resampling ratio. */ * Corresponds to expected resampling ratio. */
void *(*init)(double bandwidth_mod); void *(*init)(double bandwidth_mod);
void (*process)(void *re, struct resampler_data *data); void (*process)(void *re, struct resampler_data *data);

View File

@ -181,18 +181,20 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
int i, j, p; int i, j, p;
double window_mod = window_function(0.0); /* Need to normalize w(0) to 1.0. */ double window_mod = 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;
for (i = 0; i < phases; i++) for (i = 0; i < phases; i++)
{ {
for (j = 0; j < taps; j++) for (j = 0; j < taps; j++)
{ {
double window_phase, sinc_phase;
float val;
int n = j * phases + i; int n = j * phases + i;
double window_phase = (double)n / (phases * taps); /* [0, 1). */ 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) */
double sinc_phase = sidelobes * window_phase; sinc_phase = sidelobes * window_phase;
float val = cutoff * sinc(M_PI * sinc_phase * cutoff) * val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
window_function(window_phase) / window_mod; window_function(window_phase) / window_mod;
phase_table[i * stride * taps + j] = val; phase_table[i * stride * taps + j] = val;
} }
@ -213,14 +215,16 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
int phase = phases - 1; int phase = phases - 1;
for (j = 0; j < taps; j++) for (j = 0; j < taps; j++)
{ {
float val, delta;
double window_phase, sinc_phase;
int n = j * phases + (phase + 1); int n = j * phases + (phase + 1);
double window_phase = (double)n / (phases * taps); /* (0, 1]. */ 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] */
double sinc_phase = sidelobes * window_phase; sinc_phase = sidelobes * window_phase;
float val = cutoff * sinc(M_PI * sinc_phase * cutoff) * val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
window_function(window_phase) / window_mod; window_function(window_phase) / window_mod;
float delta = (val - phase_table[phase * stride * taps + j]); delta = (val - phase_table[phase * stride * taps + j]);
phase_table[(phase * stride + 1) * taps + j] = delta; phase_table[(phase * stride + 1) * taps + j] = delta;
} }
} }
@ -229,13 +233,16 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
/* No memalign() for us on Win32 ... */ /* No memalign() for us on Win32 ... */
static void *aligned_alloc__(size_t boundary, size_t size) static void *aligned_alloc__(size_t boundary, size_t size)
{ {
uintptr_t addr;
void **place;
void *ptr = malloc(boundary + size + sizeof(uintptr_t)); void *ptr = malloc(boundary + size + sizeof(uintptr_t));
if (!ptr) if (!ptr)
return NULL; return NULL;
uintptr_t addr = ((uintptr_t)ptr + addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary)
sizeof(uintptr_t) + boundary) & ~(boundary - 1); & ~(boundary - 1);
void **place = (void**)addr; place = (void**)addr;
place[-1] = ptr; place[-1] = ptr;
return (void*)addr; return (void*)addr;
@ -373,7 +380,7 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
sum_r = _mm_add_ps(sum_r, _mm_mul_ps(buf_r, sinc)); sum_r = _mm_add_ps(sum_r, _mm_mul_ps(buf_r, sinc));
} }
/* Them annoying shuffles :V /* Them annoying shuffles.
* sum_l = { l3, l2, l1, l0 } * sum_l = { l3, l2, l1, l0 }
* sum_r = { r3, r2, r1, r0 } * sum_r = { r3, r2, r1, r0 }
*/ */