ref: 9ac6cf69758fe0db6d6e654f298cd36efdb73366
parent: 4c0d2d92e6cc5c607a145f9fcbc8903e39327d1f
author: Chris Moeller <[email protected]>
date: Sun Jan 9 09:16:37 EST 2011
- Replaced old aliased resampling mode with a 65536x oversampling sinc resampler - Version is now 0.9.9.23 git-tfs-id: [http://localhost:8080/tfs/DefaultCollection/]$/foobar2000/files/plugins.root;C539
--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -650,6 +650,8 @@
typedef void (*DUMB_RESAMPLE_PICKUP)(DUMB_RESAMPLER *resampler, void *data);
+#include "internal/blip_buf.h"
+
struct DUMB_RESAMPLER
{
void *src;
@@ -667,6 +669,9 @@
signed char x8[3*2];
} x;
int overshot;
+ int last_clock;
+ int last_amp[2];
+ blip_t* blip_buffer[2];
};
struct DUMB_VOLUME_RAMP_INFO
--- a/dumb/src/helpers/resamp2.inc
+++ b/dumb/src/helpers/resamp2.inc
@@ -94,7 +94,8 @@
#define SET_VOLUME_VARIABLES SET_MONO_DEST_VOLUME_VARIABLES
#define RETURN_VOLUME_VARIABLES RETURN_MONO_DEST_VOLUME_VARIABLES
#define VOLUMES_ARE_ZERO MONO_DEST_VOLUMES_ARE_ZERO
-#define MIX_ALIAS(op, upd, offset) MONO_DEST_MIX_ALIAS(op, upd, offset)
+#define MIX_ALIAS(count) MONO_DEST_MIX_ALIAS(count)
+#define PEEK_ALIAS MONO_DEST_PEEK_ALIAS
#define MIX_LINEAR(op, upd, o0, o1) MONO_DEST_MIX_LINEAR(op, upd, o0, o1)
#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3)
#define MIX_ZEROS(op) *dst++ op 0
@@ -133,7 +134,8 @@
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)
+#define MIX_ALIAS(count) STEREO_DEST_MIX_ALIAS(count)
+#define PEEK_ALIAS STEREO_DEST_PEEK_ALIAS
#define MIX_LINEAR(op, upd, o0, o1) STEREO_DEST_MIX_LINEAR(op, upd, o0, o1)
#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3)
#define MIX_ZEROS(op) { *dst++ op 0; *dst++ op 0; }
@@ -153,6 +155,9 @@
#undef MONO_DEST_VOLUME_ZEROS
#undef MONO_DEST_VOLUME_VARIABLES
#undef MONO_DEST_VOLUME_PARAMETERS
+#undef STEREO_DEST_PEEK_ALIAS
+#undef MONO_DEST_PEEK_ALIAS
+#undef POKE_ALIAS
#undef COPYSRC2
#undef COPYSRC
#undef DIVIDE_BY_SRC_CHANNELS
--- a/dumb/src/helpers/resamp3.inc
+++ b/dumb/src/helpers/resamp3.inc
@@ -46,12 +46,13 @@
long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, VOLUME_PARAMETERS, float delta)
{
- int dt;
+ int dt, inv_dt;
int VOLUME_VARIABLES;
long done;
long todo;
LONG_LONG todo64;
int quality;
+ int blip_samples[256*SRC_CHANNELS];
if (!resampler || resampler->dir == 0) return 0;
ASSERT(resampler->dir == -1 || resampler->dir == 1);
@@ -59,6 +60,7 @@
done = 0;
dt = (int)(delta * 65536.0 + 0.5);
if (dt == 0 || dt == 0x80000000) return 0;
+ inv_dt = (int)(1.0 / delta * 65536.0 + 0.5);
SET_VOLUME_VARIABLES;
if (VOLUMES_ARE_ZERO) dst = NULL;
@@ -104,29 +106,34 @@
subpos = (long)new_subpos & 65535;
} else if (quality <= DUMB_RQ_ALIASING) {
/* Aliasing, backwards */
+ int todo_clocks = todo << 16, todo_clocks_set = todo_clocks;
SRCTYPE xbuf[2*SRC_CHANNELS];
SRCTYPE *x = &xbuf[0];
- SRCTYPE *xstart;
COPYSRC(xbuf, 0, resampler->X, 1);
COPYSRC(xbuf, 1, resampler->X, 2);
- while (todo && x < &xbuf[2*SRC_CHANNELS]) {
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) {
// TODO: check what happens when multiple tempo slides occur per row
HEAVYASSERT(pos >= resampler->start);
- MIX_ALIAS(+=, 1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x -= (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
+ POKE_ALIAS(0);
+ pos--;
+ x += SRC_CHANNELS;
}
- x = xstart = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- MIX_ALIAS(+=, 1, 2);
- subpos += dt;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- pos += DIVIDE_BY_SRC_CHANNELS(x - xstart);
+ x = &src[pos*SRC_CHANNELS];
+ while ( todo_clocks ) {
+ todo_clocks_set = todo_clocks;
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ todo_clocks -= todo_clocks_set;
+ todo = ( todo_clocks_set - resampler->last_clock + inv_dt - 1 ) / inv_dt;
+ if ( todo < 0 ) todo = 0;
+ LOOP4(todo,
+ POKE_ALIAS(2);
+ pos--;
+ x -= SRC_CHANNELS;
+ );
+ todo = todo_clocks_set >> 16;
+ MIX_ALIAS( todo );
+ }
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, backwards */
SRCTYPE xbuf[3*SRC_CHANNELS];
@@ -205,28 +212,33 @@
subpos = (long)new_subpos & 65535;
} else if (quality <= DUMB_RQ_ALIASING) {
/* Aliasing, forwards */
+ int todo_clocks = todo << 16, todo_clocks_set = todo_clocks;
SRCTYPE xbuf[2*SRC_CHANNELS];
SRCTYPE *x = &xbuf[0];
- SRCTYPE *xstart;
COPYSRC(xbuf, 0, resampler->X, 1);
COPYSRC(xbuf, 1, resampler->X, 2);
- while (todo && x < &xbuf[2*SRC_CHANNELS]) {
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) {
HEAVYASSERT(pos < resampler->end);
- MIX_ALIAS(+=, 1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
+ POKE_ALIAS(0);
+ pos++;
+ x += SRC_CHANNELS;
}
- x = xstart = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- MIX_ALIAS(+=, 1, -2);
- subpos += dt;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- pos += DIVIDE_BY_SRC_CHANNELS(x - xstart);
+ x = &src[pos*SRC_CHANNELS];
+ while ( todo_clocks ) {
+ todo_clocks_set = todo_clocks;
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ todo_clocks -= todo_clocks_set;
+ todo = ( todo_clocks_set - resampler->last_clock + inv_dt - 1 ) / inv_dt;
+ if ( todo < 0 ) todo = 0;
+ LOOP4(todo,
+ POKE_ALIAS(-2);
+ pos++;
+ x += SRC_CHANNELS;
+ );
+ todo = todo_clocks_set >> 16;
+ MIX_ALIAS( todo );
+ }
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, forwards */
SRCTYPE xbuf[3*SRC_CHANNELS];
@@ -339,7 +351,7 @@
HEAVYASSERT(pos >= resampler->start);
if (quality <= DUMB_RQ_ALIASING) {
/* Aliasing, backwards */
- MIX_ALIAS(=, 0, 1);
+ PEEK_ALIAS;
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, backwards */
MIX_LINEAR(=, 0, 2, 1);
@@ -351,7 +363,7 @@
HEAVYASSERT(pos < resampler->end);
if (quality <= DUMB_RQ_ALIASING) {
/* Aliasing */
- MIX_ALIAS(=, 0, 1);
+ PEEK_ALIAS;
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, forwards */
MIX_LINEAR(=, 0, 1, 2);
@@ -368,6 +380,7 @@
#undef MIX_CUBIC
#undef MIX_LINEAR
#undef MIX_ALIAS
+#undef PEEK_ALIAS
#undef VOLUMES_ARE_ZERO
#undef SET_VOLUME_VARIABLES
#undef RETURN_VOLUME_VARIABLES
--- a/dumb/src/helpers/resample.c
+++ b/dumb/src/helpers/resample.c
@@ -176,7 +176,7 @@
#define SRCTYPE sample_t
#define SRCBITS 24
-#define ALIAS(x, vol) MULSC(x, vol)
+#define ALIAS(x) (x >> 8)
#define LINEAR(x0, x1) (x0 + MULSC(x1 - x0, subpos))
/*
#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
@@ -212,7 +212,7 @@
#define SUFFIX _16
#define SRCTYPE short
#define SRCBITS 16
-#define ALIAS(x, vol) (x * vol >> 8)
+#define ALIAS(x) (x)
#define LINEAR(x0, x1) ((x0 << 8) + MULSC16(x1 - x0, subpos))
/*
#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
@@ -234,7 +234,7 @@
#define SUFFIX _8
#define SRCTYPE signed char
#define SRCBITS 8
-#define ALIAS(x, vol) (x * vol)
+#define ALIAS(x) (x << 8)
#define LINEAR(x0, x1) ((x0 << 16) + (x1 - x0) * subpos)
/*
#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
--- a/dumb/src/helpers/resample.inc
+++ b/dumb/src/helpers/resample.inc
@@ -69,6 +69,11 @@
}
for (i = 0; i < src_channels*3; i++) resampler->X[i] = 0;
resampler->overshot = -1;
+ resampler->last_clock = 0;
+ resampler->last_amp[0] = 0;
+ resampler->last_amp[1] = 0;
+ blip_clear(resampler->blip_buffer[0]);
+ blip_clear(resampler->blip_buffer[1]);
}
@@ -77,6 +82,21 @@
{
DUMB_RESAMPLER *resampler = malloc(sizeof(*resampler));
if (!resampler) return NULL;
+ resampler->blip_buffer[0] = blip_new( 256 );
+ if (!resampler->blip_buffer[0])
+ {
+ free(resampler);
+ return NULL;
+ }
+ resampler->blip_buffer[1] = blip_new( 256 );
+ if (!resampler->blip_buffer[1])
+ {
+ free(resampler->blip_buffer[0]);
+ free(resampler);
+ return NULL;
+ }
+ blip_set_rates(resampler->blip_buffer[0], 65536, 1);
+ blip_set_rates(resampler->blip_buffer[1], 65536, 1);
dumb_reset_resampler(resampler, src, src_channels, pos, start, end, quality);
return resampler;
}
@@ -123,17 +143,42 @@
}
#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); \
- if ( upd ) UPDATE_VOLUME( volume, vol ); \
+#define POKE_ALIAS(offset) { \
+ int delta = ALIAS(x[offset]) - resampler->last_amp[0]; \
+ resampler->last_amp[0] += delta; \
+ if ( delta ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, delta ); \
+ resampler->last_clock += inv_dt; \
}
-#define STEREO_DEST_MIX_ALIAS(op, upd, offset) { \
- int xm = x[offset]; \
- *dst++ op ALIAS(xm, lvol); \
- *dst++ op ALIAS(xm, rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
+#define MONO_DEST_PEEK_ALIAS *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), vol )
+#define MONO_DEST_MIX_ALIAS(count) { \
+ int n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ LOOP4( count, \
+ *dst++ += MULSC( blip_samples[n], vol ); \
+ n++; \
+ UPDATE_VOLUME( volume, vol ); \
+ ); \
}
+#define STEREO_DEST_PEEK_ALIAS { \
+ int sample = blip_peek_sample( resampler->blip_buffer[0] ); \
+ *dst++ = MULSC( sample, lvol ); \
+ *dst++ = MULSC( sample, rvol ); \
+}
+#define STEREO_DEST_MIX_ALIAS(count) { \
+ int sample, n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ LOOP4( count, \
+ sample = blip_samples[n++]; \
+ *dst++ += MULSC( sample, lvol ); \
+ *dst++ += MULSC( sample, rvol ); \
+ UPDATE_VOLUME( volume_left, lvol ); \
+ UPDATE_VOLUME( volume_right, rvol ); \
+ ); \
+}
#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
*dst++ op MULSC(LINEAR(x[o0], x[o1]), vol); \
if ( upd ) UPDATE_VOLUME( volume, vol ); \
@@ -208,16 +253,51 @@
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) { \
- *dst++ op ALIAS(x[(offset)*2], lvol) + ALIAS(x[(offset)*2+1], rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
+#define POKE_ALIAS(offset) { \
+ int deltal = ALIAS(x[(offset)*2+0]) - resampler->last_amp[0]; \
+ int deltar = ALIAS(x[(offset)*2+1]) - resampler->last_amp[1]; \
+ resampler->last_amp[0] += deltal; \
+ resampler->last_amp[1] += deltar; \
+ if ( deltal ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, deltal ); \
+ if ( deltar ) blip_add_delta( resampler->blip_buffer[1], resampler->last_clock, deltar ); \
+ resampler->last_clock += inv_dt; \
}
-#define STEREO_DEST_MIX_ALIAS(op, upd, offset) { \
- *dst++ op ALIAS(x[(offset)*2], lvol); \
- *dst++ op ALIAS(x[(offset)*2+1], rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
+#define MONO_DEST_PEEK_ALIAS { \
+ *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ) + \
+ MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
+}
+#define MONO_DEST_MIX_ALIAS(count) { \
+ int n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \
+ LOOP4( count, \
+ *dst++ += MULSC( blip_samples[n], lvol ) + MULSC( blip_samples[256+n], rvol ); \
+ n++; \
+ UPDATE_VOLUME( volume_left, lvol ); \
+ UPDATE_VOLUME( volume_right, rvol ); \
+ ); \
+}
+#define STEREO_DEST_PEEK_ALIAS { \
+ *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ); \
+ *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
+}
+#define STEREO_DEST_MIX_ALIAS(count) { \
+ int n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \
+ LOOP4( count, \
+ *dst++ += MULSC( blip_samples[n], lvol); \
+ *dst++ += MULSC( blip_samples[256+n], rvol); \
+ n++; \
+ UPDATE_VOLUME( volume_left, lvol ); \
+ UPDATE_VOLUME( volume_right, rvol ); \
+ ); \
}
#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
*dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol) + MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -29,6 +29,37 @@
#define END_RAMPING
#define RAMP_DOWN
+static IT_PLAYING *new_playing()
+{
+ IT_PLAYING * r = (IT_PLAYING*) malloc(sizeof(*r));
+ if (r)
+ {
+ r->resampler.blip_buffer[0] = blip_new( 256 );
+ if ( !r->resampler.blip_buffer[0] )
+ {
+ free( r );
+ return NULL;
+ }
+ r->resampler.blip_buffer[1] = blip_new( 256 );
+ if ( !r->resampler.blip_buffer[1] )
+ {
+ free( r->resampler.blip_buffer[0] );
+ free( r );
+ return NULL;
+ }
+ blip_set_rates(r->resampler.blip_buffer[0], 65536, 1);
+ blip_set_rates(r->resampler.blip_buffer[1], 65536, 1);
+ }
+ return r;
+}
+
+static void free_playing(IT_PLAYING * r)
+{
+ blip_delete( r->resampler.blip_buffer[1] );
+ blip_delete( r->resampler.blip_buffer[0] );
+ free( r );
+}
+
static IT_PLAYING *dup_playing(IT_PLAYING *src, IT_CHANNEL *dstchannel, IT_CHANNEL *srcchannel)
{
IT_PLAYING *dst;
@@ -118,6 +149,19 @@
dst->resampler = src->resampler;
dst->resampler.pickup_data = dst;
+ dst->resampler.blip_buffer[0] = blip_dup( dst->resampler.blip_buffer[0] );
+ if ( !dst->resampler.blip_buffer[0] )
+ {
+ free( dst );
+ return NULL;
+ }
+ dst->resampler.blip_buffer[1] = blip_dup( dst->resampler.blip_buffer[1] );
+ if ( !dst->resampler.blip_buffer[1] )
+ {
+ blip_delete( dst->resampler.blip_buffer[0] );
+ free( dst );
+ return NULL;
+ }
dst->time_lost = src->time_lost;
//dst->output = src->output;
@@ -1472,7 +1516,7 @@
#ifdef RAMP_DOWN
channel->playing->declick_stage = 2;
#else
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
#endif
break;
@@ -1526,7 +1570,7 @@
#ifdef RAMP_DOWN
playing->declick_stage = 2;
#else
- free(playing);
+ free_playing(playing);
sigrenderer->playing[i] = NULL;
#endif
if (channel->playing == playing) channel->playing = NULL;
@@ -1561,9 +1605,9 @@
}
if (channel->playing)
- free(channel->playing);
+ free_playing(channel->playing);
- channel->playing = malloc(sizeof(*channel->playing));
+ channel->playing = new_playing();
if (!channel->playing)
return;
@@ -2372,7 +2416,7 @@
#ifdef RAMP_DOWN
playing->declick_stage = 2;
#else
- free(playing);
+ free_playing(playing);
sigrenderer->playing[i] = NULL;
#endif
if (channel->playing == playing) channel->playing = NULL;
@@ -2870,10 +2914,8 @@
{
DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
- IT_PLAYING playing;
+ IT_PLAYING * playing = NULL;
- playing.sample = 0;
-
if (entry->mask & IT_ENTRY_INSTRUMENT) {
int oldsample = channel->sample;
int oldvolume = channel->volume;
@@ -2882,7 +2924,8 @@
if (channel->playing &&
!((entry->mask & IT_ENTRY_NOTE) && entry->note >= 120) &&
!((entry->mask & IT_ENTRY_EFFECT) && entry->effect == IT_XM_KEY_OFF && entry->effectvalue == 0)) {
- playing = *channel->playing;
+ playing = dup_playing(channel->playing, channel, channel);
+ if (!playing) return;
if (!(sigdata->flags & IT_WAS_A_MOD)) {
/* Retrigger vol/pan envelopes if enabled, and cancel fadeout.
* Also reset vol/pan to that of _original_ instrument.
@@ -2911,21 +2954,20 @@
if (!channel->sample) {
if (channel->playing)
{
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
}
} else {
- if (!channel->playing) {
- channel->playing = malloc(sizeof(*channel->playing));
- if (!channel->playing) return;
+ if (channel->playing) {
+ free_playing(channel->playing);
}
- *channel->playing = playing;
- playing.sample = (IT_SAMPLE *)-1;
+ channel->playing = playing;
+ playing = NULL;
channel->playing->declick_stage = 0;
channel->playing->declick_volume = 1.f / 256.f;
#else
if (!channel->sample) {
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
} else {
#endif
@@ -2966,7 +3008,11 @@
if (channel->playing) {
#ifdef RAMP_DOWN
int i;
- if (playing.sample) *channel->playing = playing;
+ if (playing) {
+ free_playing(channel->playing);
+ channel->playing = playing;
+ playing = NULL;
+ }
for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (!sigrenderer->playing[i]) {
channel->playing->declick_stage = 2;
@@ -2976,14 +3022,15 @@
}
}
if (channel->playing) {
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
}
#else
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
#endif
}
+ if (playing) free_playing(playing);
return;
} else if (channel->playing && (entry->mask & IT_ENTRY_VOLPAN) && ((entry->volpan>>4) == 0xF)) {
/* Don't retrigger note; portamento in the volume column. */
@@ -2996,20 +3043,26 @@
channel->destnote = IT_NOTE_OFF;
if (!channel->playing) {
- channel->playing = malloc(sizeof(*channel->playing));
- if (!channel->playing)
+ channel->playing = new_playing();
+ if (!channel->playing) {
+ if (playing) free_playing(playing);
return;
+ }
// Adding the following seems to do the trick for the case where a piece starts with an instrument alone and then some notes alone.
retrigger_xm_envelopes(channel->playing);
}
#ifdef RAMP_DOWN
- else if (playing.sample != (IT_SAMPLE *)-1) {
+ else if (playing) {
/* volume rampy stuff! move note to NNA */
int i;
- IT_PLAYING * ptemp = malloc(sizeof(*channel->playing));
- if (!ptemp) return;
- if (playing.sample) *ptemp = playing;
- else *ptemp = *channel->playing;
+ IT_PLAYING * ptemp;
+ if (playing->sample) ptemp = playing;
+ else ptemp = channel->playing;
+ if (!ptemp) {
+ if (playing) free_playing(playing);
+ return;
+ }
+ playing = NULL;
for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (!sigrenderer->playing[i]) {
ptemp->declick_stage = 2;
@@ -3019,7 +3072,7 @@
break;
}
}
- if (ptemp) free(ptemp);
+ if (ptemp) free_playing(ptemp);
}
#endif
@@ -3170,6 +3223,8 @@
break;
}
}
+
+ if (playing) free_playing(playing);
}
@@ -3247,11 +3302,11 @@
}
}
if (channel->playing) {
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
}
#else
- free(channel->playing);
+ free_playing(channel->playing);
channel->playing = NULL;
#endif
}
@@ -3708,7 +3763,7 @@
//if ((sigrenderer->channel[i].playing->flags & (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) == (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) {
// This change was made so Gxx would work correctly when a note faded out or whatever. Let's hope nothing else was broken by it.
if (sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD) {
- free(sigrenderer->channel[i].playing);
+ free_playing(sigrenderer->channel[i].playing);
sigrenderer->channel[i].playing = NULL;
}
}
@@ -3719,7 +3774,7 @@
if (sigrenderer->playing[i]) {
process_playing(sigrenderer, sigrenderer->playing[i], invt2g);
if (sigrenderer->playing[i]->flags & IT_PLAYING_DEAD) {
- free(sigrenderer->playing[i]);
+ free_playing(sigrenderer->playing[i]);
sigrenderer->playing[i] = NULL;
}
}
@@ -4728,7 +4783,7 @@
(sigrenderer->channel[i].playing->declick_stage == 3) ||
#endif
(sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD)) {
- free(sigrenderer->channel[i].playing);
+ free_playing(sigrenderer->channel[i].playing);
sigrenderer->channel[i].playing = NULL;
}
}
@@ -4741,7 +4796,7 @@
(sigrenderer->playing[i]->declick_stage == 3) ||
#endif
(sigrenderer->playing[i]->flags & IT_PLAYING_DEAD)) {
- free(sigrenderer->playing[i]);
+ free_playing(sigrenderer->playing[i]);
sigrenderer->playing[i] = NULL;
}
}
@@ -5144,7 +5199,7 @@
if (sigrenderer) {
for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
if (sigrenderer->channel[i].playing)
- free(sigrenderer->channel[i].playing);
+ free_playing(sigrenderer->channel[i].playing);
#ifdef BIT_ARRAY_BULLSHIT
bit_array_destroy(sigrenderer->channel[i].played_patjump);
#endif
@@ -5152,7 +5207,7 @@
for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++)
if (sigrenderer->playing[i])
- free(sigrenderer->playing[i]);
+ free_playing(sigrenderer->playing[i]);
dumb_destroy_click_remover_array(sigrenderer->n_channels, sigrenderer->click_remover);
--- a/dumb/vc6/dumb/dumb.vcxproj
+++ b/dumb/vc6/dumb/dumb.vcxproj
@@ -306,6 +306,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
+ <ClCompile Include="..\..\src\helpers\blip_buf.c" />
<ClCompile Include="..\..\src\helpers\clickrem.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -710,6 +711,7 @@
<ItemGroup>
<ClInclude Include="..\..\include\dumb.h" />
<ClInclude Include="..\..\include\internal\barray.h" />
+ <ClInclude Include="..\..\include\internal\blip_buf.h" />
<ClInclude Include="..\..\include\internal\dumb.h" />
<ClInclude Include="..\..\include\internal\it.h" />
<ClInclude Include="..\..\include\internal\riff.h" />
--- a/dumb/vc6/dumb/dumb.vcxproj.filters
+++ b/dumb/vc6/dumb/dumb.vcxproj.filters
@@ -249,6 +249,9 @@
<ClCompile Include="..\..\src\it\xmeffect.c">
<Filter>src\it</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\helpers\blip_buf.c">
+ <Filter>src\helpers</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\dumb.h">
@@ -266,12 +269,15 @@
<ClInclude Include="..\..\include\internal\riff.h">
<Filter>include\internal</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\internal\blip_buf.h">
+ <Filter>include\internal</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
- <CustomBuild Include="..\..\src\helpers\resamp2.inc">
+ <CustomBuild Include="..\..\src\helpers\resamp3.inc">
<Filter>src\helpers</Filter>
</CustomBuild>
- <CustomBuild Include="..\..\src\helpers\resamp3.inc">
+ <CustomBuild Include="..\..\src\helpers\resamp2.inc">
<Filter>src\helpers</Filter>
</CustomBuild>
<CustomBuild Include="..\..\src\helpers\resample.inc">