shithub: dumb

Download patch

ref: a8d9baafc008bc851bce7b0aef799b74b9732a76
parent: 0d21e1317cb204c4975cb98f7ab3ca5685aca910
author: Chris Moeller <[email protected]>
date: Sat Mar 22 12:29:27 EDT 2014

Renamed lanczos_resampler to sinc_resampler, changed to Blackman window

--- a/dumb/cmake/CMakeLists.txt
+++ b/dumb/cmake/CMakeLists.txt
@@ -101,7 +101,7 @@
     ../src/it/loadany2.c
     ../src/it/loadany.c
     ../src/it/readany2.c
-    ../src/helpers/lanczos_resampler.c
+    ../src/helpers/sinc_resampler.c
     ../src/helpers/lpc.c
 )
 
--- a/dumb/include/internal/lanczos_resampler.h
+++ /dev/null
@@ -1,39 +1,0 @@
-#ifndef _LANCZOS_RESAMPLER_H_
-#define _LANCZOS_RESAMPLER_H_
-
-// Ugglay
-#ifdef LANCZOS_DECORATE
-#define PASTE(a,b) a ## b
-#define EVALUATE(a,b) PASTE(a,b)
-#define lanczos_init EVALUATE(LANCZOS_DECORATE,_lanczos_init)
-#define lanczos_resampler_create EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_create)
-#define lanczos_resampler_delete EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_delete)
-#define lanczos_resampler_dup EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_dup)
-#define lanczos_resampler_dup_inplace EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_dup_inplace)
-#define lanczos_resampler_get_free_count EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_get_free_count)
-#define lanczos_resampler_write_sample EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_write_sample)
-#define lanczos_resampler_set_rate EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_set_rate)
-#define lanczos_resampler_ready EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_ready)
-#define lanczos_resampler_clear EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_clear)
-#define lanczos_resampler_get_sample_count EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_get_sample_count)
-#define lanczos_resampler_get_sample EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_get_sample)
-#define lanczos_resampler_remove_sample EVALUATE(LANCZOS_DECORATE,_lanczos_resampler_remove_sample)
-#endif
-
-void lanczos_init(void);
-
-void * lanczos_resampler_create(void);
-void lanczos_resampler_delete(void *);
-void * lanczos_resampler_dup(const void *);
-void lanczos_resampler_dup_inplace(void *, const void *);
-
-int lanczos_resampler_get_free_count(void *);
-void lanczos_resampler_write_sample(void *, short sample);
-void lanczos_resampler_set_rate( void *, double new_factor );
-int lanczos_resampler_ready(void *);
-void lanczos_resampler_clear(void *);
-int lanczos_resampler_get_sample_count(void *);
-int lanczos_resampler_get_sample(void *);
-void lanczos_resampler_remove_sample(void *);
-
-#endif
--- /dev/null
+++ b/dumb/include/internal/sinc_resampler.h
@@ -1,0 +1,39 @@
+#ifndef _SINC_RESAMPLER_H_
+#define _SINC_RESAMPLER_H_
+
+// Ugglay
+#ifdef SINC_DECORATE
+#define PASTE(a,b) a ## b
+#define EVALUATE(a,b) PASTE(a,b)
+#define sinc_init EVALUATE(SINC_DECORATE,_sinc_init)
+#define sinc_resampler_create EVALUATE(SINC_DECORATE,_sinc_resampler_create)
+#define sinc_resampler_delete EVALUATE(SINC_DECORATE,_sinc_resampler_delete)
+#define sinc_resampler_dup EVALUATE(SINC_DECORATE,_sinc_resampler_dup)
+#define sinc_resampler_dup_inplace EVALUATE(SINC_DECORATE,_sinc_resampler_dup_inplace)
+#define sinc_resampler_get_free_count EVALUATE(SINC_DECORATE,_sinc_resampler_get_free_count)
+#define sinc_resampler_write_sample EVALUATE(SINC_DECORATE,_sinc_resampler_write_sample)
+#define sinc_resampler_set_rate EVALUATE(SINC_DECORATE,_sinc_resampler_set_rate)
+#define sinc_resampler_ready EVALUATE(SINC_DECORATE,_sinc_resampler_ready)
+#define sinc_resampler_clear EVALUATE(SINC_DECORATE,_sinc_resampler_clear)
+#define sinc_resampler_get_sample_count EVALUATE(SINC_DECORATE,_sinc_resampler_get_sample_count)
+#define sinc_resampler_get_sample EVALUATE(SINC_DECORATE,_sinc_resampler_get_sample)
+#define sinc_resampler_remove_sample EVALUATE(SINC_DECORATE,_sinc_resampler_remove_sample)
+#endif
+
+void sinc_init(void);
+
+void * sinc_resampler_create(void);
+void sinc_resampler_delete(void *);
+void * sinc_resampler_dup(const void *);
+void sinc_resampler_dup_inplace(void *, const void *);
+
+int sinc_resampler_get_free_count(void *);
+void sinc_resampler_write_sample(void *, short sample);
+void sinc_resampler_set_rate( void *, double new_factor );
+int sinc_resampler_ready(void *);
+void sinc_resampler_clear(void *);
+int sinc_resampler_get_sample_count(void *);
+int sinc_resampler_get_sample(void *);
+void sinc_resampler_remove_sample(void *);
+
+#endif
--- a/dumb/prj/dumb/dumb.pro
+++ b/dumb/prj/dumb/dumb.pro
@@ -101,7 +101,7 @@
     ../../src/it/loadany2.c \
     ../../src/it/loadany.c \
     ../../src/it/readany2.c \
-    ../../src/helpers/lanczos_resampler.c \
+    ../../src/helpers/sinc_resampler.c \
     ../../src/helpers/lpc.c
 
 HEADERS += \
@@ -113,7 +113,7 @@
     ../../include/internal/barray.h \
     ../../include/internal/tarray.h \
     ../../include/internal/aldumb.h \
-    ../../include/internal/lanczos_resampler.h \
+    ../../include/internal/sinc_resampler.h \
     ../../include/internal/stack_alloc.h \
     ../../include/internal/lpc.h \
     ../../include/internal/dumbfile.h
--- a/dumb/src/helpers/lanczos_resampler.c
+++ /dev/null
@@ -1,355 +1,0 @@
-#include <stdlib.h>
-#include <string.h>
-#define _USE_MATH_DEFINES
-#include <math.h>
-#if (defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__amd64__))
-#include <xmmintrin.h>
-#define LANCZOS_SSE
-#endif
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#include "internal/lanczos_resampler.h"
-
-enum { LANCZOS_RESOLUTION = 8192 };
-enum { LANCZOS_WIDTH = 16 };
-enum { LANCZOS_SAMPLES = LANCZOS_RESOLUTION * LANCZOS_WIDTH };
-
-static float lanczos_lut[LANCZOS_SAMPLES + 1];
-
-enum { lanczos_buffer_size = LANCZOS_WIDTH * 4 };
-
-static int fEqual(const float b, const float a)
-{
-    return fabs(a - b) < 1.0e-6;
-}
-
-static float sinc(float x)
-{
-    return fEqual(x, 0.0) ? 1.0 : sin(x * M_PI) / (x * M_PI);
-}
-
-#ifdef LANCZOS_SSE
-#ifdef _MSC_VER
-#include <intrin.h>
-#elif defined(__clang__) || defined(__GNUC__)
-static inline void
-__cpuid(int *data, int selector)
-{
-    asm("cpuid"
-        : "=a" (data[0]),
-        "=b" (data[1]),
-        "=c" (data[2]),
-        "=d" (data[3])
-        : "a"(selector));
-}
-#else
-#define __cpuid(a,b) memset((a), 0, sizeof(int) * 4)
-#endif
-
-static int query_cpu_feature_sse() {
-	int buffer[4];
-	__cpuid(buffer,1);
-	if ((buffer[3]&(1<<25)) == 0) return 0;
-	return 1;
-}
-
-static int lanczos_has_sse = 0;
-#endif
-
-void lanczos_init(void)
-{
-    unsigned i;
-    float dx = (float)(LANCZOS_WIDTH) / LANCZOS_SAMPLES, x = 0.0;
-    for (i = 0; i < LANCZOS_SAMPLES + 1; ++i, x += dx)
-        lanczos_lut[i] = fabs(x) < LANCZOS_WIDTH ? sinc(x) * sinc(x / LANCZOS_WIDTH) : 0.0;
-#ifdef LANCZOS_SSE
-    lanczos_has_sse = query_cpu_feature_sse();
-#endif
-}
-
-typedef struct lanczos_resampler
-{
-    int write_pos, write_filled;
-    int read_pos, read_filled;
-    unsigned short phase;
-    unsigned int phase_inc;
-    float buffer_in[lanczos_buffer_size * 2];
-    int buffer_out[lanczos_buffer_size];
-} lanczos_resampler;
-
-void * lanczos_resampler_create(void)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) malloc( sizeof(lanczos_resampler) );
-    if ( !r ) return 0;
-
-    r->write_pos = 0;
-    r->write_filled = 0;
-    r->read_pos = 0;
-    r->read_filled = 0;
-    r->phase = 0;
-    r->phase_inc = 0;
-    memset( r->buffer_in, 0, sizeof(r->buffer_in) );
-    memset( r->buffer_out, 0, sizeof(r->buffer_out) );
-
-    return r;
-}
-
-void lanczos_resampler_delete(void * _r)
-{
-    free( _r );
-}
-
-void * lanczos_resampler_dup(const void * _r)
-{
-    const lanczos_resampler * r_in = ( const lanczos_resampler * ) _r;
-    lanczos_resampler * r_out = ( lanczos_resampler * ) malloc( sizeof(lanczos_resampler) );
-    if ( !r_out ) return 0;
-
-    r_out->write_pos = r_in->write_pos;
-    r_out->write_filled = r_in->write_filled;
-    r_out->read_pos = r_in->read_pos;
-    r_out->read_filled = r_in->read_filled;
-    r_out->phase = r_in->phase;
-    r_out->phase_inc = r_in->phase_inc;
-    memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) );
-    memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
-
-    return r_out;
-}
-
-void lanczos_resampler_dup_inplace(void *_d, const void *_s)
-{
-    const lanczos_resampler * r_in = ( const lanczos_resampler * ) _s;
-    lanczos_resampler * r_out = ( lanczos_resampler * ) _d;
-
-    r_out->write_pos = r_in->write_pos;
-    r_out->write_filled = r_in->write_filled;
-    r_out->read_pos = r_in->read_pos;
-    r_out->read_filled = r_in->read_filled;
-    r_out->phase = r_in->phase;
-    r_out->phase_inc = r_in->phase_inc;
-    memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) );
-    memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
-}
-
-int lanczos_resampler_get_free_count(void *_r)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    return lanczos_buffer_size - r->write_filled;
-}
-
-int lanczos_resampler_ready(void *_r)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    return r->write_filled > (LANCZOS_WIDTH * 2);
-}
-
-void lanczos_resampler_clear(void *_r)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    r->write_pos = 0;
-    r->write_filled = 0;
-    r->read_pos = 0;
-    r->read_filled = 0;
-    r->phase = 0;
-}
-
-void lanczos_resampler_set_rate(void *_r, double new_factor)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    r->phase_inc = (int)( new_factor * LANCZOS_RESOLUTION );
-}
-
-void lanczos_resampler_write_sample(void *_r, short s)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-
-    if ( r->write_filled < lanczos_buffer_size )
-    {
-        float s32 = s;
-
-        r->buffer_in[ r->write_pos ] = s32;
-        r->buffer_in[ r->write_pos + lanczos_buffer_size ] = s32;
-
-        ++r->write_filled;
-
-        r->write_pos = ( r->write_pos + 1 ) % lanczos_buffer_size;
-    }
-}
-
-static int lanczos_resampler_run(lanczos_resampler * r, int ** out_, int * out_end)
-{
-    int in_size = 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_;
-        float const* in = in_;
-        float const* const in_end = in + in_size;
-        int phase = r->phase;
-        int phase_inc = r->phase_inc;
-
-        int step = phase_inc > LANCZOS_RESOLUTION ? LANCZOS_RESOLUTION * LANCZOS_RESOLUTION / phase_inc : LANCZOS_RESOLUTION;
-
-        do
-        {
-            float kernel[LANCZOS_WIDTH * 2], kernel_sum = 0.0;
-            int i = LANCZOS_WIDTH;
-            int phase_adj = phase * step / LANCZOS_RESOLUTION;
-            float sample;
-
-            if ( out >= out_end )
-                break;
-
-            for (; i >= -LANCZOS_WIDTH + 1; --i)
-            {
-                int pos = i * step;
-                kernel_sum += kernel[i + LANCZOS_WIDTH - 1] = lanczos_lut[abs(phase_adj - pos)];
-            }
-            for (sample = 0, i = 0; i < LANCZOS_WIDTH * 2; ++i)
-                sample += in[i] * kernel[i];
-            *out++ = (int)(sample / kernel_sum * 256.0);
-
-            phase += phase_inc;
-
-            in += phase >> 13;
-
-            phase &= 8191;
-        }
-        while ( in < in_end );
-
-        r->phase = (unsigned short) phase;
-        *out_ = out;
-
-        used = (int)(in - in_);
-
-        r->write_filled -= used;
-    }
-
-    return used;
-}
-
-#ifdef LANCZOS_SSE
-static int lanczos_resampler_run_sse(lanczos_resampler * r, int ** out_, int * out_end)
-{
-    int in_size = 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_;
-        float const* in = in_;
-        float const* const in_end = in + in_size;
-        int phase = r->phase;
-        int phase_inc = r->phase_inc;
-        
-        int step = phase_inc > LANCZOS_RESOLUTION ? LANCZOS_RESOLUTION * LANCZOS_RESOLUTION / phase_inc : LANCZOS_RESOLUTION;
-        
-        do
-        {
-            float kernel_sum = 0.0;
-            __m128 kernel[LANCZOS_WIDTH / 2];
-            __m128 temp1, temp2;
-            __m128 samplex = _mm_setzero_ps();
-            float *kernelf = (float*)(&kernel);
-            int i = LANCZOS_WIDTH;
-            int phase_adj = phase * step / LANCZOS_RESOLUTION;
-            
-            if ( out >= out_end )
-                break;
-            
-            for (; i >= -LANCZOS_WIDTH + 1; --i)
-            {
-                int pos = i * step;
-                kernel_sum += kernelf[i + LANCZOS_WIDTH - 1] = lanczos_lut[abs(phase_adj - pos)];
-            }
-            for (i = 0; i < LANCZOS_WIDTH / 2; ++i)
-            {
-                temp1 = _mm_loadu_ps( (const float *)( in + i * 4 ) );
-                temp2 = _mm_load_ps( (const float *)( kernel + i ) );
-                temp1 = _mm_mul_ps( temp1, temp2 );
-                samplex = _mm_add_ps( samplex, temp1 );
-            }
-            kernel_sum = 1.0 / kernel_sum * 256.0;
-            temp1 = _mm_movehl_ps( temp1, samplex );
-            samplex = _mm_add_ps( samplex, temp1 );
-            temp1 = samplex;
-            temp1 = _mm_shuffle_ps( temp1, samplex, _MM_SHUFFLE(0, 0, 0, 1) );
-            samplex = _mm_add_ps( samplex, temp1 );
-            temp1 = _mm_set_ss( kernel_sum );
-            samplex = _mm_mul_ps( samplex, temp1 );
-            *out++ = _mm_cvtss_si32( samplex );
-            
-            phase += phase_inc;
-            
-            in += phase >> 13;
-            
-            phase &= 8191;
-        }
-        while ( in < in_end );
-        
-        r->phase = (unsigned short) phase;
-        *out_ = out;
-        
-        used = (int)(in - in_);
-        
-        r->write_filled -= used;
-    }
-    
-    return used;
-}
-#endif
-
-static void lanczos_resampler_fill(lanczos_resampler * r)
-{
-    while ( r->write_filled > (LANCZOS_WIDTH * 2) &&
-            r->read_filled < lanczos_buffer_size )
-    {
-        int write_pos = ( r->read_pos + r->read_filled ) % lanczos_buffer_size;
-        int write_size = lanczos_buffer_size - write_pos;
-        int * out = r->buffer_out + write_pos;
-        if ( write_size > ( lanczos_buffer_size - r->read_filled ) )
-            write_size = lanczos_buffer_size - r->read_filled;
-#ifdef LANCZOS_SSE
-        if ( lanczos_has_sse )
-            lanczos_resampler_run_sse( r, &out, out + write_size );
-        else
-#endif
-            lanczos_resampler_run( r, &out, out + write_size );
-        r->read_filled += out - r->buffer_out - write_pos;
-    }
-}
-
-int lanczos_resampler_get_sample_count(void *_r)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    if ( r->read_filled < 1 )
-        lanczos_resampler_fill( r );
-    return r->read_filled;
-}
-
-int lanczos_resampler_get_sample(void *_r)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    if ( r->read_filled < 1 )
-        lanczos_resampler_fill( r );
-    if ( r->read_filled < 1 )
-        return 0;
-    return r->buffer_out[ r->read_pos ];
-}
-
-void lanczos_resampler_remove_sample(void *_r)
-{
-    lanczos_resampler * r = ( lanczos_resampler * ) _r;
-    if ( r->read_filled > 0 )
-    {
-        --r->read_filled;
-        r->read_pos = ( r->read_pos + 1 ) % lanczos_buffer_size;
-    }
-}
--- a/dumb/src/helpers/resamp3.inc
+++ b/dumb/src/helpers/resamp3.inc
@@ -198,13 +198,13 @@
                                     /* FIR resampling, backwards */
                                     SRCTYPE *x;
                                     if ( resampler->fir_resampler_ratio != delta ) {
-                                        lanczos_resampler_set_rate( resampler->fir_resampler[0], delta );
-                                        lanczos_resampler_set_rate( resampler->fir_resampler[1], delta );
+                                        sinc_resampler_set_rate( resampler->fir_resampler[0], delta );
+                                        sinc_resampler_set_rate( resampler->fir_resampler[1], delta );
                                         resampler->fir_resampler_ratio = delta;
                                     }
                                     x = &src[pos*SRC_CHANNELS];
                                     while ( todo ) {
-                                            while ( lanczos_resampler_get_free_count( resampler->fir_resampler[0] ) &&
+                                            while ( sinc_resampler_get_free_count( resampler->fir_resampler[0] ) &&
                                                     pos >= resampler->start )
                                             {
                                                     POKE_FIR(0);
@@ -211,7 +211,7 @@
                                                     pos--;
                                                     x -= SRC_CHANNELS;
                                             }
-                                            if ( !lanczos_resampler_get_sample_count( resampler->fir_resampler[0] ) ) break;
+                                            if ( !sinc_resampler_get_sample_count( resampler->fir_resampler[0] ) ) break;
                                             MIX_FIR;
                                             ADVANCE_FIR;
                                             --todo;
@@ -330,13 +330,13 @@
                                     /* FIR resampling, forwards */
                                     SRCTYPE *x;
                                     if ( resampler->fir_resampler_ratio != delta ) {
-                                        lanczos_resampler_set_rate( resampler->fir_resampler[0], delta );
-                                        lanczos_resampler_set_rate( resampler->fir_resampler[1], delta );
+                                        sinc_resampler_set_rate( resampler->fir_resampler[0], delta );
+                                        sinc_resampler_set_rate( resampler->fir_resampler[1], delta );
                                         resampler->fir_resampler_ratio = delta;
                                     }
                                     x = &src[pos*SRC_CHANNELS];
                                     while ( todo ) {
-                                            while ( lanczos_resampler_get_free_count( resampler->fir_resampler[0] ) &&
+                                            while ( sinc_resampler_get_free_count( resampler->fir_resampler[0] ) &&
                                                     pos < resampler->end )
                                             {
                                                     POKE_FIR(0);
@@ -343,7 +343,7 @@
                                                     pos++;
                                                     x += SRC_CHANNELS;
                                             }
-                                            if ( !lanczos_resampler_get_sample_count( resampler->fir_resampler[0] ) ) break;
+                                            if ( !sinc_resampler_get_sample_count( resampler->fir_resampler[0] ) ) break;
                                             MIX_FIR;
                                             ADVANCE_FIR;
                                             --todo;
--- a/dumb/src/helpers/resample.c
+++ b/dumb/src/helpers/resample.c
@@ -46,7 +46,7 @@
 #include "dumb.h"
 
 #include "internal/blip_buf.h"
-#include "internal/lanczos_resampler.h"
+#include "internal/sinc_resampler.h"
 
 
 
@@ -171,7 +171,7 @@
 		cubicA1[t] =  (int)(3*t*t*t >> 17) - (int)(5*t*t >> 7)                 + (int)(1 << 14);
 	}
 
-    lanczos_init();
+	sinc_init();
 
 	done = 1;
 }
--- a/dumb/src/helpers/resample.inc
+++ b/dumb/src/helpers/resample.inc
@@ -75,8 +75,8 @@
 	blip_clear(resampler->blip_buffer[0]);
 	blip_clear(resampler->blip_buffer[1]);
         resampler->fir_resampler_ratio = 0;
-        lanczos_resampler_clear(resampler->fir_resampler[0]);
-        lanczos_resampler_clear(resampler->fir_resampler[1]);
+        sinc_resampler_clear(resampler->fir_resampler[0]);
+        sinc_resampler_clear(resampler->fir_resampler[1]);
 }
 
 
@@ -158,15 +158,15 @@
 	resampler->last_clock += inv_dt; \
 }
 #define POKE_FIR(offset) { \
-        lanczos_resampler_write_sample( resampler->fir_resampler[0], FIR(x[offset]) ); \
+        sinc_resampler_write_sample( resampler->fir_resampler[0], FIR(x[offset]) ); \
 }
 #define MONO_DEST_PEEK_ALIAS *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), vol )
-#define MONO_DEST_PEEK_FIR *dst = MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[0] ), vol )
+#define MONO_DEST_PEEK_FIR *dst = MULSC( sinc_resampler_get_sample( resampler->fir_resampler[0] ), vol )
 #define MONO_DEST_MIX_FIR { \
-        *dst++ += MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[0] ), vol ); \
+        *dst++ += MULSC( sinc_resampler_get_sample( resampler->fir_resampler[0] ), vol ); \
         UPDATE_VOLUME( volume, vol ); \
 }
-#define ADVANCE_FIR lanczos_resampler_remove_sample( resampler->fir_resampler[0] )
+#define ADVANCE_FIR sinc_resampler_remove_sample( resampler->fir_resampler[0] )
 #define MONO_DEST_MIX_ALIAS(count) { \
 	int n = 0; \
 	resampler->last_clock -= count * 65536; \
@@ -184,12 +184,12 @@
 	*dst++ = MULSC( sample, rvol ); \
 }
 #define STEREO_DEST_PEEK_FIR { \
-        int sample = lanczos_resampler_get_sample( resampler->fir_resampler[0] ); \
+        int sample = sinc_resampler_get_sample( resampler->fir_resampler[0] ); \
         *dst++ = MULSC( sample, lvol ); \
         *dst++ = MULSC( sample, rvol ); \
 }
 #define STEREO_DEST_MIX_FIR { \
-        int sample = lanczos_resampler_get_sample( resampler->fir_resampler[0] ); \
+        int sample = sinc_resampler_get_sample( resampler->fir_resampler[0] ); \
         *dst++ += MULSC( sample, lvol ); \
         *dst++ += MULSC( sample, rvol ); \
         UPDATE_VOLUME( volume_left, lvol ); \
@@ -296,8 +296,8 @@
 	resampler->last_clock += inv_dt; \
 }
 #define POKE_FIR(offset) { \
-        lanczos_resampler_write_sample( resampler->fir_resampler[0], FIR(x[(offset)*2+0]) ); \
-        lanczos_resampler_write_sample( resampler->fir_resampler[1], FIR(x[(offset)*2+1]) ); \
+        sinc_resampler_write_sample( resampler->fir_resampler[0], FIR(x[(offset)*2+0]) ); \
+        sinc_resampler_write_sample( resampler->fir_resampler[1], FIR(x[(offset)*2+1]) ); \
 }
 #define MONO_DEST_PEEK_ALIAS { \
 	*dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ) + \
@@ -304,18 +304,18 @@
 		MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
 }
 #define MONO_DEST_PEEK_FIR { \
-        *dst = MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[0] ), lvol ) + \
-                MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
+        *dst = MULSC( sinc_resampler_get_sample( resampler->fir_resampler[0] ), lvol ) + \
+                MULSC( sinc_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
 }
 #define MONO_DEST_MIX_FIR { \
-        *dst++ += MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[0] ), lvol ) + \
-                MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
+        *dst++ += MULSC( sinc_resampler_get_sample( resampler->fir_resampler[0] ), lvol ) + \
+                MULSC( sinc_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
         UPDATE_VOLUME( volume_left, lvol ); \
         UPDATE_VOLUME( volume_right, rvol ); \
 }
 #define ADVANCE_FIR { \
-        lanczos_resampler_remove_sample( resampler->fir_resampler[0] ); \
-        lanczos_resampler_remove_sample( resampler->fir_resampler[1] ); \
+        sinc_resampler_remove_sample( resampler->fir_resampler[0] ); \
+        sinc_resampler_remove_sample( resampler->fir_resampler[1] ); \
 }
 #define MONO_DEST_MIX_ALIAS(count) { \
 	int n = 0; \
@@ -336,12 +336,12 @@
 	*dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
 }
 #define STEREO_DEST_PEEK_FIR { \
-        *dst++ = MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[0] ), lvol ); \
-        *dst++ = MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
+        *dst++ = MULSC( sinc_resampler_get_sample( resampler->fir_resampler[0] ), lvol ); \
+        *dst++ = MULSC( sinc_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
 }
 #define STEREO_DEST_MIX_FIR { \
-        *dst++ += MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[0] ), lvol ); \
-        *dst++ += MULSC( lanczos_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
+        *dst++ += MULSC( sinc_resampler_get_sample( resampler->fir_resampler[0] ), lvol ); \
+        *dst++ += MULSC( sinc_resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
         UPDATE_VOLUME( volume_left, lvol ); \
         UPDATE_VOLUME( volume_right, rvol ); \
 }
--- /dev/null
+++ b/dumb/src/helpers/sinc_resampler.c
@@ -1,0 +1,361 @@
+#include <stdlib.h>
+#include <string.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
+#if (defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__amd64__))
+#include <xmmintrin.h>
+#define SINC_SSE
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#include "sinc_resampler.h"
+
+enum { SINC_RESOLUTION = 8192 };
+enum { SINC_WIDTH = 16 };
+enum { SINC_SAMPLES = SINC_RESOLUTION * SINC_WIDTH };
+
+static float sinc_lut[SINC_SAMPLES + 1];
+
+enum { sinc_buffer_size = SINC_WIDTH * 4 };
+
+static int fEqual(const float b, const float a)
+{
+    return fabs(a - b) < 1.0e-6;
+}
+
+static float sinc(float x)
+{
+    return fEqual(x, 0.0) ? 1.0 : sin(x * M_PI) / (x * M_PI);
+}
+
+#ifdef SINC_SSE
+#ifdef _MSC_VER
+#include <intrin.h>
+#elif defined(__clang__) || defined(__GNUC__)
+static inline void
+__cpuid(int *data, int selector)
+{
+    asm("cpuid"
+        : "=a" (data[0]),
+        "=b" (data[1]),
+        "=c" (data[2]),
+        "=d" (data[3])
+        : "a"(selector));
+}
+#else
+#define __cpuid(a,b) memset((a), 0, sizeof(int) * 4)
+#endif
+
+static int query_cpu_feature_sse() {
+	int buffer[4];
+	__cpuid(buffer,1);
+	if ((buffer[3]&(1<<25)) == 0) return 0;
+	return 1;
+}
+
+static int sinc_has_sse = 0;
+#endif
+
+void sinc_init(void)
+{
+    unsigned i;
+    float dx = (float)(SINC_WIDTH) / SINC_SAMPLES, x = 0.0;
+    for (i = 0; i < SINC_SAMPLES + 1; ++i, x += dx)
+    {
+        float y = x / SINC_WIDTH;
+        float window = 0.42659 - 0.49656 * cos(M_PI + M_PI * y) + 0.076849 * cos(2.0 * M_PI * y);
+        sinc_lut[i] = fabs(x) < SINC_WIDTH ? sinc(x) * window : 0.0;
+    }
+#ifdef SINC_SSE
+    sinc_has_sse = query_cpu_feature_sse();
+#endif
+}
+
+typedef struct sinc_resampler
+{
+    int write_pos, write_filled;
+    int read_pos, read_filled;
+    unsigned short phase;
+    unsigned int phase_inc;
+    float buffer_in[sinc_buffer_size * 2];
+    int buffer_out[sinc_buffer_size];
+} sinc_resampler;
+
+void * sinc_resampler_create(void)
+{
+    sinc_resampler * r = ( sinc_resampler * ) malloc( sizeof(sinc_resampler) );
+    if ( !r ) return 0;
+
+    r->write_pos = 0;
+    r->write_filled = 0;
+    r->read_pos = 0;
+    r->read_filled = 0;
+    r->phase = 0;
+    r->phase_inc = 0;
+    memset( r->buffer_in, 0, sizeof(r->buffer_in) );
+    memset( r->buffer_out, 0, sizeof(r->buffer_out) );
+
+    return r;
+}
+
+void sinc_resampler_delete(void * _r)
+{
+    free( _r );
+}
+
+void * sinc_resampler_dup(const void * _r)
+{
+    const sinc_resampler * r_in = ( const sinc_resampler * ) _r;
+    sinc_resampler * r_out = ( sinc_resampler * ) malloc( sizeof(sinc_resampler) );
+    if ( !r_out ) return 0;
+
+    r_out->write_pos = r_in->write_pos;
+    r_out->write_filled = r_in->write_filled;
+    r_out->read_pos = r_in->read_pos;
+    r_out->read_filled = r_in->read_filled;
+    r_out->phase = r_in->phase;
+    r_out->phase_inc = r_in->phase_inc;
+    memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) );
+    memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
+
+    return r_out;
+}
+
+void sinc_resampler_dup_inplace(void *_d, const void *_s)
+{
+    const sinc_resampler * r_in = ( const sinc_resampler * ) _s;
+    sinc_resampler * r_out = ( sinc_resampler * ) _d;
+
+    r_out->write_pos = r_in->write_pos;
+    r_out->write_filled = r_in->write_filled;
+    r_out->read_pos = r_in->read_pos;
+    r_out->read_filled = r_in->read_filled;
+    r_out->phase = r_in->phase;
+    r_out->phase_inc = r_in->phase_inc;
+    memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) );
+    memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
+}
+
+int sinc_resampler_get_free_count(void *_r)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    return sinc_buffer_size - r->write_filled;
+}
+
+int sinc_resampler_ready(void *_r)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    return r->write_filled > (SINC_WIDTH * 2);
+}
+
+void sinc_resampler_clear(void *_r)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    r->write_pos = 0;
+    r->write_filled = 0;
+    r->read_pos = 0;
+    r->read_filled = 0;
+    r->phase = 0;
+}
+
+void sinc_resampler_set_rate(void *_r, double new_factor)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    r->phase_inc = (int)( new_factor * SINC_RESOLUTION );
+}
+
+void sinc_resampler_write_sample(void *_r, short s)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+
+    if ( r->write_filled < sinc_buffer_size )
+    {
+        float s32 = s;
+
+        r->buffer_in[ r->write_pos ] = s32;
+        r->buffer_in[ r->write_pos + sinc_buffer_size ] = s32;
+
+        ++r->write_filled;
+
+        r->write_pos = ( r->write_pos + 1 ) % sinc_buffer_size;
+    }
+}
+
+static int sinc_resampler_run(sinc_resampler * r, int ** out_, int * out_end)
+{
+    int in_size = r->write_filled;
+    float const* in_ = r->buffer_in + sinc_buffer_size + r->write_pos - r->write_filled;
+    int used = 0;
+    in_size -= SINC_WIDTH * 2;
+    if ( in_size > 0 )
+    {
+        int* out = *out_;
+        float const* in = in_;
+        float const* const in_end = in + in_size;
+        int phase = r->phase;
+        int phase_inc = r->phase_inc;
+
+        int step = phase_inc > SINC_RESOLUTION ? SINC_RESOLUTION * SINC_RESOLUTION / phase_inc : SINC_RESOLUTION;
+
+        do
+        {
+            // accumulate in extended precision
+            float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
+            int i = SINC_WIDTH;
+            int phase_adj = phase * step / SINC_RESOLUTION;
+            float sample;
+
+            if ( out >= out_end )
+                break;
+
+            for (; i >= -SINC_WIDTH + 1; --i)
+            {
+                int pos = i * step;
+                kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)];
+            }
+            for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
+                sample += in[i] * kernel[i];
+            *out++ = (int)(sample / kernel_sum * 256.0);
+
+            phase += phase_inc;
+
+            in += phase >> 13;
+
+            phase &= 8191;
+        }
+        while ( in < in_end );
+
+        r->phase = (unsigned short) phase;
+        *out_ = out;
+
+        used = (int)(in - in_);
+
+        r->write_filled -= used;
+    }
+
+    return used;
+}
+
+#ifdef SINC_SSE
+static int sinc_resampler_run_sse(sinc_resampler * r, int ** out_, int * out_end)
+{
+    int in_size = r->write_filled;
+    float const* in_ = r->buffer_in + sinc_buffer_size + r->write_pos - r->write_filled;
+    int used = 0;
+    in_size -= SINC_WIDTH * 2;
+    if ( in_size > 0 )
+    {
+        int* out = *out_;
+        float const* in = in_;
+        float const* const in_end = in + in_size;
+        int phase = r->phase;
+        int phase_inc = r->phase_inc;
+        
+        int step = phase_inc > SINC_RESOLUTION ? SINC_RESOLUTION * SINC_RESOLUTION / phase_inc : SINC_RESOLUTION;
+        
+        do
+        {
+            // accumulate in extended precision
+            float kernel_sum = 0.0;
+            __m128 kernel[SINC_WIDTH / 2];
+            __m128 temp1, temp2;
+            __m128 samplex = _mm_setzero_ps();
+            float *kernelf = (float*)(&kernel);
+            int i = SINC_WIDTH;
+            int phase_adj = phase * step / SINC_RESOLUTION;
+            
+            if ( out >= out_end )
+                break;
+            
+            for (; i >= -SINC_WIDTH + 1; --i)
+            {
+                int pos = i * step;
+                kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)];
+            }
+            for (i = 0; i < SINC_WIDTH / 2; ++i)
+            {
+                temp1 = _mm_loadu_ps( (const float *)( in + i * 4 ) );
+                temp2 = _mm_load_ps( (const float *)( kernel + i ) );
+                temp1 = _mm_mul_ps( temp1, temp2 );
+                samplex = _mm_add_ps( samplex, temp1 );
+            }
+            kernel_sum = 1.0 / kernel_sum * 256.0;
+            temp1 = _mm_movehl_ps( temp1, samplex );
+            samplex = _mm_add_ps( samplex, temp1 );
+            temp1 = samplex;
+            temp1 = _mm_shuffle_ps( temp1, samplex, _MM_SHUFFLE(0, 0, 0, 1) );
+            samplex = _mm_add_ps( samplex, temp1 );
+            temp1 = _mm_set_ss( kernel_sum );
+            samplex = _mm_mul_ps( samplex, temp1 );
+            *out++ = _mm_cvtss_si32( samplex );
+            
+            phase += phase_inc;
+            
+            in += phase >> 13;
+            
+            phase &= 8191;
+        }
+        while ( in < in_end );
+        
+        r->phase = (unsigned short) phase;
+        *out_ = out;
+        
+        used = (int)(in - in_);
+        
+        r->write_filled -= used;
+    }
+    
+    return used;
+}
+#endif
+
+static void sinc_resampler_fill(sinc_resampler * r)
+{
+    while ( r->write_filled > (SINC_WIDTH * 2) &&
+            r->read_filled < sinc_buffer_size )
+    {
+        int write_pos = ( r->read_pos + r->read_filled ) % sinc_buffer_size;
+        int write_size = sinc_buffer_size - write_pos;
+        int * out = r->buffer_out + write_pos;
+        if ( write_size > ( sinc_buffer_size - r->read_filled ) )
+            write_size = sinc_buffer_size - r->read_filled;
+#ifdef SINC_SSE
+        if ( sinc_has_sse )
+            sinc_resampler_run_sse( r, &out, out + write_size );
+        else
+#endif
+            sinc_resampler_run( r, &out, out + write_size );
+        r->read_filled += out - r->buffer_out - write_pos;
+    }
+}
+
+int sinc_resampler_get_sample_count(void *_r)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    if ( r->read_filled < 1 )
+        sinc_resampler_fill( r );
+    return r->read_filled;
+}
+
+int sinc_resampler_get_sample(void *_r)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    if ( r->read_filled < 1 )
+        sinc_resampler_fill( r );
+    if ( r->read_filled < 1 )
+        return 0;
+    return r->buffer_out[ r->read_pos ];
+}
+
+void sinc_resampler_remove_sample(void *_r)
+{
+    sinc_resampler * r = ( sinc_resampler * ) _r;
+    if ( r->read_filled > 0 )
+    {
+        --r->read_filled;
+        r->read_pos = ( r->read_pos + 1 ) % sinc_buffer_size;
+    }
+}
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -27,7 +27,7 @@
 #include "internal/lpc.h"
 
 #include "internal/blip_buf.h"
-#include "internal/lanczos_resampler.h"
+#include "internal/sinc_resampler.h"
 
 // #define BIT_ARRAY_BULLSHIT
 
@@ -52,7 +52,7 @@
 		blip_set_rates(r->resampler.blip_buffer[0], 65536, 1);
 		blip_set_rates(r->resampler.blip_buffer[1], 65536, 1);
 		r->resampler.fir_resampler_ratio = 0.0;
-		r->resampler.fir_resampler[0] = lanczos_resampler_create();
+		r->resampler.fir_resampler[0] = sinc_resampler_create();
 		if ( !r->resampler.fir_resampler[0] ) {
 			free( r->resampler.blip_buffer[1] );
 			free( r->resampler.blip_buffer[0] );
@@ -59,9 +59,9 @@
 			free( r );
 			return NULL;
 		}
-		r->resampler.fir_resampler[1] = lanczos_resampler_create();
+		r->resampler.fir_resampler[1] = sinc_resampler_create();
 		if ( !r->resampler.fir_resampler[1] ) {
-			lanczos_resampler_delete( r->resampler.fir_resampler[0] );
+			sinc_resampler_delete( r->resampler.fir_resampler[0] );
 			free( r->resampler.blip_buffer[1] );
 			free( r->resampler.blip_buffer[0] );
 			free( r );
@@ -73,8 +73,8 @@
 
 static void free_playing(IT_PLAYING * r)
 {
-	lanczos_resampler_delete( r->resampler.fir_resampler[1] );
-	lanczos_resampler_delete( r->resampler.fir_resampler[0] );
+	sinc_resampler_delete( r->resampler.fir_resampler[1] );
+	sinc_resampler_delete( r->resampler.fir_resampler[0] );
 	blip_delete( r->resampler.blip_buffer[1] );
 	blip_delete( r->resampler.blip_buffer[0] );
 	free( r );
@@ -180,7 +180,7 @@
 		return NULL;
 	}
 	dst->resampler.fir_resampler_ratio = src->resampler.fir_resampler_ratio;
-	dst->resampler.fir_resampler[0] = lanczos_resampler_dup( src->resampler.fir_resampler[0] );
+	dst->resampler.fir_resampler[0] = sinc_resampler_dup( src->resampler.fir_resampler[0] );
 	if ( !dst->resampler.fir_resampler[0] ) {
 		blip_delete( dst->resampler.blip_buffer[1] );
 		blip_delete( dst->resampler.blip_buffer[0] );
@@ -187,9 +187,9 @@
 		free( dst );
 		return NULL;
 	}
-	dst->resampler.fir_resampler[1] = lanczos_resampler_dup( src->resampler.fir_resampler[1] );
+	dst->resampler.fir_resampler[1] = sinc_resampler_dup( src->resampler.fir_resampler[1] );
 	if ( !dst->resampler.fir_resampler[1] ) {
-		lanczos_resampler_delete( dst->resampler.fir_resampler[0] );
+		sinc_resampler_delete( dst->resampler.fir_resampler[0] );
 		blip_delete( dst->resampler.blip_buffer[1] );
 		blip_delete( dst->resampler.blip_buffer[0] );
 		free( dst );
--- a/dumb/vc6/dumb/dumb.vcxproj
+++ b/dumb/vc6/dumb/dumb.vcxproj
@@ -112,7 +112,7 @@
     <ClCompile Include="..\..\src\helpers\blip_buf.c" />
     <ClCompile Include="..\..\src\helpers\clickrem.c" />
     <ClCompile Include="..\..\src\helpers\fir_resampler.c" />
-    <ClCompile Include="..\..\src\helpers\lanczos_resampler.c" />
+    <ClCompile Include="..\..\src\helpers\sinc_resampler.c" />
     <ClCompile Include="..\..\src\helpers\lpc.c" />
     <ClCompile Include="..\..\src\helpers\memfile.c" />
     <ClCompile Include="..\..\src\helpers\resample.c" />
@@ -209,7 +209,7 @@
     <ClInclude Include="..\..\include\internal\dumbfile.h" />
     <ClInclude Include="..\..\include\internal\fir_resampler.h" />
     <ClInclude Include="..\..\include\internal\it.h" />
-    <ClInclude Include="..\..\include\internal\lanczos_resampler.h" />
+    <ClInclude Include="..\..\include\internal\sinc_resampler.h" />
     <ClInclude Include="..\..\include\internal\lpc.h" />
     <ClInclude Include="..\..\include\internal\riff.h" />
     <ClInclude Include="..\..\include\internal\stack_alloc.h" />
@@ -218,4 +218,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
--- a/dumb/vc6/dumb/dumb.vcxproj.filters
+++ b/dumb/vc6/dumb/dumb.vcxproj.filters
@@ -282,7 +282,7 @@
     <ClCompile Include="..\..\src\it\readany2.c">
       <Filter>src\it\readers</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\helpers\lanczos_resampler.c">
+    <ClCompile Include="..\..\src\helpers\sinc_resampler.c">
       <Filter>src\helpers</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\helpers\tarray.c">
@@ -320,7 +320,7 @@
     <ClInclude Include="..\..\include\internal\blip_buf.h">
       <Filter>include\internal</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\include\internal\lanczos_resampler.h">
+    <ClInclude Include="..\..\include\internal\sinc_resampler.h">
       <Filter>include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\..\include\internal\tarray.h">
@@ -338,4 +338,4 @@
       <Filter>src\helpers</Filter>
     </CustomBuild>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>