ref: a869c4734a0df7a35b7616089db89cf64fcb3d80
parent: 6edaad13465e6739f185884bd2d308e1f50d7cc9
author: Chris Moeller <kode54@gmail.com>
date: Sat May 4 17:07:58 EDT 2013
Optimizations and bug fixes for the Lanczos resampler
--- a/dumb/src/helpers/lanczos_resampler.c
+++ b/dumb/src/helpers/lanczos_resampler.c
@@ -9,10 +9,16 @@
enum { LANCZOS_WIDTH = 8 };
enum { LANCZOS_SAMPLES = LANCZOS_RESOLUTION * LANCZOS_WIDTH };
-static double lanczos_lut[LANCZOS_SAMPLES];
+static double lanczos_lut[LANCZOS_SAMPLES + 1];
enum { lanczos_buffer_size = LANCZOS_WIDTH * 4 };
+int my_abs(int in)
+{
+ int const mask = in >> sizeof(int) * CHAR_BIT - 1;
+ return (in + mask) ^ mask;
+}
+
int fEqual(const double b, const double a)
{
return fabs(a - b) < 1.0e-6;
@@ -27,8 +33,8 @@
{
unsigned i;
double dx = (double)(LANCZOS_WIDTH) / LANCZOS_SAMPLES, x = 0.0;
- for (i = 0; i < LANCZOS_SAMPLES; ++i, x += dx)
- lanczos_lut[i] = abs(x) < LANCZOS_WIDTH ? sinc(x) * sinc(x / LANCZOS_WIDTH) : 0.0;
+ for (i = 0; i < LANCZOS_SAMPLES + 1; ++i, x += dx)
+ lanczos_lut[i] = my_abs(x) < LANCZOS_WIDTH ? sinc(x) * sinc(x / LANCZOS_WIDTH) : 0.0;
}
typedef struct lanczos_resampler
@@ -37,7 +43,7 @@
int read_pos, read_filled;
unsigned short phase;
unsigned int phase_inc;
- int buffer_in[lanczos_buffer_size * 2];
+ float buffer_in[lanczos_buffer_size * 2];
int buffer_out[lanczos_buffer_size];
} lanczos_resampler;
@@ -116,7 +122,7 @@
if ( r->write_filled < lanczos_buffer_size )
{
- int s32 = s;
+ float s32 = s;
r->buffer_in[ r->write_pos ] = s32;
r->buffer_in[ r->write_pos + lanczos_buffer_size ] = s32;
@@ -131,14 +137,14 @@
{
lanczos_resampler * r = ( lanczos_resampler * ) _r;
int in_size = r->write_filled;
- int const* in_ = r->buffer_in + lanczos_buffer_size + r->write_pos - r->write_filled;
+ float const* in_ = r->buffer_in + lanczos_buffer_size + r->write_pos - r->write_filled;
int used = 0;
in_size -= LANCZOS_WIDTH * 2;
if ( in_size > 0 )
{
int* out = *out_;
- int const* in = in_;
- int const* const in_end = in + in_size;
+ float const* in = in_;
+ float const* const in_end = in + in_size;
int phase = r->phase;
int phase_inc = r->phase_inc;
@@ -158,7 +164,7 @@
for (; i >= -LANCZOS_WIDTH + 1; --i)
{
int pos = i * step;
- kernel_sum += kernel[i + LANCZOS_WIDTH - 1] = lanczos_lut[abs(phase_adj - pos)];
+ kernel_sum += kernel[i + LANCZOS_WIDTH - 1] = lanczos_lut[my_abs(phase_adj - pos)];
}
for (sample = 0, i = 0; i < LANCZOS_WIDTH * 2; ++i)
sample += in[i] * kernel[i];