Removed muffling cutoff from blip_buf and added a sinc generator, and changed playptmod vblank mode so it only applies to ProTracker mods and not any other tracker's formats

CQTexperiment
Chris Moeller 2014-04-11 18:23:53 -07:00
parent f0c3567214
commit 6c3c261ef9
4 changed files with 85 additions and 73 deletions

View File

@ -103,42 +103,41 @@ int ptm_blip_read_sample( blip_t* m )
restrict restrict
*/ */
/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ static int const bl_step [phase_count + 1] [half_width] =
static short const bl_step [phase_count + 1] [half_width] =
{ {
{ 43, -115, 350, -488, 1136, -914, 5861,21022}, { 0, 0, 0, 0, 0, 0, 0,32768},
{ 44, -118, 348, -473, 1076, -799, 5274,21001}, { -1, 9, -30, 79, -178, 380, -923,32713},
{ 45, -121, 344, -454, 1011, -677, 4706,20936}, { -2, 17, -58, 153, -346, 739,-1775,32549},
{ 46, -122, 336, -431, 942, -549, 4156,20829}, { -3, 24, -83, 221, -503, 1073,-2555,32277},
{ 47, -123, 327, -404, 868, -418, 3629,20679}, { -4, 30, -107, 284, -647, 1382,-3259,31898},
{ 47, -122, 316, -375, 792, -285, 3124,20488}, { -5, 36, -127, 340, -778, 1662,-3887,31415},
{ 47, -120, 303, -344, 714, -151, 2644,20256}, { -5, 40, -145, 390, -895, 1913,-4439,30832},
{ 46, -117, 289, -310, 634, -17, 2188,19985}, { -6, 44, -160, 433, -998, 2133,-4914,30151},
{ 46, -114, 273, -275, 553, 117, 1758,19675}, { -6, 47, -172, 469,-1085, 2322,-5313,29377},
{ 44, -108, 255, -237, 471, 247, 1356,19327}, { -6, 49, -181, 499,-1158, 2479,-5636,28515},
{ 43, -103, 237, -199, 390, 373, 981,18944}, { -6, 50, -188, 521,-1215, 2604,-5885,27570},
{ 42, -98, 218, -160, 310, 495, 633,18527}, { -5, 51, -193, 537,-1257, 2697,-6063,26548},
{ 40, -91, 198, -121, 231, 611, 314,18078}, { -5, 51, -195, 547,-1285, 2760,-6172,25455},
{ 38, -84, 178, -81, 153, 722, 22,17599}, { -5, 50, -195, 550,-1298, 2792,-6214,24298},
{ 36, -76, 157, -43, 80, 824, -241,17092}, { -4, 49, -192, 548,-1298, 2795,-6193,23084},
{ 34, -68, 135, -3, 8, 919, -476,16558}, { -4, 47, -188, 540,-1284, 2770,-6112,21820},
{ 32, -61, 115, 34, -60, 1006, -683,16001}, { -3, 45, -182, 526,-1258, 2719,-5976,20513},
{ 29, -52, 94, 70, -123, 1083, -862,15422}, { -3, 42, -175, 508,-1221, 2643,-5788,19172},
{ 27, -44, 73, 106, -184, 1152,-1015,14824}, { -2, 39, -166, 486,-1173, 2544,-5554,17805},
{ 25, -36, 53, 139, -239, 1211,-1142,14210}, { -2, 36, -156, 460,-1116, 2425,-5277,16418},
{ 22, -27, 34, 170, -290, 1261,-1244,13582}, { -1, 33, -145, 431,-1050, 2287,-4963,15020},
{ 20, -20, 16, 199, -335, 1301,-1322,12942}, { -1, 30, -133, 399, -977, 2132,-4615,13618},
{ 18, -12, -3, 226, -375, 1331,-1376,12293}, { -1, 26, -120, 365, -898, 1963,-4240,12221},
{ 15, -4, -19, 250, -410, 1351,-1408,11638}, { 0, 23, -107, 329, -813, 1783,-3843,10836},
{ 13, 3, -35, 272, -439, 1361,-1419,10979}, { 0, 20, -94, 292, -725, 1593,-3427, 9470},
{ 11, 9, -49, 292, -464, 1362,-1410,10319}, { 0, 17, -81, 254, -633, 1396,-2998, 8131},
{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, { 0, 14, -68, 215, -540, 1194,-2560, 6824},
{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, { 0, 11, -56, 177, -446, 989,-2119, 5556},
{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, { 0, 8, -43, 139, -353, 784,-1678, 4334},
{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, { 0, 6, -31, 102, -260, 581,-1242, 3162},
{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, { 0, 3, -20, 66, -170, 381, -814, 2046},
{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, { 0, 1, -9, 32, -83, 187, -399, 991},
{ 0, 43, -115, 350, -488, 1136, -914, 5861} { 0, 0, 0, 0, 0, 0, 0, 0}
}; };
/* Shifting by pre_shift allows calculation using unsigned int rather than /* Shifting by pre_shift allows calculation using unsigned int rather than
@ -154,8 +153,8 @@ void ptm_blip_add_delta( blip_t* m, float time, int delta )
int const phase_shift = frac_bits - phase_bits; int const phase_shift = frac_bits - phase_bits;
int phase = fixed >> phase_shift & (phase_count - 1); int phase = fixed >> phase_shift & (phase_count - 1);
short const* in = bl_step [phase]; int const* in = bl_step [phase];
short const* rev = bl_step [phase_count - phase]; int const* rev = bl_step [phase_count - phase];
int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1);
int delta2 = (delta * interp) >> delta_bits; int delta2 = (delta * interp) >> delta_bits;

View File

@ -93,21 +93,6 @@
enum enum
{ {
FORMAT_MK, // ProTracker 1.x
FORMAT_MK2, // ProTracker 2.x (if tune has >64 patterns)
FORMAT_FLT4, // StarTrekker
FORMAT_FLT8,
FORMAT_NCHN, // FastTracker II (only 1-9 channel MODs)
FORMAT_NNCH, // FastTracker II (10-32 channel MODs)
FORMAT_16CN, // FastTracker II (16 channel MODs)
FORMAT_32CN, // FastTracker II (32 channel MODs)
FORMAT_STK, // The Ultimate SoundTracker (15 samples)
FORMAT_NT, // NoiseTracker 1.0
FORMAT_MTM, // MultiTracker
FORMAT_UNKNOWN,
FLAG_NOTE = 1, FLAG_NOTE = 1,
FLAG_SAMPLE = 2, FLAG_SAMPLE = 2,
FLAG_NEWSAMPLE = 4, FLAG_NEWSAMPLE = 4,
@ -954,6 +939,7 @@ static int playptmod_LoadMTM(player *p, BUF *fmodule)
p->minPeriod = 14; p->minPeriod = 14;
p->maxPeriod = 1712; p->maxPeriod = 1712;
p->source->head.format = FORMAT_MTM;
p->source->head.initBPM = 125; p->source->head.initBPM = 125;
return (true); return (true);
@ -1500,6 +1486,11 @@ int playptmod_Load(void *_p, const char *filename)
return (false); return (false);
} }
int playptmod_GetFormat(void *p)
{
return ((player *)p)->source->head.format;
}
static void fxArpeggio(player *p, mod_channel *ch); static void fxArpeggio(player *p, mod_channel *ch);
static void fxPortamentoSlideUp(player *p, mod_channel *ch); static void fxPortamentoSlideUp(player *p, mod_channel *ch);
static void fxPortamentoSlideDown(player *p, mod_channel *ch); static void fxPortamentoSlideDown(player *p, mod_channel *ch);
@ -2388,7 +2379,7 @@ static void processEffects(player *p, mod_channel *ch)
static void fxPan(player *p, mod_channel *ch) static void fxPan(player *p, mod_channel *ch)
{ {
if (p->modTick == 0) if (p->modTick == 0)
mixerSetChPan(p, ch->chanIndex, ch->param); mixerSetChPan(p, ch->chanIndex, ch->param <= 128 ? ch->param * 2 : 128);
} }
static void efxPan(player *p, mod_channel *ch) static void efxPan(player *p, mod_channel *ch)
@ -2743,7 +2734,6 @@ void playptmod_Render16(void *_p, short *target, int length)
void *playptmod_Create(int samplingFrequency) void *playptmod_Create(int samplingFrequency)
{ {
player *p = (player *) calloc(1, sizeof(player)); player *p = (player *) calloc(1, sizeof(player));
float norm;
int i, j; int i, j;

View File

@ -5,6 +5,24 @@
extern "C" { extern "C" {
#endif #endif
enum
{
FORMAT_MK, // ProTracker 1.x
FORMAT_MK2, // ProTracker 2.x (if tune has >64 patterns)
FORMAT_FLT4, // StarTrekker
FORMAT_FLT8,
FORMAT_NCHN, // FastTracker II (only 1-9 channel MODs)
FORMAT_NNCH, // FastTracker II (10-32 channel MODs)
FORMAT_16CN, // FastTracker II (16 channel MODs)
FORMAT_32CN, // FastTracker II (32 channel MODs)
FORMAT_STK, // The Ultimate SoundTracker (15 samples)
FORMAT_NT, // NoiseTracker 1.0
FORMAT_MTM, // MultiTracker
FORMAT_UNKNOWN
};
void * playptmod_Create(int samplingFrequency); void * playptmod_Create(int samplingFrequency);
#define PTMOD_OPTION_CLAMP_PERIODS 0 #define PTMOD_OPTION_CLAMP_PERIODS 0
@ -21,6 +39,8 @@ void playptmod_Config(void *p, int option, int value);
int playptmod_LoadMem(void *p, const unsigned char *buf, unsigned long bufLength); int playptmod_LoadMem(void *p, const unsigned char *buf, unsigned long bufLength);
int playptmod_Load(void *p, const char *filename); int playptmod_Load(void *p, const char *filename);
int playptmod_GetFormat(void *p);
void playptmod_Play(void *p, unsigned int startOrder); void playptmod_Play(void *p, unsigned int startOrder);
void playptmod_Stop(void *p); void playptmod_Stop(void *p);
void playptmod_Render(void *p, signed int *target, int length); void playptmod_Render(void *p, signed int *target, int length);

View File

@ -14,20 +14,10 @@
@implementation ptmodDecoder @implementation ptmodDecoder
BOOL probe_length( unsigned long * intro_length, unsigned long * loop_length, int test_vblank, const void * src, unsigned long size, unsigned int subsong ) BOOL probe_length( void * ptmod, unsigned long * intro_length, unsigned long * loop_length, int test_vblank, const void * src, unsigned long size, unsigned int subsong )
{ {
void * ptmod = playptmod_Create( 44100 );
if ( !ptmod ) return NO;
playptmod_Config( ptmod, PTMOD_OPTION_CLAMP_PERIODS, 0 );
playptmod_Config( ptmod, PTMOD_OPTION_VSYNC_TIMING, test_vblank ); playptmod_Config( ptmod, PTMOD_OPTION_VSYNC_TIMING, test_vblank );
if ( !playptmod_LoadMem( ptmod, src, size ) )
{
playptmod_Free( ptmod );
return NO;
}
playptmod_Play( ptmod, subsong ); playptmod_Play( ptmod, subsong );
unsigned long length_total = 0; unsigned long length_total = 0;
@ -46,7 +36,6 @@ BOOL probe_length( unsigned long * intro_length, unsigned long * loop_length, in
*loop_length = 0; *loop_length = 0;
*intro_length = 44100 * 60 * 3; *intro_length = 44100 * 60 * 3;
playptmod_Stop(ptmod); playptmod_Stop(ptmod);
playptmod_Free( ptmod );
return YES; return YES;
} }
@ -59,7 +48,6 @@ BOOL probe_length( unsigned long * intro_length, unsigned long * loop_length, in
} }
playptmod_Stop(ptmod); playptmod_Stop(ptmod);
playptmod_Free( ptmod );
*loop_length = length_total - length_saved; *loop_length = length_total - length_saved;
*intro_length = length_saved - *loop_length; *intro_length = length_saved - *loop_length;
@ -81,14 +69,29 @@ BOOL probe_length( unsigned long * intro_length, unsigned long * loop_length, in
else else
track_num = [[[s url] fragment] intValue]; track_num = [[[s url] fragment] intValue];
void * mod = playptmod_Create( 44100 );
if ( !mod ) return NO;
if ( !playptmod_LoadMem(mod, data, size) )
{
playptmod_Free(mod);
return NO;
}
int format = playptmod_GetFormat(mod);
BOOL can_be_vblank = (format <= FORMAT_MK2);
unsigned long normal_intro_length, normal_loop_length, vblank_intro_length, vblank_loop_length; unsigned long normal_intro_length, normal_loop_length, vblank_intro_length, vblank_loop_length;
if ( !probe_length(&normal_intro_length, &normal_loop_length, 0, data, size, track_num) ) if ( !probe_length(mod, &normal_intro_length, &normal_loop_length, 0, data, size, track_num) )
return NO; return NO;
if ( !probe_length(&vblank_intro_length, &vblank_loop_length, 1, data, size, track_num) ) if ( can_be_vblank && !probe_length(mod, &vblank_intro_length, &vblank_loop_length, 1, data, size, track_num) )
return NO; return NO;
else vblank_intro_length = 0, vblank_loop_length = 0;
isVblank = ( vblank_intro_length + vblank_loop_length ) < ( normal_intro_length + normal_loop_length ); playptmod_Free(mod);
isVblank = can_be_vblank && (( vblank_intro_length + vblank_loop_length ) < ( normal_intro_length + normal_loop_length ));
unsigned long intro_length = isVblank ? vblank_intro_length : normal_intro_length; unsigned long intro_length = isVblank ? vblank_intro_length : normal_intro_length;
unsigned long loop_length = isVblank ? vblank_loop_length : normal_loop_length; unsigned long loop_length = isVblank ? vblank_loop_length : normal_loop_length;