Updated playptmod

CQTexperiment
Chris Moeller 2015-11-12 21:35:58 -08:00
parent b8763c6cad
commit ae3d45cf45
3 changed files with 70 additions and 43 deletions

View File

@ -1,8 +1,14 @@
/*
** PLAYPTMOD v1.25 - 20th of April 2015 - http://16-bits.org
** =========================================================
** PLAYPTMOD v1.27 - 8th of October 2015 - http://16-bits.org
** ==========================================================
** This is the foobar2000 version, with added code by kode54
**
** Changelog from 1.26:
** - Only loop module if speed is zero after fully processing an entire row
**
** Changelog from 1.25:
** - Invert Loop (EFx) was inaccurate
**
** Changelog from 1.24:
** - Sample swaps are now only handled for PT MODs
** - Handle sample swapping even during note delay (EDx)
@ -623,7 +629,7 @@ static void outputAudio(player *p, int *target, int numSamples)
{
tempVolume = (v->data && !v->mute ? v->vol : 0);
while (interpolating && (resampler_get_free_count(bSmp) ||
while (interpolating > 0 && (resampler_get_free_count(bSmp) ||
(!resampler_get_sample_count(bSmp) &&
!resampler_get_sample_count(bVol))))
{
@ -646,7 +652,7 @@ static void outputAudio(player *p, int *target, int numSamples)
if (!v->newLoopFlag)
{
interpolating = 0;
interpolating = -resampler_get_padding_size();
break;
}
@ -673,7 +679,7 @@ static void outputAudio(player *p, int *target, int numSamples)
if (!v->newLoopFlag)
{
interpolating = 0;
interpolating = -resampler_get_padding_size();
break;
}
@ -688,13 +694,22 @@ static void outputAudio(player *p, int *target, int numSamples)
}
else
{
interpolating = 0;
interpolating = -resampler_get_padding_size();
break;
}
}
}
}
while (interpolating < 0 && (resampler_get_free_count(bSmp) ||
(!resampler_get_sample_count(bSmp) &&
!resampler_get_sample_count(bVol))))
{
resampler_write_sample_fixed(bSmp, 0, 1);
resampler_write_sample_fixed(bVol, 0, 1);
++interpolating;
}
v->interpolating = interpolating;
while (j < numSamples && resampler_get_sample_count(bSmp))
@ -713,7 +728,7 @@ static void outputAudio(player *p, int *target, int numSamples)
j++;
}
if (!interpolating)
if (!interpolating && !resampler_get_sample_count(bSmp))
{
v->data = NULL;
break;
@ -941,7 +956,7 @@ static int playptmod_LoadMTM(player *p, BUF *fmodule)
p->useLEDFilter = false;
p->moduleLoaded = true;
p->minPeriod = 14;
p->maxPeriod = 1712;
@ -1199,7 +1214,7 @@ int playptmod_LoadMem(void *_p, const unsigned char *buf, unsigned long bufLengt
s->attribute = 0;
}
}
/* STK 2.5 had loopStart in words, not bytes. Convert if late version STK */
for (i = 0; i < 15; ++i)
{
@ -1705,15 +1720,14 @@ static void processInvertLoop(player *p, mod_channel *ch)
if (ch->invertLoopSpeed > 0)
{
ch->invertLoopDelay += invertLoopSpeeds[ch->invertLoopSpeed];
if (ch->invertLoopDelay & 128)
if (ch->invertLoopDelay >= 128)
{
ch->invertLoopDelay = 0;
if (ch->invertLoopPtr != NULL) /* PT doesn't do this, but we're more sane than that */
if (ch->invertLoopPtr != NULL) /* SAFETY BUG FIX */
{
ch->invertLoopPtr++;
if (ch->invertLoopPtr >= (ch->invertLoopStart + ch->invertLoopLength))
ch->invertLoopPtr = ch->invertLoopStart;
if (++ch->invertLoopPtr >= (ch->invertLoopStart + ch->invertLoopLength))
ch->invertLoopPtr = ch->invertLoopStart;
*ch->invertLoopPtr = -1 - *ch->invertLoopPtr;
}
@ -2362,7 +2376,7 @@ static void fxTremolo(player *p, mod_channel *ch)
if (loNybble > 0)
ch->tremoloDepth = loNybble;
}
processTremolo(p, ch);
}
@ -2494,26 +2508,17 @@ static void fxSetTempo(player *p, mod_channel *ch)
{
if (p->modTick == 0)
{
if (ch->param > 0)
{
if ((ch->param < 32) || p->vBlankTiming)
modSetSpeed(p, ch->param);
else
modSetTempo(p, ch->param);
}
if ((ch->param < 32) || p->vBlankTiming)
modSetSpeed(p, ch->param);
else
{
/* Bit of a hack, will alert caller that song has restarted */
p->modOrder = p->source->head.clippedRestartPos;
p->PBreakPosition = 0;
p->PosJumpAssert = true;
}
modSetTempo(p, ch->param);
}
}
static void processEffects(player *p, mod_channel *ch)
{
processInvertLoop(p, ch);
if (p->modTick > 0)
processInvertLoop(p, ch);
if ((!ch->command && !ch->param) == 0)
{
@ -2622,7 +2627,7 @@ static void fetchPatternData(player *p, mod_channel *ch)
ch->tempPeriod = (p->minPeriod == PT_MIN_PERIOD) ? rawAmigaPeriods[(ch->fineTune * ((12 * 3) + 1)) + tempNote] : extendedRawPeriods[(ch->fineTune * ((12 * 7) + 1)) + tempNote];
ch->flags |= FLAG_NOTE;
}
/* do a slightly different path for 3xx/5xy in PT mode */
if (p->minPeriod == PT_MIN_PERIOD)
{
@ -2680,7 +2685,7 @@ static void processChannel(player *p, mod_channel *ch)
ch->invertLoopPtr = &p->source->sampleData[s->offset + s->loopStart];
ch->invertLoopStart = ch->invertLoopPtr;
ch->invertLoopLength = s->loopLength;
if ((ch->command != 0x03) && (ch->command != 0x05))
{
ch->offset = 0;
@ -2805,6 +2810,18 @@ static void processTick(player *p)
p->forceEffectsOff = true;
}
/* Only process speed 0 effect after processing entire row */
if (p->modSpeed == 0)
{
/* Bit of a hack, will alert code below of a full repeat */
p->modOrder = p->source->head.clippedRestartPos;
modSetSpeed(p, 6);
p->modTick = 6; /* cause instant repeat */
p->PBreakPosition = 0;
p->PosJumpAssert = true;
}
p->modTick++;
if (p->modTick >= p->modSpeed)
{
@ -3046,7 +3063,7 @@ void playptmod_Free(void *_p)
free(p->source);
p->source = NULL;
}
p->moduleLoaded = false;
}
@ -3085,7 +3102,7 @@ void playptmod_Free(void *_p)
resampler_delete(p->blep[i]);
resampler_delete(p->blepVol[i]);
}
free(p);
}

View File

@ -8,11 +8,13 @@
#endif
#ifdef __APPLE__
#include <TargetConditionals.h>
#if TARGET_CPU_ARM
#include <arm_neon.h>
#if TARGET_CPU_ARM || TARGET_CPU_ARM64
#define RESAMPLER_NEON
#endif
#endif
#ifdef RESAMPLER_NEON
#include <arm_neon.h>
#endif
#ifdef _MSC_VER
#define ALIGNED _declspec(align(16))
@ -301,6 +303,11 @@ static int resampler_output_delay(resampler *r)
}
}
int resampler_get_padding_size()
{
return SINC_WIDTH - 1;
}
int resampler_ready(void *_r)
{
resampler * r = ( resampler * ) _r;
@ -470,7 +477,7 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
}
last_amp += sample;
sample /= kernel_sum;
for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
for (i = 0; i < SINC_WIDTH * 2; ++i)
out[i] += sample * kernel[i];
}
@ -626,8 +633,8 @@ static int resampler_run_blep(resampler * r, float ** out_, float * out_end)
{
temp1 = vld1q_f32( (const float32_t *)( kernel + i ) );
temp2 = vld1q_f32( (const float32_t *) out + i * 4 );
temp1 = vmlaq_f32( temp2, temp1, samplex );
vst1q_f32( (float32_t *) out + i * 4, temp1 );
temp2 = vmlaq_f32( temp2, temp1, samplex );
vst1q_f32( (float32_t *) out + i * 4, temp2 );
}
}
@ -743,7 +750,7 @@ static int resampler_run_blam(resampler * r, float ** out_, float * out_end)
}
last_amp += sample;
sample /= kernel_sum;
for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i)
for (i = 0; i < SINC_WIDTH * 2; ++i)
out[i] += sample * kernel[i];
}
@ -908,7 +915,7 @@ static int resampler_run_blam(resampler * r, float ** out_, float * out_end)
sample = in[0];
if (phase_inc < 1.0f)
sample += (in[1] - in[0]) * fphase;
sample += (in[1] - in[0]) * phase;
sample -= last_amp;
if (sample)
@ -935,8 +942,8 @@ static int resampler_run_blam(resampler * r, float ** out_, float * out_end)
{
temp1 = vld1q_f32( (const float32_t *)( kernel + i ) );
temp2 = vld1q_f32( (const float32_t *) out + i * 4 );
temp1 = vmlaq_f32( temp2, temp1, samplex );
vst1q_f32( (float32_t *) out + i * 4, temp1 );
temp2 = vmlaq_f32( temp2, temp1, samplex );
vst1q_f32( (float32_t *) out + i * 4, temp2 );
}
}

View File

@ -1,7 +1,8 @@
#ifndef _RESAMPLER_H_
#define _RESAMPLER_H_
// Ugglay
#define RESAMPLER_DECORATE playptmod
#ifdef RESAMPLER_DECORATE
#define PASTE(a,b) a ## b
#define EVALUATE(a,b) PASTE(a,b)
@ -12,6 +13,7 @@
#define resampler_dup_inplace EVALUATE(RESAMPLER_DECORATE,_resampler_dup_inplace)
#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_padding_size EVALUATE(RESAMPLER_DECORATE,_resampler_get_padding_size)
#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)
@ -45,6 +47,7 @@ enum
void resampler_set_quality(void *, int quality);
int resampler_get_free_count(void *);
int resampler_get_padding_size();
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 );