Update Syntrax decoder with speed improvements.

CQTexperiment
Christopher Snowhill 2017-03-12 21:15:16 -07:00
parent d963710c28
commit fce57925c0
3 changed files with 61 additions and 75 deletions

View File

@ -62,11 +62,10 @@ static void gen_sinc( double rolloff, int width, double offset, double spacing,
}
enum { width = 32 };
enum { stereo = 2 };
enum { max_res = 512 };
enum { min_width = (width < 4 ? 4 : width) };
enum { adj_width = min_width / 4 * 4 + 2 };
enum { write_offset = adj_width * stereo };
enum { write_offset = adj_width };
enum { buffer_size = 128 };
@ -83,8 +82,8 @@ typedef struct _resampler
imp_t const* imp;
imp_t impulses [max_res * (adj_width + 2 * (sizeof(imp_off_t) / sizeof(imp_t)))];
sample_t buffer_in[buffer_size * stereo * 2];
sample_t buffer_out[buffer_size * stereo];
sample_t buffer_in[buffer_size * 2];
sample_t buffer_out[buffer_size];
} resampler;
void * resampler_create()
@ -172,7 +171,7 @@ void resampler_set_rate( void *_r, double new_factor )
rs->rate_ = ratio_;
/* how much of input is used for each output sample */
step = stereo * (int) floor( ratio_ );
step = (int) floor( ratio_ );
fraction = fmod( ratio_, 1.0 );
filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
@ -193,10 +192,10 @@ void resampler_set_rate( void *_r, double new_factor )
if ( pos >= 0.9999999 )
{
pos -= 1.0;
cur_step += stereo;
cur_step += 1;
}
((imp_off_t*)out)[0] = (cur_step - rs->width_ * 2 + 4) * sizeof (sample_t);
((imp_off_t*)out)[0] = (cur_step - rs->width_ + 2) * sizeof (sample_t);
((imp_off_t*)out)[1] = 2 * sizeof (imp_t) + 2 * sizeof (imp_off_t);
out += 2 * (sizeof(imp_off_t) / sizeof(imp_t));
/*input_per_cycle += cur_step;*/
@ -210,19 +209,19 @@ void resampler_set_rate( void *_r, double new_factor )
int resampler_get_free(void *_r)
{
resampler *r = (resampler *)_r;
return buffer_size * stereo - r->infilled;
return buffer_size - r->infilled;
}
int resampler_get_min_fill(void *_r)
{
resampler *r = (resampler *)_r;
const int min_needed = write_offset + stereo;
const int min_needed = write_offset + 1;
const int latency = r->latency ? 0 : adj_width;
int min_free = min_needed - r->infilled - latency;
return min_free < 0 ? 0 : min_free;
}
void resampler_write_pair(void *_r, sample_t ls, sample_t rs)
void resampler_write_sample(void *_r, sample_t s)
{
resampler *r = (resampler *)_r;
@ -231,24 +230,20 @@ void resampler_write_pair(void *_r, sample_t ls, sample_t rs)
int i;
for ( i = 0; i < adj_width / 2; ++i)
{
r->buffer_in[r->inptr + 0] = 0;
r->buffer_in[r->inptr + 1] = 0;
r->buffer_in[buffer_size * stereo + r->inptr + 0] = 0;
r->buffer_in[buffer_size * stereo + r->inptr + 1] = 0;
r->inptr = (r->inptr + stereo) % (buffer_size * stereo);
r->infilled += stereo;
r->buffer_in[r->inptr] = 0;
r->buffer_in[buffer_size + r->inptr] = 0;
r->inptr = (r->inptr + 1) % (buffer_size);
r->infilled += 1;
}
r->latency = 1;
}
if (r->infilled < buffer_size * stereo)
if (r->infilled < buffer_size)
{
r->buffer_in[r->inptr + 0] = ls;
r->buffer_in[r->inptr + 1] = rs;
r->buffer_in[buffer_size * stereo + r->inptr + 0] = ls;
r->buffer_in[buffer_size * stereo + r->inptr + 1] = rs;
r->inptr = (r->inptr + stereo) % (buffer_size * stereo);
r->infilled += stereo;
r->buffer_in[r->inptr] = s;
r->buffer_in[buffer_size + r->inptr + 0] = s;
r->inptr = (r->inptr + 1) % (buffer_size);
r->infilled += 1;
}
}
@ -271,35 +266,30 @@ static const sample_t * resampler_inner_loop( resampler *r, sample_t** out_,
int n;
/* accumulate in extended precision*/
int pt = imp [0];
intermediate_t l = (intermediate_t)pt * (intermediate_t)(in [0]);
intermediate_t r = (intermediate_t)pt * (intermediate_t)(in [1]);
intermediate_t s = (intermediate_t)pt * (intermediate_t)(in [0]);
if ( out >= out_end )
break;
for ( n = (adj_width - 2) / 2; n; --n )
{
pt = imp [1];
l += (intermediate_t)pt * (intermediate_t)(in [2]);
r += (intermediate_t)pt * (intermediate_t)(in [3]);
s += (intermediate_t)pt * (intermediate_t)(in [1]);
/* pre-increment more efficient on some RISC processors*/
imp += 2;
pt = imp [0];
r += (intermediate_t)pt * (intermediate_t)(in [5]);
in += 4;
l += (intermediate_t)pt * (intermediate_t)(in [0]);
s += (intermediate_t)pt * (intermediate_t)(in [2]);
in += 2;
}
pt = imp [1];
l += (intermediate_t)pt * (intermediate_t)(in [2]);
r += (intermediate_t)pt * (intermediate_t)(in [3]);
s += (intermediate_t)pt * (intermediate_t)(in [1]);
/* these two "samples" after the end of the impulse give the
* proper offsets to the next input sample and next impulse */
in = (sample_t const*) ((char const*) in + ((imp_off_t*)(&imp [2]))[0]); /* some negative value */
imp = (imp_t const*) ((char const*) imp + ((imp_off_t*)(&imp [2]))[1]); /* small positive or large negative */
out [0] = (sample_t) (l >> 15);
out [1] = (sample_t) (r >> 15);
out += 2;
out [0] = (sample_t) (s >> 15);
out += 1;
}
while ( in < in_end );
@ -315,9 +305,9 @@ static int resampler_wrapper( resampler *r, sample_t out [], int* out_size,
sample_t const in [], int in_size )
{
sample_t* out_ = out;
int result = (int)(resampler_inner_loop( r, &out_, out + *out_size, in, in_size ) - in);
int result = resampler_inner_loop( r, &out_, out + *out_size, in, in_size ) - in;
*out_size = (int)(out_ - out);
*out_size = out_ - out;
return result;
}
@ -327,11 +317,11 @@ static void resampler_fill( resampler *r )
{
int inread;
int writepos = ( r->outptr + r->outfilled ) % (buffer_size * stereo);
int writesize = (buffer_size * stereo) - writepos;
if ( writesize > ( buffer_size * stereo - r->outfilled ) )
writesize = buffer_size * stereo - r->outfilled;
inread = resampler_wrapper(r, &r->buffer_out[writepos], &writesize, &r->buffer_in[buffer_size * stereo + r->inptr - r->infilled], r->infilled);
int writepos = ( r->outptr + r->outfilled ) % (buffer_size);
int writesize = (buffer_size) - writepos;
if ( writesize > ( buffer_size - r->outfilled ) )
writesize = buffer_size - r->outfilled;
inread = resampler_wrapper(r, &r->buffer_out[writepos], &writesize, &r->buffer_in[buffer_size + r->inptr - r->infilled], r->infilled);
r->infilled -= inread;
r->outfilled += writesize;
if (!inread)
@ -342,38 +332,36 @@ static void resampler_fill( resampler *r )
int resampler_get_avail(void *_r)
{
resampler *r = (resampler *)_r;
if (r->outfilled < stereo && r->infilled >= r->width_)
if (r->outfilled < 1 && r->infilled >= r->width_)
resampler_fill( r );
return r->outfilled;
}
static void resampler_read_pair_internal( resampler *r, sample_t *ls, sample_t *rs, int advance )
static void resampler_read_sample_internal( resampler *r, sample_t *s, int advance )
{
if (r->outfilled < stereo)
if (r->outfilled < 1)
resampler_fill( r );
if (r->outfilled < stereo)
if (r->outfilled < 1)
{
*ls = 0;
*rs = 0;
*s = 0;
return;
}
*ls = r->buffer_out[r->outptr + 0];
*rs = r->buffer_out[r->outptr + 1];
*s = r->buffer_out[r->outptr];
if (advance)
{
r->outptr = (r->outptr + 2) % (buffer_size * stereo);
r->outfilled -= stereo;
r->outptr = (r->outptr + 1) % (buffer_size);
r->outfilled -= 1;
}
}
void resampler_read_pair( void *_r, sample_t *ls, sample_t *rs )
void resampler_read_sample( void *_r, sample_t *s )
{
resampler *r = (resampler *)_r;
resampler_read_pair_internal(r, ls, rs, 1);
resampler_read_sample_internal(r, s, 1);
}
void resampler_peek_pair( void *_r, sample_t *ls, sample_t *rs )
void resampler_peek_sample( void *_r, sample_t *s )
{
resampler *r = (resampler *)_r;
resampler_read_pair_internal(r, ls, rs, 0);
resampler_read_sample_internal(r, s, 0);
}

View File

@ -61,12 +61,12 @@ void resampler_set_rate( void *, double new_factor );
int resampler_get_free(void *);
int resampler_get_min_fill(void *);
void resampler_write_pair(void *, sample_t ls, sample_t rs);
void resampler_write_sample(void *, sample_t s);
int resampler_get_avail(void *);
void resampler_read_pair( void *, sample_t *ls, sample_t *rs );
void resampler_peek_pair( void *, sample_t *ls, sample_t *rs );
void resampler_read_sample( void *, sample_t *s );
void resampler_peek_sample( void *, sample_t *s );
#ifdef __cplusplus
}

View File

@ -134,11 +134,11 @@ void playerDestroy(Player *p)
Player * playerCreate(int SAMPLEFREQUENCY)
{
int i/*, j*/;
int i, j;
Player* p;
srand((unsigned int)time(NULL));
srand(time(NULL));
p = (Player *) calloc(1, sizeof(Player));
if (!p) return NULL;
@ -241,7 +241,7 @@ static void instrEffect(Player *p, int chanNum)
int _local38;
int _local39;
int _local40;
/*int _local43;*/
int _local43;
int butt, ron, pat, buf2, buf1;
TuneChannel *tc = &p->tuneChannels[chanNum];
@ -1666,7 +1666,7 @@ static void ABH(Player *p)
_local4 = 0;
}
_local2 = _local3[_local4].patLen;
if ((((tc->LJHG == _local2)) || ((tc->EQMIWERPIF == 0xFF)))){
if ((((tc->LJHG == _local2)) || ((tc->EQMIWERPIF == -1)))){
tc->LJHG = 0;
tc->EQMIWERPIF++;
p->curSubsong.mutedChans[i] = p->mutedChans[i];
@ -1744,10 +1744,10 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
{
int i, j;
uint sampleNum;
int amp, smp/*, pos*/;
int amp, smp, pos;
int32_t audioMainR, audioMainL;
int32_t audioDelayR, audioDelayL;
uint otherDelayTime = 1;
uint otherDelayTime;
Voice *v;
TuneChannel *tc;
int insNum;
@ -1850,8 +1850,6 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
{
//amp = word_6632B964;
//otherDelayTime = word_6632BB24;
amp = 0;
otherDelayTime = 1;
}
else
{
@ -1882,7 +1880,7 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
while ( v->sampPos != -1 && resampler_get_min_fill(v->resampler[0]) )
{
s = v->waveBuff[v->sampPos];
resampler_write_pair(v->resampler[0], s, s);
resampler_write_sample(v->resampler[0], s);
if ( v->isPlayingBackward )
{
v->sampPos--;
@ -1919,7 +1917,7 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
}
//smp = intp->interpSamp(v);
resampler_read_pair(v->resampler[0], &s, &s);
resampler_read_sample(v->resampler[0], &s);
smp = s;
audioMainR += (smp * v->gainRight) >> 8;
@ -1936,11 +1934,11 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
while ( resampler_get_min_fill(v->resampler[0]) )
{
s = v->waveBuff[v->synthPos];
resampler_write_pair(v->resampler[0], s, s);
resampler_write_sample(v->resampler[0], s);
v->synthPos++;
v->synthPos &= v->wavelength;
}
resampler_read_pair(v->resampler[0], &s, &s);
resampler_read_sample(v->resampler[0], &s);
smp = s;
audioMainR += (smp * v->gainRight) >> 8;
@ -2028,7 +2026,7 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
while ( v->sampPos != -1 && resampler_get_min_fill(v->resampler[1]) )
{
s = v->waveBuff[v->sampPos];
resampler_write_pair(v->resampler[1], s, s);
resampler_write_sample(v->resampler[1], s);
if ( v->isPlayingBackward )
{
v->sampPos--;
@ -2063,7 +2061,7 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
}
}
}
resampler_read_pair(v->resampler[1], &s, &s);
resampler_read_sample(v->resampler[1], &s);
smp = s;
audioMainR += (smp * v->gainRight) >> 8;
@ -2080,11 +2078,11 @@ void mixChunk(Player *p, int16_t *outBuff, uint playbackBufferSize)
while ( resampler_get_min_fill(v->resampler[1]) )
{
s = v->waveBuff[v->synthPos];
resampler_write_pair(v->resampler[1], s, s);
resampler_write_sample(v->resampler[1], s);
v->synthPos++;
v->synthPos &= v->wavelength;
}
resampler_read_pair(v->resampler[1], &s, &s);
resampler_read_sample(v->resampler[1], &s);
smp = s;
audioMainR += (smp * v->gainRight) >> 8;