ref: 3be9ce486cf67827f18346b54d83478d487abd40
parent: 719dbbe38317512e9aabb2654953e9ba226caaf6
author: Chris Moeller <kode54@gmail.com>
date: Mon Jan 11 04:00:22 EST 2010
{10/6/2006 9:42:18 PM~10/6/2006 9:42:20 PM}2006-10-07 05:24 UTC - kode54 - Simplified volume ramping update code, reducing the size of the resampler code considerably. - Bumped the volume ramping precision to 24 bits of fraction precision, which is needed by Sweetsin.xm. - Moved sample rate reporting to dynamic info as requested by Peter, since it's not a property of the files themselves, but user configurable. - Version is now 0.9.8.1 2006-10-07 03:42 UTC - kode54 - Changed DSMF sample loader to ignore unknown flags instead of blowing an error. 2006-09-25 17:39 UTC - kode54 - Added hack to MOD loader for when sample start is specified in bytes instead of words. 2006-09-19 15:05 UTC - kode54 - Shuffled finetune calculation into the correct position, immediately applied as delta is calculated from note. - Promoted IT_SAMPLE finetune property to signed short as char is insufficient for full semitone range. (+/- 256) - Changed resampler to use full 64-bit comparison for todo variable range checking which should hopefully eliminate any further problems with pitch slides which go out of range. - Version is now 0.9.8 git-tfs-id: [http://localhost:8080/tfs/DefaultCollection/]$/foobar2000/files/plugins.root;C123
--- a/dumb/include/internal/it.h
+++ b/dumb/include/internal/it.h
@@ -229,7 +229,7 @@
unsigned char vibrato_rate;
unsigned char vibrato_waveform;
- signed char finetune;
+ signed short finetune;
void *data;
--- a/dumb/src/helpers/resamp2.inc
+++ b/dumb/src/helpers/resamp2.inc
@@ -106,11 +106,11 @@
#define VOLUME_VARIABLES lvol, lvolr, lvold, lvolt, lvolm, rvol, rvolr, rvold, rvolt, rvolm
#define SET_VOLUME_VARIABLES { \
if ( volume_left ) { \
- lvolr = (int)(volume_left->volume * 65536.0); \
- lvold = (int)(volume_left->delta * 65536.0); \
- lvolt = (int)(volume_left->target * 65536.0); \
+ lvolr = (int)(volume_left->volume * 16777216.0); \
+ lvold = (int)(volume_left->delta * 16777216.0); \
+ lvolt = (int)(volume_left->target * 16777216.0); \
lvolm = (int)(volume_left->mix * 65536.0); \
- lvol = MULSC( lvolr, lvolm ); \
+ lvol = MULSC( lvolr >> 8, lvolm ); \
if ( lvolr == lvolt ) volume_left = NULL; \
} else { \
lvol = 0; \
@@ -117,11 +117,11 @@
lvolt = 0; \
} \
if ( volume_right ) { \
- rvolr = (int)(volume_right->volume * 65536.0); \
- rvold = (int)(volume_right->delta * 65536.0); \
- rvolt = (int)(volume_right->target * 65536.0); \
+ rvolr = (int)(volume_right->volume * 16777216.0); \
+ rvold = (int)(volume_right->delta * 16777216.0); \
+ rvolt = (int)(volume_right->target * 16777216.0); \
rvolm = (int)(volume_right->mix * 65536.0); \
- rvol = MULSC( rvolr, rvolm ); \
+ rvol = MULSC( rvolr >> 8, rvolm ); \
if ( rvolr == rvolt ) volume_right = NULL; \
} else { \
rvol = 0; \
@@ -129,8 +129,8 @@
} \
}
#define RETURN_VOLUME_VARIABLES { \
- if ( volume_left ) volume_left->volume = (float)lvolr / 65536.0f; \
- if ( volume_right ) volume_right->volume = (float)rvolr / 65536.0f; \
+ if ( volume_left ) volume_left->volume = (float)lvolr / 16777216.0f; \
+ if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \
}
#define VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0)
#define MIX_ALIAS(op, upd, offset) STEREO_DEST_MIX_ALIAS(op, upd, offset)
--- a/dumb/src/helpers/resamp3.inc
+++ b/dumb/src/helpers/resamp3.inc
@@ -50,6 +50,7 @@
int VOLUME_VARIABLES;
long done;
long todo;
+ LONG_LONG todo64;
int quality;
if (!resampler || resampler->dir == 0) return 0;
@@ -75,14 +76,16 @@
dt = -dt;
if (resampler->dir < 0)
- todo = (long)((((LONG_LONG)(resampler->pos - resampler->start) << 16) + resampler->subpos - dt) / -dt);
+ todo64 = ((((LONG_LONG)(resampler->pos - resampler->start) << 16) + resampler->subpos - dt) / -dt);
else
- todo = (long)((((LONG_LONG)(resampler->end - resampler->pos) << 16) - resampler->subpos - 1 + dt) / dt);
+ todo64 = ((((LONG_LONG)(resampler->end - resampler->pos) << 16) - resampler->subpos - 1 + dt) / dt);
- if (todo < 0)
+ if (todo64 < 0)
todo = 0;
- else if (todo > dst_size - done)
+ else if (todo64 > dst_size - done)
todo = dst_size - done;
+ else
+ todo = (long) todo64;
done += todo;
--- a/dumb/src/helpers/resample.inc
+++ b/dumb/src/helpers/resample.inc
@@ -85,24 +85,14 @@
#define UPDATE_VOLUME( pvol, vol ) { \
if (pvol) { \
- if (vol##d < 0) { \
- if (vol##t - vol##r > vol##d) { \
- pvol->volume = pvol->target; \
- pvol = NULL; \
- vol = MULSC( vol##t, vol##m ); \
- } else { \
- vol##r += vol##d; \
- vol = MULSC( vol##r, vol##m ); \
- } \
+ vol##r += vol##d; \
+ if ((vol##d < 0 && vol##r <= vol##t) || \
+ (vol##d > 0 && vol##r >= vol##t)) { \
+ pvol->volume = pvol->target; \
+ pvol = NULL; \
+ vol = MULSC( vol##t >> 8, vol##m ); \
} else { \
- if (vol##t - vol##r < vol##d) { \
- pvol->volume = pvol->target; \
- pvol = NULL; \
- vol = MULSC( vol##t, vol##m ); \
- } else { \
- vol##r += vol##d; \
- vol = MULSC( vol##r, vol##m ); \
- } \
+ vol = MULSC( vol##r >> 8, vol##m ); \
} \
} \
}
@@ -120,11 +110,11 @@
#define MONO_DEST_VOLUME_ZEROS 0
#define SET_MONO_DEST_VOLUME_VARIABLES { \
if ( volume ) { \
- volr = (int)(volume->volume * 65536.0); \
- vold = (int)(volume->delta * 65536.0); \
- volt = (int)(volume->target * 65536.0); \
+ volr = (int)(volume->volume * 16777216.0); \
+ vold = (int)(volume->delta * 16777216.0); \
+ volt = (int)(volume->target * 16777216.0); \
volm = (int)(volume->mix * 65536.0); \
- vol = MULSC( volr, volm ); \
+ vol = MULSC( volr >> 8, volm ); \
if ( volr == volt ) volume = NULL; \
} else { \
vol = 0; \
@@ -131,7 +121,7 @@
volt = 0; \
} \
}
-#define RETURN_MONO_DEST_VOLUME_VARIABLES if ( volume ) volume->volume = (float)volr / 65536.0f
+#define RETURN_MONO_DEST_VOLUME_VARIABLES if ( volume ) volume->volume = (float)volr / 16777216.0f
#define MONO_DEST_VOLUMES_ARE_ZERO (vol == 0 && volt == 0)
#define MONO_DEST_MIX_ALIAS(op, upd, offset) { \
*dst++ op ALIAS(x[offset], vol); \
@@ -191,11 +181,11 @@
#define MONO_DEST_VOLUME_ZEROS 0, 0
#define SET_MONO_DEST_VOLUME_VARIABLES { \
if ( volume_left ) { \
- lvolr = (int)(volume_left->volume * 65536.0); \
- lvold = (int)(volume_left->delta * 65536.0); \
- lvolt = (int)(volume_left->target * 65536.0); \
+ lvolr = (int)(volume_left->volume * 16777216.0); \
+ lvold = (int)(volume_left->delta * 16777216.0); \
+ lvolt = (int)(volume_left->target * 16777216.0); \
lvolm = (int)(volume_left->mix * 65536.0); \
- lvol = MULSC( lvolr, lvolm ); \
+ lvol = MULSC( lvolr >> 8, lvolm ); \
if ( lvolr == lvolt ) volume_left = NULL; \
} else { \
lvol = 0; \
@@ -202,11 +192,11 @@
lvolt = 0; \
} \
if ( volume_right ) { \
- rvolr = (int)(volume_right->volume * 65536.0); \
- rvold = (int)(volume_right->delta * 65536.0); \
- rvolt = (int)(volume_right->target * 65536.0); \
+ rvolr = (int)(volume_right->volume * 16777216.0); \
+ rvold = (int)(volume_right->delta * 16777216.0); \
+ rvolt = (int)(volume_right->target * 16777216.0); \
rvolm = (int)(volume_right->mix * 65536.0); \
- rvol = MULSC( rvolr, rvolm ); \
+ rvol = MULSC( rvolr >> 8, rvolm ); \
if ( rvolr == rvolt ) volume_right = NULL; \
} else { \
rvol = 0; \
@@ -214,8 +204,8 @@
} \
}
#define RETURN_MONO_DEST_VOLUME_VARIABLES { \
- if ( volume_left ) volume_left->volume = (float)lvolr / 65536.0f; \
- if ( volume_right ) volume_right->volume = (float)rvolr / 65536.0f; \
+ if ( volume_left ) volume_left->volume = (float)lvolr / 16777216.0f; \
+ if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \
}
#define MONO_DEST_VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0)
#define MONO_DEST_MIX_ALIAS(op, upd, offset) { \
--- a/dumb/src/it/itread.c
+++ b/dumb/src/it/itread.c
@@ -587,6 +587,7 @@
sample->vibrato_rate = 0;
sample->vibrato_waveform = 0;
}
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
return dumbfile_error(f);
@@ -686,7 +687,7 @@
-#define DETECT_DUPLICATE_CHANNELS
+//#define DETECT_DUPLICATE_CHANNELS
#ifdef DETECT_DUPLICATE_CHANNELS
#include <stdio.h>
#endif
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -1639,7 +1639,7 @@
channel->playing->sample_vibrato_waveform = channel->playing->sample->vibrato_waveform;
channel->playing->sample_vibrato_depth = 0;
channel->playing->slide = 0;
- channel->playing->finetune = 0;
+ channel->playing->finetune = channel->playing->sample->finetune;
if (flags & 1) {
channel->playing->volume_envelope = volume_envelope;
@@ -3023,7 +3023,7 @@
channel->playing->sample_vibrato_waveform = channel->playing->sample->vibrato_waveform;
channel->playing->sample_vibrato_depth = 0;
channel->playing->slide = 0;
- channel->playing->finetune = 0;
+ channel->playing->finetune = channel->playing->sample->finetune;
it_reset_filter_state(&channel->playing->filter_state[0]); // Are these
it_reset_filter_state(&channel->playing->filter_state[1]); // necessary?
it_playing_reset_resamplers(channel->playing, 0);
@@ -3492,6 +3492,38 @@
return (int)note;
}
+// Period table for Protracker octaves 0-5:
+static const unsigned short ProTrackerPeriodTable[6*12] =
+{
+ 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907,
+ 856,808,762,720,678,640,604,570,538,508,480,453,
+ 428,404,381,360,339,320,302,285,269,254,240,226,
+ 214,202,190,180,170,160,151,143,135,127,120,113,
+ 107,101,95,90,85,80,75,71,67,63,60,56,
+ 53,50,47,45,42,40,37,35,33,31,30,28
+};
+
+
+static const unsigned short ProTrackerTunedPeriods[16*12] =
+{
+ 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907,
+ 1700,1604,1514,1430,1348,1274,1202,1134,1070,1010,954,900,
+ 1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,894,
+ 1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,888,
+ 1664,1570,1482,1398,1320,1246,1176,1110,1048,990,934,882,
+ 1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,874,
+ 1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,868,
+ 1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914,862,
+ 1814,1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,
+ 1800,1700,1604,1514,1430,1350,1272,1202,1134,1070,1010,954,
+ 1788,1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,
+ 1774,1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,
+ 1762,1664,1570,1482,1398,1320,1246,1176,1110,1048,988,934,
+ 1750,1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,
+ 1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,
+ 1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914
+};
+
static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer)
{
DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
@@ -3557,7 +3589,8 @@
if (sigdata->flags & IT_LINEAR_SLIDES) {
int currpitch = ((playing->note - 60) << 8) + playing->slide
- + vibrato_shift;
+ + vibrato_shift
+ + playing->finetune;
/* We add a feature here, which is that of keeping the pitch
* within range. Otherwise it crashes. Trust me. It happened.
@@ -3573,7 +3606,7 @@
} else {
int slide = playing->slide + vibrato_shift;
- playing->delta = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note);
+ playing->delta = (float)pow(DUMB_PITCH_BASE, ((60 - playing->note) << 8) - playing->finetune );
/* playing->delta is 1.0 for C-5, 0.5 for C-6, etc. */
playing->delta *= 1.0f / playing->sample->C5_speed;
@@ -3605,9 +3638,6 @@
}
else*/ playing->delta *= (float)pow(DUMB_SEMITONE_BASE, channel->arpeggio >> 8);/*
}*/
-
- if (playing->finetune)
- playing->delta *= (float)pow(DUMB_PITCH_BASE, playing->finetune);
playing->filter_cutoff = channel->filter_cutoff;
playing->filter_resonance = channel->filter_resonance;
--- a/dumb/src/it/read669.c
+++ b/dumb/src/it/read669.c
@@ -199,6 +199,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = 0; // do we have to set _all_ these?
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
return 0;
--- a/dumb/src/it/readam.c
+++ b/dumb/src/it/readam.c
@@ -118,6 +118,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = IT_VIBRATO_SINE;
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
if ( flags & 0x08 )
--- a/dumb/src/it/readasy.c
+++ b/dumb/src/it/readasy.c
@@ -124,7 +124,8 @@
sample->flags = IT_SAMPLE_EXISTS;
sample->default_pan = 0;
- sample->C5_speed = ( long )( 16726.0 * pow( DUMB_PITCH_BASE, finetune * 32 ) );
+ sample->C5_speed = (int)( AMIGA_CLOCK / 214.0 );//( long )( 16726.0 * pow( DUMB_PITCH_BASE, finetune * 32 ) );
+ sample->finetune = finetune * 32;
// the above line might be wrong
if ( ( sample->loop_end - sample->loop_start > 2 ) && ( sample->loop_end <= sample->length ) )
--- a/dumb/src/it/readdsmf.c
+++ b/dumb/src/it/readdsmf.c
@@ -48,8 +48,8 @@
return 0;
}
- if ( flags & ~( 2 | 1 ) )
- return -1;
+ /*if ( flags & ~( 2 | 1 ) )
+ return -1;*/
if ( sample->length + 64 > len )
return -1;
@@ -62,6 +62,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = IT_VIBRATO_SINE;
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
if ( flags & 1 )
--- a/dumb/src/it/readmod.c
+++ b/dumb/src/it/readmod.c
@@ -120,7 +120,7 @@
static int it_mod_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f)
{
- int finetune;
+ int finetune, loop_start, loop_length;
/**
21 22 Chars Sample 1 name. If the name is not a full
@@ -141,8 +141,12 @@
/** Each finetune step changes the note 1/8th of a semitone. */
sample->global_volume = 64;
sample->default_volume = dumbfile_getc(f); // Should we be setting global_volume to this instead?
- sample->loop_start = dumbfile_mgetw(f) << 1;
- sample->loop_end = sample->loop_start + (dumbfile_mgetw(f) << 1);
+ loop_start = dumbfile_mgetw(f) << 1;
+ loop_length = dumbfile_mgetw(f) << 1;
+ if ( loop_length > 2 && loop_start + loop_length > sample->length && loop_start / 2 + loop_length <= sample->length )
+ loop_start /= 2;
+ sample->loop_start = loop_start;
+ sample->loop_end = loop_start + loop_length;
/**
Once this sample has been played completely from beginning
to end, if the repeat length (next field) is greater than two bytes it
@@ -160,7 +164,8 @@
sample->flags = IT_SAMPLE_EXISTS;
sample->default_pan = 0;
- sample->C5_speed = (long)(16726.0*pow(DUMB_PITCH_BASE, finetune*32));
+ sample->C5_speed = (int)( AMIGA_CLOCK / 214.0 ); //(long)(16726.0*pow(DUMB_PITCH_BASE, finetune*32));
+ sample->finetune = finetune * 32;
// the above line might be wrong
if (sample->loop_end > sample->length)
@@ -485,8 +490,8 @@
* combined into one eight-channel pattern. Pattern indexes must
* be halved. Why oh why do they obfuscate so?
*/
- for (i = 0; i < 128; i++)
- sigdata->order[i] >>= 1;
+ /*for (i = 0; i < 128; i++)
+ sigdata->order[i] >>= 1;*/
break;
case DUMB_ID('C','D','8','1'):
case DUMB_ID('O','C','T','A'):
@@ -611,6 +616,10 @@
//while (sigdata->n_orders > 1 && !sigdata->order[sigdata->n_orders - 1]) sigdata->n_orders--;
}
+ if ( ! n_channels )
+ for (i = 0; i < 128; i++)
+ sigdata->order[i] >>= 1;
+
/* "The old NST format contains only 15 samples (instead of 31). Further
* it doesn't contain a file format tag (id). So Pattern data offset is
* at 20+15*30+1+1+128."
@@ -688,7 +697,6 @@
}
}
}
-
/* And finally, the sample data */
for (i = 0; i < sigdata->n_samples; i++) {
@@ -699,6 +707,24 @@
return NULL;
}
}
+
+ /* w00t! */
+ /*if ( n_channels == 4 &&
+ ( sigdata->n_samples == 15 ||
+ ( ( fft & 240 ) != DUMB_ID( 0, 0, 'C', 0 ) &&
+ ( fft & 240 ) != DUMB_ID( 0, 0, 'H', 0 ) &&
+ ( fft & 240 ) != 0 ) ) ) {
+ for ( i = 0; i < sigdata->n_samples; ++i ) {
+ IT_SAMPLE * sample = &sigdata->sample [i];
+ if ( sample && ( sample->flags & IT_SAMPLE_EXISTS ) ) {
+ int n, o;
+ o = sample->length;
+ if ( o > 4 ) o = 4;
+ for ( n = 0; n < o; ++n )
+ ( ( char * ) sample->data ) [n] = 0;
+ }
+ }
+ }*/
dumbfile_close(f); /* Destroy the BUFFERED_MOD DUMBFILE we were using. */
/* The DUMBFILE originally passed to our function is intact. */
--- a/dumb/src/it/readmtm.c
+++ b/dumb/src/it/readmtm.c
@@ -125,7 +125,8 @@
}
sample->default_pan = 0;
- sample->C5_speed = (long)(16726.0*pow(DUMB_PITCH_BASE, finetune*32));
+ sample->C5_speed = (int)( AMIGA_CLOCK / 214.0 );//(long)(16726.0*pow(DUMB_PITCH_BASE, finetune*32));
+ sample->finetune = finetune * 32;
// the above line might be wrong
if (sample->loop_end > sample->length)
--- a/dumb/src/it/readoldpsm.c
+++ b/dumb/src/it/readoldpsm.c
@@ -96,8 +96,10 @@
s->C5_speed = buffer[(n * 64) + 62] | (buffer[(n * 64) + 63] << 8);
if (finetune < 16) {
if (finetune >= 8) finetune -= 16;
- s->C5_speed = (long)((double)s->C5_speed * pow(DUMB_PITCH_BASE, finetune*32));
+ //s->C5_speed = (long)((double)s->C5_speed * pow(DUMB_PITCH_BASE, finetune*32));
+ s->finetune = finetune * 32;
}
+ else s->finetune = 0;
s->flags |= IT_SAMPLE_EXISTS;
if (flags & 0x41) {
--- a/dumb/src/it/readpsm.c
+++ b/dumb/src/it/readpsm.c
@@ -108,6 +108,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = IT_VIBRATO_SINE;
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
if (flags & 0x80) {
@@ -443,6 +444,8 @@
static void dumb_it_optimize_orders(DUMB_IT_SIGDATA * sigdata);
+static int pattcmp( const unsigned char *, const unsigned char *, size_t );
+
static DUMB_IT_SIGDATA *it_psm_load_sigdata(DUMBFILE *f, int * ver, int subsong)
{
DUMB_IT_SIGDATA *sigdata;
@@ -593,14 +596,14 @@
if (!n_song_chunks) goto error_sc;
+ found = 0;
+
for (n = 0; n < n_song_chunks; n++) {
PSMCHUNK * c = &songchunk[n];
if (c->id == DUMB_ID('D','A','T','E')) {
/* date of the library build / format spec */
- found = 0;
if (c->len == 6) {
- found = 0;
length = c->len;
ptr = c->data;
while (length > 0) {
@@ -790,7 +793,7 @@
length = c->len;
if (found == PSMV_OLD) {
if (length < 8) goto error_ev;
- if (!memcmp(ptr + 4, e->data, 4)) {
+ if (!pattcmp(ptr + 4, e->data, 4)) {
if (it_psm_process_pattern(&sigdata->pattern[n_patterns], ptr, length, speed, bpm, pan, vol, found)) goto error_ev;
if (first_pattern_line < 0) {
first_pattern_line = n;
@@ -803,7 +806,7 @@
}
} else if (found == PSMV_NEW) {
if (length < 12) goto error_ev;
- if (!memcmp(ptr + 4, e->data, 8)) {
+ if (!pattcmp(ptr + 4, e->data, 8)) {
if (it_psm_process_pattern(&sigdata->pattern[n_patterns], ptr, length, speed, bpm, pan, vol, found)) goto error_ev;
if (first_pattern_line < 0) {
first_pattern_line = n;
@@ -1192,6 +1195,52 @@
return subsongs;
}
+
+
+/* Eww */
+int pattcmp( const unsigned char * a, const unsigned char * b, size_t l )
+{
+ int i, j, na, nb;
+ char * p;
+
+ i = memcmp( a, b, l );
+ if ( !i ) return i;
+
+ /* damnit */
+
+ for ( i = 0; i < l; ++i )
+ {
+ if ( a [i] >= '0' && a [i] <= '9' ) break;
+ }
+
+ if ( i < l )
+ {
+ na = strtoul( a + i, &p, 10 );
+ if ( p == a + i ) return 1;
+ }
+
+ for ( j = 0; j < l; ++j )
+ {
+ if ( b [j] >= '0' && b [j] <= '9' ) break;
+ }
+
+ if ( j < l )
+ {
+ nb = strtoul( b + j, &p, 10 );
+ if ( p == b + j ) return -1;
+ }
+
+ if ( i < j ) return -1;
+ else if ( j > i ) return 1;
+
+ i = memcmp( a, b, j );
+ if ( i ) return i;
+
+ return na - nb;
+}
+
+
+
DUH *dumb_read_psm_quick(DUMBFILE *f, int subsong)
{
sigdata_t *sigdata;
@@ -1205,6 +1254,7 @@
return NULL;
{
+ int n_tags = 2;
char version[16];
const char *tag[3][2];
tag[0][0] = "TITLE";
@@ -1211,9 +1261,13 @@
tag[0][1] = ((DUMB_IT_SIGDATA *)sigdata)->name;
tag[1][0] = "FORMAT";
tag[1][1] = "PSM";
- tag[2][0] = "FORMATVERSION";
- itoa(ver, version, 10);
- tag[2][1] = (const char *) &version;
- return make_duh(-1, 3, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
+ if ( ver )
+ {
+ tag[2][0] = "FORMATVERSION";
+ itoa(ver, version, 10);
+ tag[2][1] = (const char *) &version;
+ ++n_tags;
+ }
+ return make_duh(-1, n_tags, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
}
}
--- a/dumb/src/it/readptm.c
+++ b/dumb/src/it/readptm.c
@@ -119,6 +119,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = IT_VIBRATO_SINE;
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
return dumbfile_error(f);
--- a/dumb/src/it/reads3m.c
+++ b/dumb/src/it/reads3m.c
@@ -148,6 +148,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = IT_VIBRATO_SINE;
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
return dumbfile_error(f);
--- a/dumb/src/it/readstm.c
+++ b/dumb/src/it/readstm.c
@@ -84,6 +84,7 @@
sample->vibrato_depth = 0;
sample->vibrato_rate = 0;
sample->vibrato_waveform = IT_VIBRATO_SINE;
+ sample->finetune = 0;
sample->max_resampling_quality = -1;
return dumbfile_error(f);
--- a/dumb/src/it/readxm.c
+++ b/dumb/src/it/readxm.c
@@ -525,7 +525,8 @@
if (dumbfile_error(f))
return -1;
- sample->C5_speed = (long)(16726.0*pow(DUMB_SEMITONE_BASE, relative_note_number)*pow(DUMB_PITCH_BASE, finetune*2));
+ sample->C5_speed = (long)(16726.0*pow(DUMB_SEMITONE_BASE, relative_note_number) /**pow(DUMB_PITCH_BASE, )*/ );
+ sample->finetune = finetune*2;
sample->flags = IT_SAMPLE_EXISTS;