Fixed a cause for rounding errors in DUMB/modplay resamplers, which would have caused some extreme cases of samples to play too slowly
parent
641302d597
commit
579451737c
|
@ -13,11 +13,13 @@
|
||||||
#define resampler_set_quality EVALUATE(RESAMPLER_DECORATE,_resampler_set_quality)
|
#define resampler_set_quality EVALUATE(RESAMPLER_DECORATE,_resampler_set_quality)
|
||||||
#define resampler_get_free_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_free_count)
|
#define resampler_get_free_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_free_count)
|
||||||
#define resampler_write_sample EVALUATE(RESAMPLER_DECORATE,_resampler_write_sample)
|
#define resampler_write_sample EVALUATE(RESAMPLER_DECORATE,_resampler_write_sample)
|
||||||
|
#define resampler_write_sample_fixed EVALUATE(RESAMPLER_DECORATE,_resampler_write_sample_fixed)
|
||||||
#define resampler_set_rate EVALUATE(RESAMPLER_DECORATE,_resampler_set_rate)
|
#define resampler_set_rate EVALUATE(RESAMPLER_DECORATE,_resampler_set_rate)
|
||||||
#define resampler_ready EVALUATE(RESAMPLER_DECORATE,_resampler_ready)
|
#define resampler_ready EVALUATE(RESAMPLER_DECORATE,_resampler_ready)
|
||||||
#define resampler_clear EVALUATE(RESAMPLER_DECORATE,_resampler_clear)
|
#define resampler_clear EVALUATE(RESAMPLER_DECORATE,_resampler_clear)
|
||||||
#define resampler_get_sample_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample_count)
|
#define resampler_get_sample_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample_count)
|
||||||
#define resampler_get_sample EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample)
|
#define resampler_get_sample EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample)
|
||||||
|
#define resampler_get_sample_float EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample_float)
|
||||||
#define resampler_remove_sample EVALUATE(RESAMPLER_DECORATE,_resampler_remove_sample)
|
#define resampler_remove_sample EVALUATE(RESAMPLER_DECORATE,_resampler_remove_sample)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -43,11 +45,13 @@ void resampler_set_quality(void *, int quality);
|
||||||
|
|
||||||
int resampler_get_free_count(void *);
|
int resampler_get_free_count(void *);
|
||||||
void resampler_write_sample(void *, short sample);
|
void resampler_write_sample(void *, short sample);
|
||||||
|
void resampler_write_sample_fixed(void *, int sample, unsigned char depth);
|
||||||
void resampler_set_rate( void *, double new_factor );
|
void resampler_set_rate( void *, double new_factor );
|
||||||
int resampler_ready(void *);
|
int resampler_ready(void *);
|
||||||
void resampler_clear(void *);
|
void resampler_clear(void *);
|
||||||
int resampler_get_sample_count(void *);
|
int resampler_get_sample_count(void *);
|
||||||
int resampler_get_sample(void *);
|
int resampler_get_sample(void *);
|
||||||
|
float resampler_get_sample_float(void *);
|
||||||
void resampler_remove_sample(void *);
|
void resampler_remove_sample(void *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#include "internal/resampler.h"
|
#include "internal/resampler.h"
|
||||||
|
|
||||||
enum { RESAMPLER_SHIFT = 10 };
|
enum { RESAMPLER_SHIFT = 10 };
|
||||||
|
enum { RESAMPLER_SHIFT_EXTRA = 8 };
|
||||||
enum { RESAMPLER_RESOLUTION = 1 << RESAMPLER_SHIFT };
|
enum { RESAMPLER_RESOLUTION = 1 << RESAMPLER_SHIFT };
|
||||||
|
enum { RESAMPLER_RESOLUTION_EXTRA = 1 << (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA) };
|
||||||
enum { SINC_WIDTH = 16 };
|
enum { SINC_WIDTH = 16 };
|
||||||
enum { SINC_SAMPLES = RESAMPLER_RESOLUTION * SINC_WIDTH };
|
enum { SINC_SAMPLES = RESAMPLER_RESOLUTION * SINC_WIDTH };
|
||||||
enum { CUBIC_SAMPLES = RESAMPLER_RESOLUTION * 4 };
|
enum { CUBIC_SAMPLES = RESAMPLER_RESOLUTION * 4 };
|
||||||
|
@ -324,9 +326,9 @@ void resampler_clear(void *_r)
|
||||||
void resampler_set_rate(void *_r, double new_factor)
|
void resampler_set_rate(void *_r, double new_factor)
|
||||||
{
|
{
|
||||||
resampler * r = ( resampler * ) _r;
|
resampler * r = ( resampler * ) _r;
|
||||||
r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION );
|
r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION_EXTRA );
|
||||||
new_factor = 1.0 / new_factor;
|
new_factor = 1.0 / new_factor;
|
||||||
r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION );
|
r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION_EXTRA );
|
||||||
}
|
}
|
||||||
|
|
||||||
void resampler_write_sample(void *_r, short s)
|
void resampler_write_sample(void *_r, short s)
|
||||||
|
@ -403,13 +405,13 @@ static int resampler_run_zoh(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
r->phase = (unsigned short) phase;
|
r->phase = phase;
|
||||||
*out_ = out;
|
*out_ = out;
|
||||||
|
|
||||||
used = (int)(in - in_);
|
used = (int)(in - in_);
|
||||||
|
@ -440,6 +442,7 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
||||||
|
int phase_reduced = inv_phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
float sample;
|
float sample;
|
||||||
|
|
||||||
|
@ -449,7 +452,7 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
|
||||||
for (; i >= -SINC_WIDTH + 1; --i)
|
for (; i >= -SINC_WIDTH + 1; --i)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int abs_pos = abs(inv_phase - pos);
|
int abs_pos = abs(phase_reduced - pos);
|
||||||
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
||||||
}
|
}
|
||||||
sample = *in++ - last_amp;
|
sample = *in++ - last_amp;
|
||||||
|
@ -460,9 +463,9 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
inv_phase += inv_phase_inc;
|
inv_phase += inv_phase_inc;
|
||||||
|
|
||||||
out += inv_phase >> RESAMPLER_SHIFT;
|
out += inv_phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
inv_phase &= RESAMPLER_RESOLUTION-1;
|
inv_phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -505,6 +508,7 @@ static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
|
||||||
__m128 samplex;
|
__m128 samplex;
|
||||||
float sample;
|
float sample;
|
||||||
float *kernelf = (float*)(&kernel);
|
float *kernelf = (float*)(&kernel);
|
||||||
|
int phase_reduced = inv_phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
|
|
||||||
if ( out + SINC_WIDTH * 2 > out_end )
|
if ( out + SINC_WIDTH * 2 > out_end )
|
||||||
|
@ -513,7 +517,7 @@ static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
|
||||||
for (; i >= -SINC_WIDTH + 1; --i)
|
for (; i >= -SINC_WIDTH + 1; --i)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int abs_pos = abs(inv_phase - pos);
|
int abs_pos = abs(phase_reduced - pos);
|
||||||
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
||||||
}
|
}
|
||||||
sample = *in++ - last_amp;
|
sample = *in++ - last_amp;
|
||||||
|
@ -531,9 +535,9 @@ static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
inv_phase += inv_phase_inc;
|
inv_phase += inv_phase_inc;
|
||||||
|
|
||||||
out += inv_phase >> RESAMPLER_SHIFT;
|
out += inv_phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
inv_phase &= RESAMPLER_RESOLUTION - 1;
|
inv_phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -571,14 +575,14 @@ static int resampler_run_linear(resampler * r, float ** out_, float * out_end)
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sample = in[0] + (in[1] - in[0]) * ((float)phase / RESAMPLER_RESOLUTION);
|
sample = in[0] + (in[1] - in[0]) * ((float)phase / RESAMPLER_RESOLUTION_EXTRA);
|
||||||
*out++ = sample;
|
*out++ = sample;
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -616,7 +620,7 @@ static int resampler_run_cubic(resampler * r, float ** out_, float * out_end)
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
kernel = cubic_lut + phase * 4;
|
kernel = cubic_lut + (phase >> RESAMPLER_SHIFT_EXTRA) * 4;
|
||||||
|
|
||||||
for (sample = 0, i = 0; i < 4; ++i)
|
for (sample = 0, i = 0; i < 4; ++i)
|
||||||
sample += in[i] * kernel[i];
|
sample += in[i] * kernel[i];
|
||||||
|
@ -624,9 +628,9 @@ static int resampler_run_cubic(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -665,7 +669,7 @@ static int resampler_run_cubic_sse(resampler * r, float ** out_, float * out_end
|
||||||
break;
|
break;
|
||||||
|
|
||||||
temp1 = _mm_loadu_ps( (const float *)( in ) );
|
temp1 = _mm_loadu_ps( (const float *)( in ) );
|
||||||
temp2 = _mm_load_ps( (const float *)( cubic_lut + phase * 4 ) );
|
temp2 = _mm_load_ps( (const float *)( cubic_lut + (phase >> RESAMPLER_SHIFT_EXTRA) * 4 ) );
|
||||||
temp1 = _mm_mul_ps( temp1, temp2 );
|
temp1 = _mm_mul_ps( temp1, temp2 );
|
||||||
samplex = _mm_add_ps( samplex, temp1 );
|
samplex = _mm_add_ps( samplex, temp1 );
|
||||||
temp1 = _mm_movehl_ps( temp1, samplex );
|
temp1 = _mm_movehl_ps( temp1, samplex );
|
||||||
|
@ -678,9 +682,9 @@ static int resampler_run_cubic_sse(resampler * r, float ** out_, float * out_end
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION - 1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -710,14 +714,15 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end)
|
||||||
int phase = r->phase;
|
int phase = r->phase;
|
||||||
int phase_inc = r->phase_inc;
|
int phase_inc = r->phase_inc;
|
||||||
|
|
||||||
int step = phase_inc > RESAMPLER_RESOLUTION ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION / phase_inc : RESAMPLER_RESOLUTION;
|
int step = phase_inc > RESAMPLER_RESOLUTION_EXTRA ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION_EXTRA / phase_inc : RESAMPLER_RESOLUTION;
|
||||||
int window_step = RESAMPLER_RESOLUTION;
|
int window_step = RESAMPLER_RESOLUTION;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
int phase_adj = phase * step / RESAMPLER_RESOLUTION;
|
int phase_reduced = phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
|
int phase_adj = phase_reduced * step / RESAMPLER_RESOLUTION;
|
||||||
float sample;
|
float sample;
|
||||||
|
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
|
@ -727,7 +732,7 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int window_pos = i * window_step;
|
int window_pos = i * window_step;
|
||||||
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase - window_pos)];
|
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase_reduced - window_pos)];
|
||||||
}
|
}
|
||||||
for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
|
for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
|
||||||
sample += in[i] * kernel[i];
|
sample += in[i] * kernel[i];
|
||||||
|
@ -735,9 +740,9 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -767,7 +772,7 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
int phase = r->phase;
|
int phase = r->phase;
|
||||||
int phase_inc = r->phase_inc;
|
int phase_inc = r->phase_inc;
|
||||||
|
|
||||||
int step = phase_inc > RESAMPLER_RESOLUTION ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION / phase_inc : RESAMPLER_RESOLUTION;
|
int step = phase_inc > RESAMPLER_RESOLUTION_EXTRA ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION_EXTRA / phase_inc : RESAMPLER_RESOLUTION;
|
||||||
int window_step = RESAMPLER_RESOLUTION;
|
int window_step = RESAMPLER_RESOLUTION;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -779,7 +784,8 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
__m128 samplex = _mm_setzero_ps();
|
__m128 samplex = _mm_setzero_ps();
|
||||||
float *kernelf = (float*)(&kernel);
|
float *kernelf = (float*)(&kernel);
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
int phase_adj = phase * step / RESAMPLER_RESOLUTION;
|
int phase_reduced = phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
|
int phase_adj = phase_reduced * step / RESAMPLER_RESOLUTION;
|
||||||
|
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
break;
|
break;
|
||||||
|
@ -788,7 +794,7 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int window_pos = i * window_step;
|
int window_pos = i * window_step;
|
||||||
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase - window_pos)];
|
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase_reduced - window_pos)];
|
||||||
}
|
}
|
||||||
for (i = 0; i < SINC_WIDTH / 2; ++i)
|
for (i = 0; i < SINC_WIDTH / 2; ++i)
|
||||||
{
|
{
|
||||||
|
@ -810,9 +816,9 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION - 1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -924,6 +930,19 @@ int resampler_get_sample(void *_r)
|
||||||
return (int)r->buffer_out[ r->read_pos ];
|
return (int)r->buffer_out[ r->read_pos ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float resampler_get_sample_float(void *_r)
|
||||||
|
{
|
||||||
|
resampler * r = ( resampler * ) _r;
|
||||||
|
if ( r->read_filled < 1 && r->phase_inc)
|
||||||
|
resampler_fill_and_remove_delay( r );
|
||||||
|
if ( r->read_filled < 1 )
|
||||||
|
return 0;
|
||||||
|
if ( r->quality == RESAMPLER_QUALITY_BLEP )
|
||||||
|
return r->buffer_out[ r->read_pos ] + r->accumulator;
|
||||||
|
else
|
||||||
|
return r->buffer_out[ r->read_pos ];
|
||||||
|
}
|
||||||
|
|
||||||
void resampler_remove_sample(void *_r)
|
void resampler_remove_sample(void *_r)
|
||||||
{
|
{
|
||||||
resampler * r = ( resampler * ) _r;
|
resampler * r = ( resampler * ) _r;
|
||||||
|
|
|
@ -2402,7 +2402,10 @@ static int8_t LoadInstrSample(PLAYER *p, MEM *f, uint16_t i)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mread(s->Pek, adpcm ? adpcm : l, 1, f);
|
if (s->Typ & 16)
|
||||||
|
mread_swap(s->Pek, l, 1, f, 0, 1); // byte swap 16 bit sample on big endian system, which by definition cannot be an adpcm sample
|
||||||
|
else
|
||||||
|
mread(s->Pek, adpcm ? adpcm : l, 1, f);
|
||||||
if (!adpcm)
|
if (!adpcm)
|
||||||
Delta2Samp(s->Pek, l, s->Typ);
|
Delta2Samp(s->Pek, l, s->Typ);
|
||||||
else
|
else
|
||||||
|
@ -2911,7 +2914,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler))
|
while (interpolating && resampler_get_free_count(resampler))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler, sampleData[samplePosition] * 256);
|
resampler_write_sample_fixed(resampler, sampleData[samplePosition], 8);
|
||||||
|
|
||||||
if (loopDir == 1)
|
if (loopDir == 1)
|
||||||
--samplePosition;
|
--samplePosition;
|
||||||
|
@ -2962,7 +2965,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample = resampler_get_sample(resampler);
|
sample = resampler_get_sample_float(resampler);
|
||||||
resampler_remove_sample(resampler);
|
resampler_remove_sample(resampler);
|
||||||
|
|
||||||
sample *= p->voice[ch].volume;
|
sample *= p->voice[ch].volume;
|
||||||
|
@ -3075,8 +3078,8 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler[0]))
|
while (interpolating && resampler_get_free_count(resampler[0]))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler[0], sampleData[samplePosition] * 256);
|
resampler_write_sample_fixed(resampler[0], sampleData[samplePosition], 8);
|
||||||
resampler_write_sample(resampler[1], sampleData[sampleLength + samplePosition] * 256);
|
resampler_write_sample_fixed(resampler[1], sampleData[sampleLength + samplePosition], 8);
|
||||||
|
|
||||||
if (loopDir == 1)
|
if (loopDir == 1)
|
||||||
--samplePosition;
|
--samplePosition;
|
||||||
|
@ -3127,8 +3130,8 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleL = resampler_get_sample(resampler[0]);
|
sampleL = resampler_get_sample_float(resampler[0]);
|
||||||
sampleR = resampler_get_sample(resampler[1]);
|
sampleR = resampler_get_sample_float(resampler[1]);
|
||||||
resampler_remove_sample(resampler[0]);
|
resampler_remove_sample(resampler[0]);
|
||||||
resampler_remove_sample(resampler[1]);
|
resampler_remove_sample(resampler[1]);
|
||||||
|
|
||||||
|
@ -3238,7 +3241,7 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler))
|
while (interpolating && resampler_get_free_count(resampler))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler, sampleData[samplePosition]);
|
resampler_write_sample_fixed(resampler, sampleData[samplePosition], 16);
|
||||||
|
|
||||||
if (loopDir == 1)
|
if (loopDir == 1)
|
||||||
--samplePosition;
|
--samplePosition;
|
||||||
|
@ -3289,7 +3292,7 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample = resampler_get_sample(resampler);
|
sample = resampler_get_sample_float(resampler);
|
||||||
resampler_remove_sample(resampler);
|
resampler_remove_sample(resampler);
|
||||||
|
|
||||||
sample *= p->voice[ch].volume;
|
sample *= p->voice[ch].volume;
|
||||||
|
@ -3402,8 +3405,8 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler[0]))
|
while (interpolating && resampler_get_free_count(resampler[0]))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler[0], sampleData[samplePosition]);
|
resampler_write_sample_fixed(resampler[0], sampleData[samplePosition], 16);
|
||||||
resampler_write_sample(resampler[1], sampleData[sampleLength + samplePosition]);
|
resampler_write_sample_fixed(resampler[1], sampleData[sampleLength + samplePosition], 16);
|
||||||
|
|
||||||
if (loopDir == 1)
|
if (loopDir == 1)
|
||||||
--samplePosition;
|
--samplePosition;
|
||||||
|
@ -3454,8 +3457,8 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleL = resampler_get_sample(resampler[0]);
|
sampleL = resampler_get_sample_float(resampler[0]);
|
||||||
sampleR = resampler_get_sample(resampler[1]);
|
sampleR = resampler_get_sample_float(resampler[1]);
|
||||||
resampler_remove_sample(resampler[0]);
|
resampler_remove_sample(resampler[0]);
|
||||||
resampler_remove_sample(resampler[1]);
|
resampler_remove_sample(resampler[1]);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#include "resampler.h"
|
#include "resampler.h"
|
||||||
|
|
||||||
enum { RESAMPLER_SHIFT = 10 };
|
enum { RESAMPLER_SHIFT = 10 };
|
||||||
|
enum { RESAMPLER_SHIFT_EXTRA = 8 };
|
||||||
enum { RESAMPLER_RESOLUTION = 1 << RESAMPLER_SHIFT };
|
enum { RESAMPLER_RESOLUTION = 1 << RESAMPLER_SHIFT };
|
||||||
|
enum { RESAMPLER_RESOLUTION_EXTRA = 1 << (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA) };
|
||||||
enum { SINC_WIDTH = 16 };
|
enum { SINC_WIDTH = 16 };
|
||||||
enum { SINC_SAMPLES = RESAMPLER_RESOLUTION * SINC_WIDTH };
|
enum { SINC_SAMPLES = RESAMPLER_RESOLUTION * SINC_WIDTH };
|
||||||
enum { CUBIC_SAMPLES = RESAMPLER_RESOLUTION * 4 };
|
enum { CUBIC_SAMPLES = RESAMPLER_RESOLUTION * 4 };
|
||||||
|
@ -324,9 +326,9 @@ void resampler_clear(void *_r)
|
||||||
void resampler_set_rate(void *_r, double new_factor)
|
void resampler_set_rate(void *_r, double new_factor)
|
||||||
{
|
{
|
||||||
resampler * r = ( resampler * ) _r;
|
resampler * r = ( resampler * ) _r;
|
||||||
r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION );
|
r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION_EXTRA );
|
||||||
new_factor = 1.0 / new_factor;
|
new_factor = 1.0 / new_factor;
|
||||||
r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION );
|
r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION_EXTRA );
|
||||||
}
|
}
|
||||||
|
|
||||||
void resampler_write_sample(void *_r, short s)
|
void resampler_write_sample(void *_r, short s)
|
||||||
|
@ -342,7 +344,7 @@ void resampler_write_sample(void *_r, short s)
|
||||||
if ( r->write_filled < resampler_buffer_size )
|
if ( r->write_filled < resampler_buffer_size )
|
||||||
{
|
{
|
||||||
float s32 = s;
|
float s32 = s;
|
||||||
s32 *= (1.0 / 32768.0);
|
s32 *= 256.0;
|
||||||
|
|
||||||
r->buffer_in[ r->write_pos ] = s32;
|
r->buffer_in[ r->write_pos ] = s32;
|
||||||
r->buffer_in[ r->write_pos + resampler_buffer_size ] = s32;
|
r->buffer_in[ r->write_pos + resampler_buffer_size ] = s32;
|
||||||
|
@ -403,13 +405,13 @@ static int resampler_run_zoh(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
r->phase = (unsigned short) phase;
|
r->phase = phase;
|
||||||
*out_ = out;
|
*out_ = out;
|
||||||
|
|
||||||
used = (int)(in - in_);
|
used = (int)(in - in_);
|
||||||
|
@ -440,6 +442,7 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
||||||
|
int phase_reduced = inv_phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
float sample;
|
float sample;
|
||||||
|
|
||||||
|
@ -449,7 +452,7 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
|
||||||
for (; i >= -SINC_WIDTH + 1; --i)
|
for (; i >= -SINC_WIDTH + 1; --i)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int abs_pos = abs(inv_phase - pos);
|
int abs_pos = abs(phase_reduced - pos);
|
||||||
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
||||||
}
|
}
|
||||||
sample = *in++ - last_amp;
|
sample = *in++ - last_amp;
|
||||||
|
@ -460,9 +463,9 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
inv_phase += inv_phase_inc;
|
inv_phase += inv_phase_inc;
|
||||||
|
|
||||||
out += inv_phase >> RESAMPLER_SHIFT;
|
out += inv_phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
inv_phase &= RESAMPLER_RESOLUTION-1;
|
inv_phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -505,6 +508,7 @@ static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
|
||||||
__m128 samplex;
|
__m128 samplex;
|
||||||
float sample;
|
float sample;
|
||||||
float *kernelf = (float*)(&kernel);
|
float *kernelf = (float*)(&kernel);
|
||||||
|
int phase_reduced = inv_phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
|
|
||||||
if ( out + SINC_WIDTH * 2 > out_end )
|
if ( out + SINC_WIDTH * 2 > out_end )
|
||||||
|
@ -513,7 +517,7 @@ static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
|
||||||
for (; i >= -SINC_WIDTH + 1; --i)
|
for (; i >= -SINC_WIDTH + 1; --i)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int abs_pos = abs(inv_phase - pos);
|
int abs_pos = abs(phase_reduced - pos);
|
||||||
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs_pos] * window_lut[abs_pos];
|
||||||
}
|
}
|
||||||
sample = *in++ - last_amp;
|
sample = *in++ - last_amp;
|
||||||
|
@ -531,9 +535,9 @@ static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
inv_phase += inv_phase_inc;
|
inv_phase += inv_phase_inc;
|
||||||
|
|
||||||
out += inv_phase >> RESAMPLER_SHIFT;
|
out += inv_phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
inv_phase &= RESAMPLER_RESOLUTION - 1;
|
inv_phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -571,14 +575,14 @@ static int resampler_run_linear(resampler * r, float ** out_, float * out_end)
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sample = in[0] + (in[1] - in[0]) * ((float)phase / RESAMPLER_RESOLUTION);
|
sample = in[0] + (in[1] - in[0]) * ((float)phase / RESAMPLER_RESOLUTION_EXTRA);
|
||||||
*out++ = sample;
|
*out++ = sample;
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -616,7 +620,7 @@ static int resampler_run_cubic(resampler * r, float ** out_, float * out_end)
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
kernel = cubic_lut + phase * 4;
|
kernel = cubic_lut + (phase >> RESAMPLER_SHIFT_EXTRA) * 4;
|
||||||
|
|
||||||
for (sample = 0, i = 0; i < 4; ++i)
|
for (sample = 0, i = 0; i < 4; ++i)
|
||||||
sample += in[i] * kernel[i];
|
sample += in[i] * kernel[i];
|
||||||
|
@ -624,9 +628,9 @@ static int resampler_run_cubic(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -665,7 +669,7 @@ static int resampler_run_cubic_sse(resampler * r, float ** out_, float * out_end
|
||||||
break;
|
break;
|
||||||
|
|
||||||
temp1 = _mm_loadu_ps( (const float *)( in ) );
|
temp1 = _mm_loadu_ps( (const float *)( in ) );
|
||||||
temp2 = _mm_load_ps( (const float *)( cubic_lut + phase * 4 ) );
|
temp2 = _mm_load_ps( (const float *)( cubic_lut + (phase >> RESAMPLER_SHIFT_EXTRA) * 4 ) );
|
||||||
temp1 = _mm_mul_ps( temp1, temp2 );
|
temp1 = _mm_mul_ps( temp1, temp2 );
|
||||||
samplex = _mm_add_ps( samplex, temp1 );
|
samplex = _mm_add_ps( samplex, temp1 );
|
||||||
temp1 = _mm_movehl_ps( temp1, samplex );
|
temp1 = _mm_movehl_ps( temp1, samplex );
|
||||||
|
@ -678,9 +682,9 @@ static int resampler_run_cubic_sse(resampler * r, float ** out_, float * out_end
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION - 1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -710,14 +714,15 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end)
|
||||||
int phase = r->phase;
|
int phase = r->phase;
|
||||||
int phase_inc = r->phase_inc;
|
int phase_inc = r->phase_inc;
|
||||||
|
|
||||||
int step = phase_inc > RESAMPLER_RESOLUTION ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION / phase_inc : RESAMPLER_RESOLUTION;
|
int step = phase_inc > RESAMPLER_RESOLUTION_EXTRA ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION_EXTRA / phase_inc : RESAMPLER_RESOLUTION;
|
||||||
int window_step = RESAMPLER_RESOLUTION;
|
int window_step = RESAMPLER_RESOLUTION;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
float kernel[SINC_WIDTH * 2], kernel_sum = 0.0;
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
int phase_adj = phase * step / RESAMPLER_RESOLUTION;
|
int phase_reduced = phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
|
int phase_adj = phase_reduced * step / RESAMPLER_RESOLUTION;
|
||||||
float sample;
|
float sample;
|
||||||
|
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
|
@ -727,7 +732,7 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int window_pos = i * window_step;
|
int window_pos = i * window_step;
|
||||||
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase - window_pos)];
|
kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase_reduced - window_pos)];
|
||||||
}
|
}
|
||||||
for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
|
for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
|
||||||
sample += in[i] * kernel[i];
|
sample += in[i] * kernel[i];
|
||||||
|
@ -735,9 +740,9 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION-1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -767,7 +772,7 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
int phase = r->phase;
|
int phase = r->phase;
|
||||||
int phase_inc = r->phase_inc;
|
int phase_inc = r->phase_inc;
|
||||||
|
|
||||||
int step = phase_inc > RESAMPLER_RESOLUTION ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION / phase_inc : RESAMPLER_RESOLUTION;
|
int step = phase_inc > RESAMPLER_RESOLUTION_EXTRA ? RESAMPLER_RESOLUTION * RESAMPLER_RESOLUTION_EXTRA / phase_inc : RESAMPLER_RESOLUTION;
|
||||||
int window_step = RESAMPLER_RESOLUTION;
|
int window_step = RESAMPLER_RESOLUTION;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -779,7 +784,8 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
__m128 samplex = _mm_setzero_ps();
|
__m128 samplex = _mm_setzero_ps();
|
||||||
float *kernelf = (float*)(&kernel);
|
float *kernelf = (float*)(&kernel);
|
||||||
int i = SINC_WIDTH;
|
int i = SINC_WIDTH;
|
||||||
int phase_adj = phase * step / RESAMPLER_RESOLUTION;
|
int phase_reduced = phase >> RESAMPLER_SHIFT_EXTRA;
|
||||||
|
int phase_adj = phase_reduced * step / RESAMPLER_RESOLUTION;
|
||||||
|
|
||||||
if ( out >= out_end )
|
if ( out >= out_end )
|
||||||
break;
|
break;
|
||||||
|
@ -788,7 +794,7 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
{
|
{
|
||||||
int pos = i * step;
|
int pos = i * step;
|
||||||
int window_pos = i * window_step;
|
int window_pos = i * window_step;
|
||||||
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase - window_pos)];
|
kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(phase_adj - pos)] * window_lut[abs(phase_reduced - window_pos)];
|
||||||
}
|
}
|
||||||
for (i = 0; i < SINC_WIDTH / 2; ++i)
|
for (i = 0; i < SINC_WIDTH / 2; ++i)
|
||||||
{
|
{
|
||||||
|
@ -810,9 +816,9 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end)
|
||||||
|
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
|
|
||||||
in += phase >> RESAMPLER_SHIFT;
|
in += phase >> (RESAMPLER_SHIFT + RESAMPLER_SHIFT_EXTRA);
|
||||||
|
|
||||||
phase &= RESAMPLER_RESOLUTION - 1;
|
phase &= RESAMPLER_RESOLUTION_EXTRA - 1;
|
||||||
}
|
}
|
||||||
while ( in < in_end );
|
while ( in < in_end );
|
||||||
|
|
||||||
|
@ -911,7 +917,20 @@ int resampler_get_sample_count(void *_r)
|
||||||
return r->read_filled;
|
return r->read_filled;
|
||||||
}
|
}
|
||||||
|
|
||||||
float resampler_get_sample(void *_r)
|
int resampler_get_sample(void *_r)
|
||||||
|
{
|
||||||
|
resampler * r = ( resampler * ) _r;
|
||||||
|
if ( r->read_filled < 1 && r->phase_inc)
|
||||||
|
resampler_fill_and_remove_delay( r );
|
||||||
|
if ( r->read_filled < 1 )
|
||||||
|
return 0;
|
||||||
|
if ( r->quality == RESAMPLER_QUALITY_BLEP )
|
||||||
|
return (int)(r->buffer_out[ r->read_pos ] + r->accumulator);
|
||||||
|
else
|
||||||
|
return (int)r->buffer_out[ r->read_pos ];
|
||||||
|
}
|
||||||
|
|
||||||
|
float resampler_get_sample_float(void *_r)
|
||||||
{
|
{
|
||||||
resampler * r = ( resampler * ) _r;
|
resampler * r = ( resampler * ) _r;
|
||||||
if ( r->read_filled < 1 && r->phase_inc)
|
if ( r->read_filled < 1 && r->phase_inc)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define resampler_clear EVALUATE(RESAMPLER_DECORATE,_resampler_clear)
|
#define resampler_clear EVALUATE(RESAMPLER_DECORATE,_resampler_clear)
|
||||||
#define resampler_get_sample_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample_count)
|
#define resampler_get_sample_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample_count)
|
||||||
#define resampler_get_sample EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample)
|
#define resampler_get_sample EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample)
|
||||||
|
#define resampler_get_sample_float EVALUATE(RESAMPLER_DECORATE,_resampler_get_sample_float)
|
||||||
#define resampler_remove_sample EVALUATE(RESAMPLER_DECORATE,_resampler_remove_sample)
|
#define resampler_remove_sample EVALUATE(RESAMPLER_DECORATE,_resampler_remove_sample)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -49,7 +50,8 @@ void resampler_set_rate( void *, double new_factor );
|
||||||
int resampler_ready(void *);
|
int resampler_ready(void *);
|
||||||
void resampler_clear(void *);
|
void resampler_clear(void *);
|
||||||
int resampler_get_sample_count(void *);
|
int resampler_get_sample_count(void *);
|
||||||
float resampler_get_sample(void *);
|
int resampler_get_sample(void *);
|
||||||
|
float resampler_get_sample_float(void *);
|
||||||
void resampler_remove_sample(void *);
|
void resampler_remove_sample(void *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2961,7 +2961,7 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler))
|
while (interpolating && resampler_get_free_count(resampler))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler, sampleData[samplePosition] * 256);
|
resampler_write_sample_fixed(resampler, sampleData[samplePosition], 8);
|
||||||
|
|
||||||
++samplePosition;
|
++samplePosition;
|
||||||
|
|
||||||
|
@ -2986,7 +2986,7 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample = resampler_get_sample(resampler);
|
sample = resampler_get_sample_float(resampler);
|
||||||
resampler_remove_sample(resampler);
|
resampler_remove_sample(resampler);
|
||||||
|
|
||||||
sample *= volume;
|
sample *= volume;
|
||||||
|
@ -3102,8 +3102,8 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler[0]))
|
while (interpolating && resampler_get_free_count(resampler[0]))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler[0], sampleData[samplePosition] * 256);
|
resampler_write_sample_fixed(resampler[0], sampleData[samplePosition], 8);
|
||||||
resampler_write_sample(resampler[1], sampleData[sampleLength + samplePosition] * 256);
|
resampler_write_sample_fixed(resampler[1], sampleData[sampleLength + samplePosition], 8);
|
||||||
|
|
||||||
++samplePosition;
|
++samplePosition;
|
||||||
|
|
||||||
|
@ -3128,8 +3128,8 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleL = resampler_get_sample(resampler[0]);
|
sampleL = resampler_get_sample_float(resampler[0]);
|
||||||
sampleR = resampler_get_sample(resampler[1]);
|
sampleR = resampler_get_sample_float(resampler[1]);
|
||||||
resampler_remove_sample(resampler[0]);
|
resampler_remove_sample(resampler[0]);
|
||||||
resampler_remove_sample(resampler[1]);
|
resampler_remove_sample(resampler[1]);
|
||||||
|
|
||||||
|
@ -3240,7 +3240,7 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler))
|
while (interpolating && resampler_get_free_count(resampler))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler, get_le16(&sampleData[samplePosition]));
|
resampler_write_sample_fixed(resampler, get_le16(&sampleData[samplePosition]), 16);
|
||||||
|
|
||||||
++samplePosition;
|
++samplePosition;
|
||||||
|
|
||||||
|
@ -3265,7 +3265,7 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample = resampler_get_sample(resampler);
|
sample = resampler_get_sample_float(resampler);
|
||||||
resampler_remove_sample(resampler);
|
resampler_remove_sample(resampler);
|
||||||
|
|
||||||
sample *= volume;
|
sample *= volume;
|
||||||
|
@ -3381,8 +3381,8 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
|
|
||||||
while (interpolating && resampler_get_free_count(resampler[0]))
|
while (interpolating && resampler_get_free_count(resampler[0]))
|
||||||
{
|
{
|
||||||
resampler_write_sample(resampler[0], get_le16(&sampleData[samplePosition]));
|
resampler_write_sample_fixed(resampler[0], get_le16(&sampleData[samplePosition]), 16);
|
||||||
resampler_write_sample(resampler[1], get_le16(&sampleData[sampleLength + samplePosition]));
|
resampler_write_sample_fixed(resampler[1], get_le16(&sampleData[sampleLength + samplePosition]), 16);
|
||||||
|
|
||||||
++samplePosition;
|
++samplePosition;
|
||||||
|
|
||||||
|
@ -3407,8 +3407,8 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleL = resampler_get_sample(resampler[0]);
|
sampleL = resampler_get_sample_float(resampler[0]);
|
||||||
sampleR = resampler_get_sample(resampler[1]);
|
sampleR = resampler_get_sample_float(resampler[1]);
|
||||||
resampler_remove_sample(resampler[0]);
|
resampler_remove_sample(resampler[0]);
|
||||||
resampler_remove_sample(resampler[1]);
|
resampler_remove_sample(resampler[1]);
|
||||||
|
|
||||||
|
@ -3539,9 +3539,9 @@ static inline void mixadpcm(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
while (interpolating && resampler_get_free_count(resampler))
|
while (interpolating && resampler_get_free_count(resampler))
|
||||||
{
|
{
|
||||||
int8_t nextDelta = lastDelta;
|
int8_t nextDelta = lastDelta;
|
||||||
int16_t sample = get_adpcm_sample(sampleDictionary, sampleData, samplePosition, &nextDelta) * 256;
|
int16_t sample = get_adpcm_sample(sampleDictionary, sampleData, samplePosition, &nextDelta);
|
||||||
|
|
||||||
resampler_write_sample(resampler, sample);
|
resampler_write_sample_fixed(resampler, sample, 8);
|
||||||
|
|
||||||
lastDelta = nextDelta;
|
lastDelta = nextDelta;
|
||||||
|
|
||||||
|
@ -3576,7 +3576,7 @@ static inline void mixadpcm(PLAYER *p, uint8_t ch, uint32_t samples)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample = resampler_get_sample(resampler);
|
sample = resampler_get_sample_float(resampler);
|
||||||
resampler_remove_sample(resampler);
|
resampler_remove_sample(resampler);
|
||||||
|
|
||||||
sample *= volume;
|
sample *= volume;
|
||||||
|
@ -3727,7 +3727,7 @@ static void st3play_AdlibMix(PLAYER *p, float *buffer, int32_t count)
|
||||||
|
|
||||||
for (i = 0; i < outbuffer_avail; ++i)
|
for (i = 0; i < outbuffer_avail; ++i)
|
||||||
{
|
{
|
||||||
float sample = resampler_get_sample( p->fmResampler );
|
float sample = resampler_get_sample_float( p->fmResampler );
|
||||||
resampler_remove_sample( p->fmResampler );
|
resampler_remove_sample( p->fmResampler );
|
||||||
|
|
||||||
buffer[i * 2 + 0] += sample;
|
buffer[i * 2 + 0] += sample;
|
||||||
|
|
Loading…
Reference in New Issue