Updated playptmod
parent
b8763c6cad
commit
ae3d45cf45
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue