ref: 74390bd111b0496a25967cd1418e6f7ec0a4a868
parent: cb8ab8c6f6ddef8a0938f771e3fad9d0ca6b2735
author: Chris Moeller <kode54@gmail.com>
date: Wed Mar 26 16:51:43 EDT 2014
Implemented blep synthesis into resampler.c, and removed blip_buf.c and code which referenced the old resamplers
--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -377,8 +377,6 @@
DUH_SIGRENDERER *dumb_it_start_at_order(DUH *duh, int n_channels, int startorder);
-void dumb_it_set_resampling_quality(DUMB_IT_SIGRENDERER * sigrenderer, int quality);
-
enum
{
DUMB_IT_RAMP_NONE = 0,
@@ -674,12 +672,15 @@
/* Resampling Helpers */
#define DUMB_RQ_ALIASING 0
-#define DUMB_RQ_LINEAR 1
-#define DUMB_RQ_CUBIC 2
-#define DUMB_RQ_FIR 3
-#define DUMB_RQ_N_LEVELS 4
-extern int dumb_resampling_quality;
+#define DUMB_RQ_BLEP 1
+#define DUMB_RQ_LINEAR 2
+#define DUMB_RQ_CUBIC 3
+#define DUMB_RQ_FIR 4
+#define DUMB_RQ_N_LEVELS 5
+extern int dumb_resampling_quality; /* This specifies the default */
+void dumb_it_set_resampling_quality(DUMB_IT_SIGRENDERER * sigrenderer, int quality); /* This overrides it */
+
typedef struct DUMB_RESAMPLER DUMB_RESAMPLER;
typedef struct DUMB_VOLUME_RAMP_INFO DUMB_VOLUME_RAMP_INFO;
@@ -686,11 +687,6 @@
typedef void (*DUMB_RESAMPLE_PICKUP)(DUMB_RESAMPLER *resampler, void *data);
-#ifndef BLIP_T_DEFINED
-#define BLIP_T_DEFINED
-typedef struct blip_t blip_t;
-#endif
-
struct DUMB_RESAMPLER
{
void *src;
@@ -708,9 +704,6 @@
signed char x8[3*2];
} x;
int overshot;
- int last_clock;
- int last_amp[2];
- blip_t* blip_buffer[2];
double fir_resampler_ratio;
void* fir_resampler[2];
};
--- a/dumb/include/internal/blip_buf.h
+++ /dev/null
@@ -1,80 +1,0 @@
-/** \file
-Sample buffer that resamples from input clock rate to output sample rate */
-
-/* blip_buf 1.1.0 */
-#ifndef BLIP_BUF_H
-#define BLIP_BUF_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/** First parameter of most functions is blip_t*, or const blip_t* if nothing
-is changed. */
-#ifndef BLIP_T_DEFINED
-#define BLIP_T_DEFINED
-typedef struct blip_t blip_t;
-#endif
-
-/** Creates new buffer that can hold at most sample_count samples. Sets rates
-so that there are blip_max_ratio clocks per sample. Returns pointer to new
-buffer, or NULL if insufficient memory. */
-blip_t* blip_new( int sample_count );
-
-blip_t* blip_dup( blip_t* );
-
-/** Sets approximate input clock rate and output sample rate. For every
-clock_rate input clocks, approximately sample_rate samples are generated. */
-void blip_set_rates( blip_t*, double clock_rate, double sample_rate );
-
-enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
-clock_rate must not be greater than sample_rate*blip_max_ratio. */
-blip_max_ratio = 1 << 20 };
-
-/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */
-void blip_clear( blip_t* );
-
-/** Adds positive/negative delta into buffer at specified clock time. */
-void blip_add_delta( blip_t*, unsigned int clock_time, int delta );
-
-/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */
-void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta );
-
-/** Length of time frame, in clocks, needed to make sample_count additional
-samples available. */
-int blip_clocks_needed( const blip_t*, int sample_count );
-
-enum { /** Maximum number of samples that can be generated from one time frame. */
-blip_max_frame = 4000 };
-
-/** Makes input clocks before clock_duration available for reading as output
-samples. Also begins new time frame at clock_duration, so that clock time 0 in
-the new time frame specifies the same clock as clock_duration in the old time
-frame specified. Deltas can have been added slightly past clock_duration (up to
-however many clocks there are in two output samples). */
-void blip_end_frame( blip_t*, unsigned int clock_duration );
-
-/** Number of buffered samples available for reading. */
-int blip_samples_avail( const blip_t* );
-
-/** Reads and removes at most 'count' samples and writes them to 'out'. If
-'stereo' is true, writes output to every other element of 'out', allowing easy
-interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed
-samples. Returns number of samples actually read. */
-int blip_read_samples( blip_t*, int out [], int count );
-
-/** Reads the current integrator and returns it */
-int blip_peek_sample( blip_t* );
-
-/** Frees buffer. No effect if NULL is passed. */
-void blip_delete( blip_t* );
-
-
-/* Deprecated */
-typedef blip_t blip_buffer_t;
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif
--- a/dumb/include/internal/resampler.h
+++ b/dumb/include/internal/resampler.h
@@ -32,10 +32,11 @@
{
RESAMPLER_QUALITY_MIN = 0,
RESAMPLER_QUALITY_ZOH = 0,
- RESAMPLER_QUALITY_LINEAR = 1,
- RESAMPLER_QUALITY_CUBIC = 2,
- RESAMPLER_QUALITY_SINC = 3,
- RESAMPLER_QUALITY_MAX = 3
+ RESAMPLER_QUALITY_BLEP = 1,
+ RESAMPLER_QUALITY_LINEAR = 2,
+ RESAMPLER_QUALITY_CUBIC = 3,
+ RESAMPLER_QUALITY_SINC = 4,
+ RESAMPLER_QUALITY_MAX = 4
};
void resampler_set_quality(void *, int quality);
--- a/dumb/src/helpers/blip_buf.c
+++ /dev/null
@@ -1,354 +1,0 @@
-/* blip_buf 1.1.0. http://www.slack.net/~ant/ */
-
-#include "internal/blip_buf.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* Library Copyright (C) 2003-2009 Shay Green. This library is free software;
-you can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-library 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 Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#if defined (BLARGG_TEST) && BLARGG_TEST
- #include "blargg_test.h"
-#endif
-
-/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000.
-Avoids constants that don't fit in 32 bits. */
-#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF
- typedef unsigned long fixed_t;
- enum { pre_shift = 32 };
-
-#elif defined(ULLONG_MAX)
- typedef unsigned long long fixed_t;
- enum { pre_shift = 32 };
-
-#else
- typedef unsigned fixed_t;
- enum { pre_shift = 0 };
-
-#endif
-
-enum { time_bits = pre_shift + 20 };
-
-static fixed_t const time_unit = (fixed_t) 1 << time_bits;
-
-enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */
-enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */
-
-enum { half_width = 8 };
-enum { buf_extra = half_width*2 + end_frame_extra };
-enum { phase_bits = 5 };
-enum { phase_count = 1 << phase_bits };
-enum { delta_bits = 15 };
-enum { delta_unit = 1 << delta_bits };
-enum { frac_bits = time_bits - pre_shift };
-
-/* We could eliminate avail and encode whole samples in offset, but that would
-limit the total buffered samples to blip_max_frame. That could only be
-increased by decreasing time_bits, which would reduce resample ratio accuracy.
-*/
-
-/** Sample buffer that resamples to output rate and accumulates samples
-until they're read out */
-struct blip_t
-{
- fixed_t factor;
- fixed_t offset;
- int avail;
- int size;
- int integrator;
-};
-
-typedef int buf_t;
-
-/* probably not totally portable */
-#define SAMPLES( buf ) ((buf_t*) ((buf) + 1))
-
-/* Arithmetic (sign-preserving) right shift */
-#define ARITH_SHIFT( n, shift ) \
- ((n) >> (shift))
-
-enum { max_sample = +32767 };
-enum { min_sample = -32768 };
-
-#define CLAMP( n ) \
- {\
- if ( (short) n != n )\
- n = ARITH_SHIFT( n, 16 ) ^ max_sample;\
- }
-
-static void check_assumptions( void )
-{
- int n;
-
- #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF
- #error "int must be at least 32 bits"
- #endif
-
- assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */
-
- n = max_sample * 2;
- CLAMP( n );
- assert( n == max_sample );
-
- n = min_sample * 2;
- CLAMP( n );
- assert( n == min_sample );
-
- assert( blip_max_ratio <= time_unit );
- assert( blip_max_frame <= (fixed_t) -1 >> time_bits );
-}
-
-blip_t* blip_new( int size )
-{
- blip_t* m;
- assert( size >= 0 );
-
- m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) );
- if ( m )
- {
- m->factor = time_unit / blip_max_ratio;
- m->size = size;
- blip_clear( m );
- check_assumptions();
- }
- return m;
-}
-
-blip_t* blip_dup( blip_t* m )
-{
- size_t size = sizeof *m + (m->size + buf_extra) * sizeof(buf_t);
- blip_t* r = (blip_t*) malloc( size );
- if ( r ) memcpy( r, m, size );
- return r;
-}
-
-void blip_delete( blip_t* m )
-{
- if ( m != NULL )
- {
- /* Clear fields in case user tries to use after freeing */
- memset( m, 0, sizeof *m );
- free( m );
- }
-}
-
-void blip_set_rates( blip_t* m, double clock_rate, double sample_rate )
-{
- double factor = time_unit * sample_rate / clock_rate;
- m->factor = (fixed_t) factor;
-
- /* Fails if clock_rate exceeds maximum, relative to sample_rate */
- assert( 0 <= factor - m->factor && factor - m->factor < 1 );
-
- /* Avoid requiring math.h. Equivalent to
- m->factor = (int) ceil( factor ) */
- if ( m->factor < factor )
- m->factor++;
-
- /* At this point, factor is most likely rounded up, but could still
- have been rounded down in the floating-point calculation. */
-}
-
-void blip_clear( blip_t* m )
-{
- /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if
- factor is rounded up. factor-1 is suitable if factor is rounded down.
- Since we don't know rounding direction, factor/2 accommodates either,
- with the slight loss of showing an error in half the time. Since for
- a 64-bit factor this is years, the halving isn't a problem. */
-
- m->offset = m->factor / 2;
- m->avail = 0;
- m->integrator = 0;
- memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) );
-}
-
-int blip_clocks_needed( const blip_t* m, int samples )
-{
- fixed_t needed;
-
- /* Fails if buffer can't hold that many more samples */
- assert( samples >= 0 && m->avail + samples <= m->size );
-
- needed = (fixed_t) samples * time_unit;
- if ( needed < m->offset )
- return 0;
-
- return (needed - m->offset + m->factor - 1) / m->factor;
-}
-
-void blip_end_frame( blip_t* m, unsigned t )
-{
- fixed_t off = t * m->factor + m->offset;
- m->avail += off >> time_bits;
- m->offset = off & (time_unit - 1);
-
- /* Fails if buffer size was exceeded */
- assert( m->avail <= m->size );
-}
-
-int blip_samples_avail( const blip_t* m )
-{
- return m->avail;
-}
-
-static void remove_samples( blip_t* m, int count )
-{
- buf_t* buf = SAMPLES( m );
- int remain = m->avail + buf_extra - count;
- m->avail -= count;
-
- memmove( &buf [0], &buf [count], remain * sizeof buf [0] );
- memset( &buf [remain], 0, count * sizeof buf [0] );
-}
-
-int blip_read_samples( blip_t* m, int out [], int count )
-{
- assert( count >= 0 );
-
- if ( count > m->avail )
- count = m->avail;
-
- if ( count )
- {
- buf_t const* in = SAMPLES( m );
- buf_t const* end = in + count;
- int sum = m->integrator;
- do
- {
- /* Eliminate fraction */
- int s = ARITH_SHIFT( sum, delta_bits - 8 );
-
- sum += *in++;
-
- *out = s;
- out++;
-
- /* High-pass filter */
- sum -= s >> (8 - (delta_bits - bass_shift)); //<< (delta_bits - bass_shift - 8);
- }
- while ( in != end );
- m->integrator = sum;
-
- remove_samples( m, count );
- }
-
- return count;
-}
-
-int blip_peek_sample( blip_t* m )
-{
- return ARITH_SHIFT( m->integrator, delta_bits - 8 );
-}
-
-/* Things that didn't help performance on x86:
- __attribute__((aligned(128)))
- #define short int
- restrict
-*/
-
-/* Sinc_Generator( 0.9, 0.55, 4.5 ) */
-static short const bl_step [phase_count + 1] [half_width] =
-{
-{ 43, -115, 350, -488, 1136, -914, 5861,21022},
-{ 44, -118, 348, -473, 1076, -799, 5274,21001},
-{ 45, -121, 344, -454, 1011, -677, 4706,20936},
-{ 46, -122, 336, -431, 942, -549, 4156,20829},
-{ 47, -123, 327, -404, 868, -418, 3629,20679},
-{ 47, -122, 316, -375, 792, -285, 3124,20488},
-{ 47, -120, 303, -344, 714, -151, 2644,20256},
-{ 46, -117, 289, -310, 634, -17, 2188,19985},
-{ 46, -114, 273, -275, 553, 117, 1758,19675},
-{ 44, -108, 255, -237, 471, 247, 1356,19327},
-{ 43, -103, 237, -199, 390, 373, 981,18944},
-{ 42, -98, 218, -160, 310, 495, 633,18527},
-{ 40, -91, 198, -121, 231, 611, 314,18078},
-{ 38, -84, 178, -81, 153, 722, 22,17599},
-{ 36, -76, 157, -43, 80, 824, -241,17092},
-{ 34, -68, 135, -3, 8, 919, -476,16558},
-{ 32, -61, 115, 34, -60, 1006, -683,16001},
-{ 29, -52, 94, 70, -123, 1083, -862,15422},
-{ 27, -44, 73, 106, -184, 1152,-1015,14824},
-{ 25, -36, 53, 139, -239, 1211,-1142,14210},
-{ 22, -27, 34, 170, -290, 1261,-1244,13582},
-{ 20, -20, 16, 199, -335, 1301,-1322,12942},
-{ 18, -12, -3, 226, -375, 1331,-1376,12293},
-{ 15, -4, -19, 250, -410, 1351,-1408,11638},
-{ 13, 3, -35, 272, -439, 1361,-1419,10979},
-{ 11, 9, -49, 292, -464, 1362,-1410,10319},
-{ 9, 16, -63, 309, -483, 1354,-1383, 9660},
-{ 7, 22, -75, 322, -496, 1337,-1339, 9005},
-{ 6, 26, -85, 333, -504, 1312,-1280, 8355},
-{ 4, 31, -94, 341, -507, 1278,-1205, 7713},
-{ 3, 35, -102, 347, -506, 1238,-1119, 7082},
-{ 1, 40, -110, 350, -499, 1190,-1021, 6464},
-{ 0, 43, -115, 350, -488, 1136, -914, 5861}
-};
-
-/* Shifting by pre_shift allows calculation using unsigned int rather than
-possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient.
-And by having pre_shift 32, a 32-bit platform can easily do the shift by
-simply ignoring the low half. */
-
-void blip_add_delta( blip_t* m, unsigned time, int delta )
-{
- unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift);
- buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits);
-
- int const phase_shift = frac_bits - phase_bits;
- int phase = fixed >> phase_shift & (phase_count - 1);
- short const* in = bl_step [phase];
- short const* rev = bl_step [phase_count - phase];
-
- int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1);
- int delta2 = (delta * interp) >> delta_bits;
- delta -= delta2;
-
- /* Fails if buffer size was exceeded */
- assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] );
-
- out [0] += in[0]*delta + in[half_width+0]*delta2;
- out [1] += in[1]*delta + in[half_width+1]*delta2;
- out [2] += in[2]*delta + in[half_width+2]*delta2;
- out [3] += in[3]*delta + in[half_width+3]*delta2;
- out [4] += in[4]*delta + in[half_width+4]*delta2;
- out [5] += in[5]*delta + in[half_width+5]*delta2;
- out [6] += in[6]*delta + in[half_width+6]*delta2;
- out [7] += in[7]*delta + in[half_width+7]*delta2;
-
- in = rev;
- out [ 8] += in[7]*delta + in[7-half_width]*delta2;
- out [ 9] += in[6]*delta + in[6-half_width]*delta2;
- out [10] += in[5]*delta + in[5-half_width]*delta2;
- out [11] += in[4]*delta + in[4-half_width]*delta2;
- out [12] += in[3]*delta + in[3-half_width]*delta2;
- out [13] += in[2]*delta + in[2-half_width]*delta2;
- out [14] += in[1]*delta + in[1-half_width]*delta2;
- out [15] += in[0]*delta + in[0-half_width]*delta2;
-}
-
-void blip_add_delta_fast( blip_t* m, unsigned time, int delta )
-{
- unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift);
- buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits);
-
- int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1);
- int delta2 = delta * interp;
-
- /* Fails if buffer size was exceeded */
- assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] );
-
- out [7] += delta * delta_unit - delta2;
- out [8] += delta2;
-}
--- a/dumb/src/helpers/resamp2.inc
+++ b/dumb/src/helpers/resamp2.inc
@@ -94,12 +94,8 @@
#define SET_VOLUME_VARIABLES SET_MONO_DEST_VOLUME_VARIABLES
#define RETURN_VOLUME_VARIABLES RETURN_MONO_DEST_VOLUME_VARIABLES
#define VOLUMES_ARE_ZERO MONO_DEST_VOLUMES_ARE_ZERO
-#define MIX_ALIAS(count) MONO_DEST_MIX_ALIAS(count)
-#define PEEK_ALIAS MONO_DEST_PEEK_ALIAS
#define PEEK_FIR MONO_DEST_PEEK_FIR
#define MIX_FIR MONO_DEST_MIX_FIR
-#define MIX_LINEAR(op, upd, o0, o1) MONO_DEST_MIX_LINEAR(op, upd, o0, o1)
-#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3)
#define MIX_ZEROS(op) *dst++ op 0
#include "resamp3.inc"
@@ -140,23 +136,13 @@
if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \
}
#define VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0)
-#define MIX_ALIAS(count) STEREO_DEST_MIX_ALIAS(count)
-#define PEEK_ALIAS STEREO_DEST_PEEK_ALIAS
#define PEEK_FIR STEREO_DEST_PEEK_FIR
#define MIX_FIR STEREO_DEST_MIX_FIR
-#define MIX_LINEAR(op, upd, o0, o1) STEREO_DEST_MIX_LINEAR(op, upd, o0, o1)
-#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3)
#define MIX_ZEROS(op) { *dst++ op 0; *dst++ op 0; }
#include "resamp3.inc"
-#undef STEREO_DEST_MIX_CUBIC
-#undef MONO_DEST_MIX_CUBIC
-#undef STEREO_DEST_MIX_LINEAR
-#undef MONO_DEST_MIX_LINEAR
-#undef STEREO_DEST_MIX_ALIAS
-#undef MONO_DEST_MIX_ALIAS
#undef MONO_DEST_VOLUMES_ARE_ZERO
#undef SET_MONO_DEST_VOLUME_VARIABLES
#undef RETURN_MONO_DEST_VOLUME_VARIABLES
@@ -163,9 +149,6 @@
#undef MONO_DEST_VOLUME_ZEROS
#undef MONO_DEST_VOLUME_VARIABLES
#undef MONO_DEST_VOLUME_PARAMETERS
-#undef STEREO_DEST_PEEK_ALIAS
-#undef MONO_DEST_PEEK_ALIAS
-#undef POKE_ALIAS
#undef MONO_DEST_PEEK_FIR
#undef STEREO_DEST_PEEK_FIR
#undef MONO_DEST_MIX_FIR
--- a/dumb/src/helpers/resamp3.inc
+++ b/dumb/src/helpers/resamp3.inc
@@ -52,7 +52,6 @@
long todo;
LONG_LONG todo64;
int quality;
- int blip_samples[256*SRC_CHANNELS];
int check;
if (!resampler || resampler->dir == 0) return 0;
@@ -105,41 +104,6 @@
LONG_LONG new_subpos = subpos + (LONG_LONG)dt * todo;
pos += (long)(new_subpos >> 16);
subpos = (long)new_subpos & 65535;
- } else if (quality <= DUMB_RQ_ALIASING) {
- /* Aliasing, backwards */
- int todo_clocks = todo << 16, todo_clocks_set = todo_clocks;
- SRCTYPE xbuf[2*SRC_CHANNELS];
- SRCTYPE *x = &xbuf[0];
- check = resampler->start;
- COPYSRC(xbuf, 0, resampler->X, 1);
- COPYSRC(xbuf, 1, resampler->X, 2);
- if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
- while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) {
- // TODO: check what happens when multiple tempo slides occur per row
- HEAVYASSERT(pos >= resampler->start);
- POKE_ALIAS(0);
- pos--;
- x += SRC_CHANNELS;
- }
- x = &src[pos*SRC_CHANNELS];
- while ( todo_clocks ) {
- todo_clocks_set = todo_clocks;
- if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
- todo_clocks -= todo_clocks_set;
- while ( resampler->last_clock < todo_clocks_set && pos >= check ) {
- POKE_ALIAS(2);
- pos--;
- x -= SRC_CHANNELS;
- }
- todo = todo_clocks_set >> 16;
- check = 0;
- if ( resampler->last_clock < todo_clocks_set ) {
- check = ( todo_clocks_set - resampler->last_clock + 65535 ) >> 16;
- }
- todo -= check;
- MIX_ALIAS( todo );
- done -= check;
- }
} else {
/* FIR resampling, backwards */
SRCTYPE *x;
@@ -185,40 +149,6 @@
LONG_LONG new_subpos = subpos + (LONG_LONG)dt * todo;
pos += (long)(new_subpos >> 16);
subpos = (long)new_subpos & 65535;
- } else if (quality <= DUMB_RQ_ALIASING) {
- /* Aliasing, forwards */
- int todo_clocks = todo << 16, todo_clocks_set = todo_clocks;
- SRCTYPE xbuf[2*SRC_CHANNELS];
- SRCTYPE *x = &xbuf[0];
- check = resampler->end;
- COPYSRC(xbuf, 0, resampler->X, 1);
- COPYSRC(xbuf, 1, resampler->X, 2);
- if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
- while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) {
- HEAVYASSERT(pos < resampler->end);
- POKE_ALIAS(0);
- pos++;
- x += SRC_CHANNELS;
- }
- x = &src[pos*SRC_CHANNELS];
- while ( todo_clocks ) {
- todo_clocks_set = todo_clocks;
- if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
- todo_clocks -= todo_clocks_set;
- while ( resampler->last_clock < todo_clocks_set && pos < check ) {
- POKE_ALIAS(-2);
- pos++;
- x += SRC_CHANNELS;
- }
- todo = todo_clocks_set >> 16;
- check = 0;
- if ( resampler->last_clock < todo_clocks_set ) {
- check = ( todo_clocks_set - resampler->last_clock + 65535 ) >> 16;
- }
- todo -= check;
- MIX_ALIAS( todo );
- done -= check;
- }
} else {
/* FIR resampling, forwards */
SRCTYPE *x;
@@ -299,22 +229,12 @@
if (resampler->dir < 0) {
HEAVYASSERT(pos >= resampler->start);
- if (quality <= DUMB_RQ_ALIASING) {
- /* Aliasing, backwards */
- PEEK_ALIAS;
- } else {
/* FIR resampling, backwards */
PEEK_FIR;
- }
} else {
HEAVYASSERT(pos < resampler->end);
- if (quality <= DUMB_RQ_ALIASING) {
- /* Aliasing */
- PEEK_ALIAS;
- } else {
/* FIR resampling, forwards */
PEEK_FIR;
- }
}
}
@@ -321,11 +241,7 @@
#undef MIX_ZEROS
-#undef MIX_CUBIC
-#undef MIX_LINEAR
-#undef MIX_ALIAS
#undef MIX_FIR
-#undef PEEK_ALIAS
#undef PEEK_FIR
#undef VOLUMES_ARE_ZERO
#undef SET_VOLUME_VARIABLES
--- a/dumb/src/helpers/resample.c
+++ b/dumb/src/helpers/resample.c
@@ -45,7 +45,6 @@
#include <math.h>
#include "dumb.h"
-#include "internal/blip_buf.h"
#include "internal/resampler.h"
@@ -73,11 +72,12 @@
* specification doesn't override it. The following values are valid:
*
* 0 - DUMB_RQ_ALIASING - fastest
- * 1 - DUMB_RQ_LINEAR
- * 2 - DUMB_RQ_CUBIC
- * 3 - DUMB_RQ_FIR - nicest
+ * 1 - DUMB_RQ_BLEP - nicer than aliasing, but slower
+ * 2 - DUMB_RQ_LINEAR
+ * 3 - DUMB_RQ_CUBIC
+ * 4 - DUMB_RQ_FIR - nicest
*
- * Values outside the range 0-3 will behave the same as the nearest
+ * Values outside the range 0-4 will behave the same as the nearest
* value within the range.
*/
int dumb_resampling_quality = DUMB_RQ_CUBIC;
@@ -157,23 +157,7 @@
#define SRCTYPE sample_t
#define SRCBITS 24
-#define ALIAS(x) (x >> 8)
#define FIR(x) (x >> 8)
-#define LINEAR(x0, x1) (x0 + MULSC(x1 - x0, subpos))
-/*
-#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
- a = (3 * (x1 - x2) + (x3 - x0)) >> 1; \
- b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) >> 1; \
- c = (x2 - x0) >> 1; \
-}
-#define CUBIC(d) MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + d, vol)
-*/
-#define CUBIC(x0, x1, x2, x3) ( \
- MULSC(x0, cubicA0[subpos >> 6] << 2) + \
- MULSC(x1, cubicA1[subpos >> 6] << 2) + \
- MULSC(x2, cubicA1[1 + (subpos >> 6 ^ 1023)] << 2) + \
- MULSC(x3, cubicA0[1 + (subpos >> 6 ^ 1023)] << 2))
-#define CUBICVOL(x, vol) MULSC(x, vol)
#include "resample.inc"
/* Undefine the simplified macros. */
@@ -194,23 +178,7 @@
#define SUFFIX _16
#define SRCTYPE short
#define SRCBITS 16
-#define ALIAS(x) (x)
#define FIR(x) (x)
-#define LINEAR(x0, x1) ((x0 << 8) + MULSC16(x1 - x0, subpos))
-/*
-#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
- a = (3 * (x1 - x2) + (x3 - x0)) << 7; \
- b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) << 7; \
- c = (x2 - x0) << 7; \
-}
-#define CUBIC(d) MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + (d << 8), vol)
-*/
-#define CUBIC(x0, x1, x2, x3) ( \
- x0 * cubicA0[subpos >> 6] + \
- x1 * cubicA1[subpos >> 6] + \
- x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \
- x3 * cubicA0[1 + (subpos >> 6 ^ 1023)])
-#define CUBICVOL(x, vol) (int)((LONG_LONG)(x) * (vol << 10) >> 32)
#include "resample.inc"
/* Create resamplers for 8-bit source samples. */
@@ -217,23 +185,7 @@
#define SUFFIX _8
#define SRCTYPE signed char
#define SRCBITS 8
-#define ALIAS(x) (x << 8)
#define FIR(x) (x << 8)
-#define LINEAR(x0, x1) ((x0 << 16) + (x1 - x0) * subpos)
-/*
-#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
- a = 3 * (x1 - x2) + (x3 - x0); \
- b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) << 15; \
- c = (x2 - x0) << 15; \
-}
-#define CUBIC(d) MULSC(MULSC(MULSC((a * subpos >> 1) + b, subpos) + c, subpos) + (d << 16), vol)
-*/
-#define CUBIC(x0, x1, x2, x3) (( \
- x0 * cubicA0[subpos >> 6] + \
- x1 * cubicA1[subpos >> 6] + \
- x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \
- x3 * cubicA0[1 + (subpos >> 6 ^ 1023)]) << 6)
-#define CUBICVOL(x, vol) (int)((LONG_LONG)(x) * (vol << 12) >> 32)
#include "resample.inc"
--- a/dumb/src/helpers/resample.inc
+++ b/dumb/src/helpers/resample.inc
@@ -69,11 +69,6 @@
}
for (i = 0; i < src_channels*3; i++) resampler->X[i] = 0;
resampler->overshot = -1;
- resampler->last_clock = 0;
- resampler->last_amp[0] = 0;
- resampler->last_amp[1] = 0;
- blip_clear(resampler->blip_buffer[0]);
- blip_clear(resampler->blip_buffer[1]);
resampler->fir_resampler_ratio = 0;
resampler_clear(resampler->fir_resampler[0]);
resampler_clear(resampler->fir_resampler[1]);
@@ -87,21 +82,6 @@
{
DUMB_RESAMPLER *resampler = malloc(sizeof(*resampler));
if (!resampler) return NULL;
- resampler->blip_buffer[0] = blip_new( 256 );
- if (!resampler->blip_buffer[0])
- {
- free(resampler);
- return NULL;
- }
- resampler->blip_buffer[1] = blip_new( 256 );
- if (!resampler->blip_buffer[1])
- {
- free(resampler->blip_buffer[0]);
- free(resampler);
- return NULL;
- }
- blip_set_rates(resampler->blip_buffer[0], 65536, 1);
- blip_set_rates(resampler->blip_buffer[1], 65536, 1);
dumb_reset_resampler(resampler, src, src_channels, pos, start, end, quality);
return resampler;
}
@@ -153,16 +133,9 @@
}
#define RETURN_MONO_DEST_VOLUME_VARIABLES if ( volume ) volume->volume = (float)volr / 16777216.0f
#define MONO_DEST_VOLUMES_ARE_ZERO (vol == 0 && volt == 0)
-#define POKE_ALIAS(offset) { \
- int delta = ALIAS(x[offset]) - resampler->last_amp[0]; \
- resampler->last_amp[0] += delta; \
- if ( delta ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, delta ); \
- resampler->last_clock += inv_dt; \
-}
#define POKE_FIR(offset) { \
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( resampler_get_sample( resampler->fir_resampler[0] ), vol )
#define MONO_DEST_MIX_FIR { \
*dst++ += MULSC( resampler_get_sample( resampler->fir_resampler[0] ), vol ); \
@@ -169,22 +142,6 @@
UPDATE_VOLUME( volume, vol ); \
}
#define ADVANCE_FIR resampler_remove_sample( resampler->fir_resampler[0] )
-#define MONO_DEST_MIX_ALIAS(count) { \
- int n = 0; \
- resampler->last_clock -= count * 65536; \
- blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
- blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
- LOOP4( count, \
- *dst++ += MULSC( blip_samples[n], vol ); \
- n++; \
- UPDATE_VOLUME( volume, vol ); \
- ); \
-}
-#define STEREO_DEST_PEEK_ALIAS { \
- int sample = blip_peek_sample( resampler->blip_buffer[0] ); \
- *dst++ = MULSC( sample, lvol ); \
- *dst++ = MULSC( sample, rvol ); \
-}
#define STEREO_DEST_PEEK_FIR { \
int sample = resampler_get_sample( resampler->fir_resampler[0] ); \
*dst++ = MULSC( sample, lvol ); \
@@ -197,41 +154,6 @@
UPDATE_VOLUME( volume_left, lvol ); \
UPDATE_VOLUME( volume_right, rvol ); \
}
-#define STEREO_DEST_MIX_ALIAS(count) { \
- int sample, n = 0; \
- resampler->last_clock -= count * 65536; \
- blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
- blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
- LOOP4( count, \
- sample = blip_samples[n++]; \
- *dst++ += MULSC( sample, lvol ); \
- *dst++ += MULSC( sample, rvol ); \
- UPDATE_VOLUME( volume_left, lvol ); \
- UPDATE_VOLUME( volume_right, rvol ); \
- ); \
-}
-#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
- *dst++ op MULSC(LINEAR(x[o0], x[o1]), vol); \
- if ( upd ) UPDATE_VOLUME( volume, vol ); \
-}
-#define STEREO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
- int xm = LINEAR(x[o0], x[o1]); \
- *dst++ op MULSC(xm, lvol); \
- *dst++ op MULSC(xm, rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
-}
-#define MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \
- *dst++ op CUBICVOL(CUBIC(x0[o0], x[o1], x[o2], x3[o3]), vol); \
- if ( upd ) UPDATE_VOLUME( volume, vol ); \
-}
-#define STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \
- int xm = CUBIC(x0[o0], x[o1], x[o2], x3[o3]); \
- *dst++ op CUBICVOL(xm, lvol); \
- *dst++ op CUBICVOL(xm, rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
-}
#include "resamp2.inc"
/* Create stereo source resampler. */
@@ -288,23 +210,10 @@
if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \
}
#define MONO_DEST_VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0)
-#define POKE_ALIAS(offset) { \
- int deltal = ALIAS(x[(offset)*2+0]) - resampler->last_amp[0]; \
- int deltar = ALIAS(x[(offset)*2+1]) - resampler->last_amp[1]; \
- resampler->last_amp[0] += deltal; \
- resampler->last_amp[1] += deltar; \
- if ( deltal ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, deltal ); \
- if ( deltar ) blip_add_delta( resampler->blip_buffer[1], resampler->last_clock, deltar ); \
- resampler->last_clock += inv_dt; \
-}
#define POKE_FIR(offset) { \
resampler_write_sample( resampler->fir_resampler[0], FIR(x[(offset)*2+0]) ); \
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 ) + \
- MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
-}
#define MONO_DEST_PEEK_FIR { \
*dst = MULSC( resampler_get_sample( resampler->fir_resampler[0] ), lvol ) + \
MULSC( resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
@@ -319,24 +228,6 @@
resampler_remove_sample( resampler->fir_resampler[0] ); \
resampler_remove_sample( resampler->fir_resampler[1] ); \
}
-#define MONO_DEST_MIX_ALIAS(count) { \
- int n = 0; \
- resampler->last_clock -= count * 65536; \
- blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
- blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \
- blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
- blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \
- LOOP4( count, \
- *dst++ += MULSC( blip_samples[n], lvol ) + MULSC( blip_samples[256+n], rvol ); \
- n++; \
- UPDATE_VOLUME( volume_left, lvol ); \
- UPDATE_VOLUME( volume_right, rvol ); \
- ); \
-}
-#define STEREO_DEST_PEEK_ALIAS { \
- *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ); \
- *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
-}
#define STEREO_DEST_PEEK_FIR { \
*dst++ = MULSC( resampler_get_sample( resampler->fir_resampler[0] ), lvol ); \
*dst++ = MULSC( resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \
@@ -347,45 +238,6 @@
UPDATE_VOLUME( volume_left, lvol ); \
UPDATE_VOLUME( volume_right, rvol ); \
}
-#define STEREO_DEST_MIX_ALIAS(count) { \
- int n = 0; \
- resampler->last_clock -= count * 65536; \
- blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
- blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \
- blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
- blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \
- LOOP4( count, \
- *dst++ += MULSC( blip_samples[n], lvol); \
- *dst++ += MULSC( blip_samples[256+n], rvol); \
- n++; \
- UPDATE_VOLUME( volume_left, lvol ); \
- UPDATE_VOLUME( volume_right, rvol ); \
- ); \
-}
-#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
- *dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol) + MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
-}
-#define STEREO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
- *dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol); \
- *dst++ op MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
-}
-#define MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \
- *dst++ op \
- CUBICVOL(CUBIC(x0[(o0)*2], x[(o1)*2], x[(o2)*2], x3[(o3)*2]), lvol) + \
- CUBICVOL(CUBIC(x0[(o0)*2+1], x[(o1)*2+1], x[(o2)*2+1], x3[(o3)*2+1]), rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
-}
-#define STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \
- *dst++ op CUBICVOL(CUBIC(x0[(o0)*2], x[(o1)*2], x[(o2)*2], x3[(o3)*2]), lvol); \
- *dst++ op CUBICVOL(CUBIC(x0[(o0)*2+1], x[(o1)*2+1], x[(o2)*2+1], x3[(o3)*2+1]), rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
-}
#include "resamp2.inc"
@@ -398,10 +250,6 @@
-#undef CUBICVOL
-#undef CUBIC
-#undef LINEAR
-#undef ALIAS
#undef FIR
#undef SRCBITS
#undef SRCTYPE
--- a/dumb/src/helpers/resampler.c
+++ b/dumb/src/helpers/resampler.c
@@ -60,10 +60,10 @@
#endif
static int query_cpu_feature_sse() {
- int buffer[4];
- __cpuid(buffer,1);
- if ((buffer[3]&(1<<25)) == 0) return 0;
- return 1;
+ int buffer[4];
+ __cpuid(buffer,1);
+ if ((buffer[3]&(1<<25)) == 0) return 0;
+ return 1;
}
static int resampler_has_sse = 0;
@@ -109,9 +109,13 @@
{
int write_pos, write_filled;
int read_pos, read_filled;
- unsigned short phase;
+ unsigned int phase;
unsigned int phase_inc;
+ unsigned int inv_phase;
+ unsigned int inv_phase_inc;
unsigned char quality;
+ float last_amp;
+ float accumulator;
float buffer_in[resampler_buffer_size * 2];
float buffer_out[resampler_buffer_size + SINC_WIDTH * 2 - 1];
} resampler;
@@ -127,7 +131,11 @@
r->read_filled = 0;
r->phase = 0;
r->phase_inc = 0;
+ r->inv_phase = 0;
+ r->inv_phase_inc = 0;
r->quality = RESAMPLER_QUALITY_MAX;
+ r->last_amp = 0;
+ r->accumulator = 0;
memset( r->buffer_in, 0, sizeof(r->buffer_in) );
memset( r->buffer_out, 0, sizeof(r->buffer_out) );
@@ -151,7 +159,11 @@
r_out->read_filled = r_in->read_filled;
r_out->phase = r_in->phase;
r_out->phase_inc = r_in->phase_inc;
+ r_out->inv_phase = r_in->inv_phase;
+ r_out->inv_phase_inc = r_in->inv_phase_inc;
r_out->quality = r_in->quality;
+ r_out->last_amp = r_in->last_amp;
+ r_out->accumulator = r_in->accumulator;
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) );
@@ -169,7 +181,11 @@
r_out->read_filled = r_in->read_filled;
r_out->phase = r_in->phase;
r_out->phase_inc = r_in->phase_inc;
+ r_out->inv_phase = r_in->inv_phase;
+ r_out->inv_phase_inc = r_in->inv_phase_inc;
r_out->quality = r_in->quality;
+ r_out->last_amp = r_in->last_amp;
+ r_out->accumulator = r_in->accumulator;
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) );
}
@@ -181,6 +197,17 @@
quality = RESAMPLER_QUALITY_MIN;
else if (quality > RESAMPLER_QUALITY_MAX)
quality = RESAMPLER_QUALITY_MAX;
+ if ( r->quality != quality )
+ {
+ if ( quality == RESAMPLER_QUALITY_BLEP || r->quality == RESAMPLER_QUALITY_BLEP )
+ {
+ r->read_pos = 0;
+ r->read_filled = 0;
+ r->last_amp = 0;
+ r->accumulator = 0;
+ memset( r->buffer_out, 0, sizeof(r->buffer_out) );
+ }
+ }
r->quality = (unsigned char)quality;
}
@@ -196,6 +223,7 @@
{
default:
case RESAMPLER_QUALITY_ZOH:
+ case RESAMPLER_QUALITY_BLEP:
return 1;
case RESAMPLER_QUALITY_LINEAR:
@@ -223,8 +251,10 @@
r->read_pos = 0;
r->read_filled = 0;
r->phase = 0;
- memset(r->buffer_in, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0]));
- memset(r->buffer_in + resampler_buffer_size, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0]));
+ memset(r->buffer_in, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0]));
+ memset(r->buffer_in + resampler_buffer_size, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0]));
+ if (r->quality == RESAMPLER_QUALITY_BLEP)
+ memset(r->buffer_out, 0, sizeof(r->buffer_out));
}
void resampler_set_rate(void *_r, double new_factor)
@@ -231,6 +261,8 @@
{
resampler * r = ( resampler * ) _r;
r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION );
+ new_factor = 1.0 / new_factor;
+ r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION );
}
void resampler_write_sample(void *_r, short s)
@@ -294,6 +326,134 @@
return used;
}
+static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
+{
+ int in_size = r->write_filled;
+ float const* in_ = r->buffer_in + resampler_buffer_size + r->write_pos - r->write_filled;
+ int used = 0;
+ in_size -= 1;
+ if ( in_size > 0 )
+ {
+ float* out = *out_;
+ float const* in = in_;
+ float const* const in_end = in + in_size;
+ float last_amp = r->last_amp;
+ int inv_phase = r->inv_phase;
+ int inv_phase_inc = r->inv_phase_inc;
+
+ const int step = RESAMPLER_RESOLUTION;
+
+ do
+ {
+ float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
+ int i = SINC_WIDTH;
+ float sample;
+
+ if ( out + SINC_WIDTH * 2 > out_end )
+ break;
+
+ for (; i >= -SINC_WIDTH + 1; --i)
+ {
+ int pos = i * step;
+ kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(inv_phase - pos)];
+ }
+ sample = *in++ - last_amp;
+ last_amp += sample;
+ sample /= kernel_sum;
+ for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
+ out[i] += sample * kernel[i];
+
+ inv_phase += inv_phase_inc;
+
+ out += inv_phase >> RESAMPLER_SHIFT;
+
+ inv_phase &= RESAMPLER_RESOLUTION-1;
+ }
+ while ( in < in_end );
+
+ r->inv_phase = inv_phase;
+ r->last_amp = last_amp;
+ *out_ = out;
+
+ used = (int)(in - in_);
+
+ r->write_filled -= used;
+ }
+
+ return used;
+}
+
+#ifdef RESAMPLER_SSE
+static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
+{
+ int in_size = r->write_filled;
+ float const* in_ = r->buffer_in + resampler_buffer_size + r->write_pos - r->write_filled;
+ int used = 0;
+ in_size -= 1;
+ if ( in_size > 0 )
+ {
+ float* out = *out_;
+ float const* in = in_;
+ float const* const in_end = in + in_size;
+ float last_amp = r->last_amp;
+ int inv_phase = r->inv_phase;
+ int inv_phase_inc = r->inv_phase_inc;
+
+ const int step = RESAMPLER_RESOLUTION;
+
+ do
+ {
+ // accumulate in extended precision
+ float kernel_sum = 0.0;
+ __m128 kernel[SINC_WIDTH / 2];
+ __m128 temp1, temp2;
+ __m128 samplex;
+ float sample;
+ float *kernelf = (float*)(&kernel);
+ int i = SINC_WIDTH;
+
+ if ( out + SINC_WIDTH * 2 > out_end )
+ break;
+
+ for (; i >= -SINC_WIDTH + 1; --i)
+ {
+ int pos = i * step;
+ kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(inv_phase - pos)];
+ }
+ sample = *in++ - last_amp;
+ last_amp += sample;
+ sample /= kernel_sum;
+ samplex = _mm_set1_ps( sample );
+ for (i = 0; i < SINC_WIDTH / 2; ++i)
+ {
+ temp1 = _mm_load_ps( (const float *)( kernel + i ) );
+ temp1 = _mm_mul_ps( temp1, samplex );
+ temp2 = _mm_loadu_ps( (const float *) out + i * 4 );
+ temp1 = _mm_add_ps( temp1, temp2 );
+ _mm_storeu_ps( (float *) out + i * 4, temp1 );
+ }
+
+ inv_phase += inv_phase_inc;
+
+ out += inv_phase >> RESAMPLER_SHIFT;
+
+ inv_phase &= RESAMPLER_RESOLUTION - 1;
+ }
+ while ( in < in_end );
+
+ r->inv_phase = inv_phase;
+ r->last_amp = last_amp;
+ *out_ = out;
+
+ used = (int)(in - in_);
+
+ r->write_filled -= used;
+ }
+
+ return used;
+}
+#endif
+
static int resampler_run_linear(resampler * r, float ** out_, float * out_end)
{
int in_size = r->write_filled;
@@ -326,7 +486,7 @@
}
while ( in < in_end );
- r->phase = (unsigned short) phase;
+ r->phase = phase;
*out_ = out;
used = (int)(in - in_);
@@ -374,7 +534,7 @@
}
while ( in < in_end );
- r->phase = (unsigned short) phase;
+ r->phase = phase;
*out_ = out;
used = (int)(in - in_);
@@ -428,7 +588,7 @@
}
while ( in < in_end );
- r->phase = (unsigned short) phase;
+ r->phase = phase;
*out_ = out;
used = (int)(in - in_);
@@ -483,7 +643,7 @@
}
while ( in < in_end );
- r->phase = (unsigned short) phase;
+ r->phase = phase;
*out_ = out;
used = (int)(in - in_);
@@ -556,7 +716,7 @@
}
while ( in < in_end );
- r->phase = (unsigned short) phase;
+ r->phase = phase;
*out_ = out;
used = (int)(in - in_);
@@ -586,6 +746,25 @@
resampler_run_zoh( r, &out, out + write_size );
break;
+ case RESAMPLER_QUALITY_BLEP:
+ {
+ int used;
+ int write_extra = 0;
+ if ( write_pos >= r->read_pos )
+ write_extra = r->read_pos;
+ if ( write_extra > SINC_WIDTH * 2 - 1 )
+ write_extra = SINC_WIDTH * 2 - 1;
+ memcpy( r->buffer_out + resampler_buffer_size, r->buffer_out, write_extra * sizeof(r->buffer_out[0]) );
+ if ( resampler_has_sse )
+ used = resampler_run_blep_sse( r, &out, out + write_size + write_extra );
+ else
+ used = resampler_run_blep( r, &out, out + write_size + write_extra );
+ memcpy( r->buffer_out, r->buffer_out + resampler_buffer_size, write_extra * sizeof(r->buffer_out[0]) );
+ if (!used)
+ return;
+ break;
+ }
+
case RESAMPLER_QUALITY_LINEAR:
resampler_run_linear( r, &out, out + write_size );
break;
@@ -623,11 +802,14 @@
int resampler_get_sample(void *_r)
{
resampler * r = ( resampler * ) _r;
- if ( r->read_filled < 1 )
+ if ( r->read_filled < 1 && r->phase_inc)
resampler_fill( r );
if ( r->read_filled < 1 )
return 0;
- return (int)(r->buffer_out[ r->read_pos ] * 8388608.0);
+ if ( r->quality == RESAMPLER_QUALITY_BLEP )
+ return (r->buffer_out[ r->read_pos ] + r->accumulator) * 8388608.0;
+ else
+ return r->buffer_out[ r->read_pos ] * 8388608.0;
}
void resampler_remove_sample(void *_r)
@@ -635,6 +817,12 @@
resampler * r = ( resampler * ) _r;
if ( r->read_filled > 0 )
{
+ if ( r->quality == RESAMPLER_QUALITY_BLEP )
+ {
+ r->accumulator += r->buffer_out[ r->read_pos ];
+ r->buffer_out[ r->read_pos ] = 0;
+ r->accumulator -= r->accumulator * (1.0 / 8192.0);
+ }
--r->read_filled;
r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size;
}
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -26,7 +26,6 @@
#include "internal/it.h"
#include "internal/lpc.h"
-#include "internal/blip_buf.h"
#include "internal/resampler.h"
// #define BIT_ARRAY_BULLSHIT
@@ -36,26 +35,9 @@
IT_PLAYING * r = (IT_PLAYING*) malloc(sizeof(*r));
if (r)
{
- r->resampler.blip_buffer[0] = blip_new( 256 );
- if ( !r->resampler.blip_buffer[0] )
- {
- free( r );
- return NULL;
- }
- r->resampler.blip_buffer[1] = blip_new( 256 );
- if ( !r->resampler.blip_buffer[1] )
- {
- free( r->resampler.blip_buffer[0] );
- free( r );
- return NULL;
- }
- 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] = resampler_create();
if ( !r->resampler.fir_resampler[0] ) {
- free( r->resampler.blip_buffer[1] );
- free( r->resampler.blip_buffer[0] );
free( r );
return NULL;
}
@@ -62,8 +44,6 @@
r->resampler.fir_resampler[1] = resampler_create();
if ( !r->resampler.fir_resampler[1] ) {
resampler_delete( r->resampler.fir_resampler[0] );
- free( r->resampler.blip_buffer[1] );
- free( r->resampler.blip_buffer[0] );
free( r );
return NULL;
}
@@ -75,8 +55,6 @@
{
resampler_delete( r->resampler.fir_resampler[1] );
resampler_delete( r->resampler.fir_resampler[0] );
- blip_delete( r->resampler.blip_buffer[1] );
- blip_delete( r->resampler.blip_buffer[0] );
free( r );
}
@@ -166,24 +144,9 @@
dst->resampler = src->resampler;
dst->resampler.pickup_data = dst;
- dst->resampler.blip_buffer[0] = blip_dup( src->resampler.blip_buffer[0] );
- if ( !dst->resampler.blip_buffer[0] )
- {
- free( dst );
- return NULL;
- }
- dst->resampler.blip_buffer[1] = blip_dup( src->resampler.blip_buffer[1] );
- if ( !dst->resampler.blip_buffer[1] )
- {
- blip_delete( dst->resampler.blip_buffer[0] );
- free( dst );
- return NULL;
- }
dst->resampler.fir_resampler_ratio = src->resampler.fir_resampler_ratio;
dst->resampler.fir_resampler[0] = 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] );
free( dst );
return NULL;
}
@@ -190,8 +153,6 @@
dst->resampler.fir_resampler[1] = resampler_dup( src->resampler.fir_resampler[1] );
if ( !dst->resampler.fir_resampler[1] ) {
resampler_delete( dst->resampler.fir_resampler[0] );
- blip_delete( dst->resampler.blip_buffer[1] );
- blip_delete( dst->resampler.blip_buffer[0] );
free( dst );
return NULL;
}
--- a/dumb/vc6/dumb/dumb.vcxproj
+++ b/dumb/vc6/dumb/dumb.vcxproj
@@ -109,7 +109,6 @@
<ClCompile Include="..\..\src\core\rendsig.c" />
<ClCompile Include="..\..\src\core\unload.c" />
<ClCompile Include="..\..\src\helpers\barray.c" />
- <ClCompile Include="..\..\src\helpers\blip_buf.c" />
<ClCompile Include="..\..\src\helpers\clickrem.c" />
<ClCompile Include="..\..\src\helpers\resampler.c" />
<ClCompile Include="..\..\src\helpers\lpc.c" />
@@ -203,7 +202,6 @@
<ItemGroup>
<ClInclude Include="..\..\include\dumb.h" />
<ClInclude Include="..\..\include\internal\barray.h" />
- <ClInclude Include="..\..\include\internal\blip_buf.h" />
<ClInclude Include="..\..\include\internal\dumb.h" />
<ClInclude Include="..\..\include\internal\dumbfile.h" />
<ClInclude Include="..\..\include\internal\fir_resampler.h" />
--- a/dumb/vc6/dumb/dumb.vcxproj.filters
+++ b/dumb/vc6/dumb/dumb.vcxproj.filters
@@ -252,9 +252,6 @@
<ClCompile Include="..\..\src\it\xmeffect.c">
<Filter>src\it</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\helpers\blip_buf.c">
- <Filter>src\helpers</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\it\readokt.c">
<Filter>src\it\readers</Filter>
</ClCompile>
@@ -312,9 +309,6 @@
<Filter>include\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\include\internal\stack_alloc.h">
- <Filter>include\internal</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\internal\blip_buf.h">
<Filter>include\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\include\internal\resampler.h">