shithub: dumb

Download patch

ref: 243233d3977da6693aeb131dce03c03cd74ead75
parent: a15a906131e89bc8b7fb43dc0c54f704f743d7df
author: Chris Moeller <kode54@gmail.com>
date: Mon Mar 24 13:23:44 EDT 2014

Reworked volume ramping a bit

--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -712,7 +712,7 @@
 	float delta;
 	float target;
 	float mix;
-    unsigned char * declick_stage;
+    unsigned char declick_stage;
 };
 
 void dumb_reset_resampler(DUMB_RESAMPLER *resampler, sample_t *src, int src_channels, long pos, long start, long end, int quality);
--- a/dumb/src/helpers/resample.c
+++ b/dumb/src/helpers/resample.c
@@ -132,32 +132,6 @@
 
 
 
-/* Cubic resampler: look-up tables
- *
- * a = 1.5*x1 - 1.5*x2 + 0.5*x3 - 0.5*x0
- * b = 2*x2 + x0 - 2.5*x1 - 0.5*x3
- * c = 0.5*x2 - 0.5*x0
- * d = x1
- *
- * x = a*t*t*t + b*t*t + c*t + d
- *   = (-0.5*x0 + 1.5*x1 - 1.5*x2 + 0.5*x3) * t*t*t +
- *     (   1*x0 - 2.5*x1 + 2  *x2 - 0.5*x3) * t*t +
- *     (-0.5*x0          + 0.5*x2         ) * t +
- *     (            1*x1                  )
- *   = (-0.5*t*t*t + 1  *t*t - 0.5*t    ) * x0 +
- *     ( 1.5*t*t*t - 2.5*t*t         + 1) * x1 +
- *     (-1.5*t*t*t + 2  *t*t + 0.5*t    ) * x2 +
- *     ( 0.5*t*t*t - 0.5*t*t            ) * x3
- *   = A0(t) * x0 + A1(t) * x1 + A2(t) * x2 + A3(t) * x3
- *
- * A0, A1, A2 and A3 stay within the range [-1,1].
- * In the tables, they are scaled with 14 fractional bits.
- *
- * Turns out we don't need to store A2 and A3; they are symmetrical to A1 and A0.
- *
- * TODO: A0 and A3 stay very small indeed. Consider different scale/resolution?
- */
-
 void _dumb_init_cubic(void)
 {
 	static int done = 0;
--- a/dumb/src/helpers/resample.inc
+++ b/dumb/src/helpers/resample.inc
@@ -114,9 +114,9 @@
 		if ((vol##d < 0 && vol##r <= vol##t) ||                    \
 			(vol##d > 0 && vol##r >= vol##t)) {                    \
 			pvol->volume = pvol->target;                           \
-            if ( *pvol->declick_stage == 0 ||                      \
-                 *pvol->declick_stage >= 3)                        \
-                 (*pvol->declick_stage)++;                         \
+            if ( pvol->declick_stage == 0 ||                       \
+                 pvol->declick_stage >= 3)                         \
+                 pvol->declick_stage++;                            \
 			pvol = NULL;                                           \
 			vol = MULSCV( vol##t, vol##m );                        \
 		} else {                                                   \
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -1799,7 +1799,7 @@
 
 		switch (nna) {
 			case NNA_NOTE_CUT:
-				channel->playing->declick_stage = 2;
+				channel->playing->declick_stage = 3;
 				break;
 			case NNA_NOTE_OFF:
 				it_note_off(channel->playing);
@@ -1848,7 +1848,7 @@
 						switch (playing->instrument->dup_check_action)
 						{
 						case DCA_NOTE_CUT:
-							playing->declick_stage = 2;
+							playing->declick_stage = 3;
 							if (channel->playing == playing) channel->playing = NULL;
 							break;
 						case DCA_NOTE_OFF:
@@ -2786,7 +2786,7 @@
 											IT_PLAYING * playing = sigrenderer->playing[i];
 											if (playing && channel == playing->channel)
 											{
-												playing->declick_stage = 2;
+												playing->declick_stage = 3;
 												if (channel->playing == playing) channel->playing = NULL;
 											}
 										}
@@ -3373,7 +3373,7 @@
 					int i;
 					for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
 						if (!sigrenderer->playing[i]) {
-							channel->playing->declick_stage = 2;
+							channel->playing->declick_stage = 3;
 							sigrenderer->playing[i] = channel->playing;
 							channel->playing = NULL;
 							break;
@@ -3430,7 +3430,7 @@
 				}
 				for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
 					if (!sigrenderer->playing[i]) {
-						channel->playing->declick_stage = 2;
+						channel->playing->declick_stage = 3;
 						sigrenderer->playing[i] = channel->playing;
 						channel->playing = NULL;
 						break;
@@ -3475,7 +3475,7 @@
 				playing = NULL;
 				for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
 					if (!sigrenderer->playing[i]) {
-						ptemp->declick_stage = 2;
+						ptemp->declick_stage = 3;
 						ptemp->flags |= IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING;
 						sigrenderer->playing[i] = ptemp;
 						ptemp = NULL;
@@ -3699,7 +3699,7 @@
 					int i;
 					for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
 						if (!sigrenderer->playing[i]) {
-							channel->playing->declick_stage = 2;
+							channel->playing->declick_stage = 3;
 							sigrenderer->playing[i] = channel->playing;
 							channel->playing = NULL;
 							break;
@@ -3949,16 +3949,14 @@
         playing->ramp_volume[0] = 0;
         playing->ramp_volume[1] = 0;
         rampScale = 48;
-    } else if (playing->declick_stage == 2) {
-        playing->ramp_volume[0] = playing->float_volume[0];
-        playing->ramp_volume[1] = playing->float_volume[1];
-        playing->float_volume[0] = 0;
-        playing->float_volume[1] = 0;
         playing->declick_stage++;
+    } else if (playing->declick_stage == 1) {
         rampScale = 48;
     } else if (playing->declick_stage >= 3) {
         playing->float_volume[0] = 0;
         playing->float_volume[1] = 0;
+        if (playing->declick_stage == 3)
+            playing->declick_stage++;
         rampScale = 48;
     }
     playing->ramp_delta[0] = rampScale * invt2g * (playing->float_volume[0] - playing->ramp_volume[0]);
@@ -4175,7 +4173,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) ||
-                    (sigrenderer->channel[i].playing->declick_stage > 3)) {
+                    (sigrenderer->channel[i].playing->declick_stage > 4)) {
 					free_playing(sigrenderer->channel[i].playing);
 					sigrenderer->channel[i].playing = NULL;
 				}
@@ -4187,7 +4185,7 @@
 		if (sigrenderer->playing[i]) {
 			process_playing(sigrenderer, sigrenderer->playing[i], invt2g);
 			if ((sigrenderer->playing[i]->flags & IT_PLAYING_DEAD) ||
-                (sigrenderer->playing[i]->declick_stage > 3)) {
+                (sigrenderer->playing[i]->declick_stage > 4)) {
 				free_playing(sigrenderer->playing[i]);
 				sigrenderer->playing[i] = NULL;
 			}
@@ -4679,7 +4677,7 @@
 		lvol.target = playing->float_volume [0];
 		rvol.target = playing->float_volume [1];
 		rvol.mix = lvol.mix = volume;
-        lvol.declick_stage = rvol.declick_stage = &(playing->declick_stage);
+        lvol.declick_stage = rvol.declick_stage = playing->declick_stage;
 		if (sigrenderer->n_channels >= 2) {
 			if (playing->sample->flags & IT_SAMPLE_STEREO) {
 				if (sigrenderer->click_remover) {
@@ -4755,6 +4753,7 @@
 		}
 		playing->ramp_volume [0] = lvol.volume;
 		playing->ramp_volume [1] = rvol.volume;
+        playing->declick_stage = (lvol.declick_stage > rvol.declick_stage) ? lvol.declick_stage : rvol.declick_stage;
 		(*left_to_mix)--;
 	}
 
@@ -4944,10 +4943,7 @@
 		if (sigrenderer->channel[i].playing) {
 			//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 (
-#ifdef RAMP_DOWN
-			(sigrenderer->channel[i].playing->declick_stage == 3) || 
-#endif
+			if ((sigrenderer->channel[i].playing->declick_stage > 4) ||
 			(sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD)) {
 				free_playing(sigrenderer->channel[i].playing);
 				sigrenderer->channel[i].playing = NULL;
@@ -4957,10 +4953,7 @@
 
 	for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
 		if (sigrenderer->playing[i]) {
-			if (
-#ifdef RAMP_DOWN
-				(sigrenderer->playing[i]->declick_stage == 3) ||
-#endif
+			if ((sigrenderer->playing[i]->declick_stage > 4) ||
 				(sigrenderer->playing[i]->flags & IT_PLAYING_DEAD)) {
 				free_playing(sigrenderer->playing[i]);
 				sigrenderer->playing[i] = NULL;
@@ -5105,10 +5098,7 @@
 		if (sigrenderer->channel[i].playing) {
 			//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 (
-#ifdef RAMP_DOWN
-			(sigrenderer->channel[i].playing->declick_stage == 3) || 
-#endif
+			if ((sigrenderer->channel[i].playing->declick_stage > 4) ||
 			(sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD)) {
 				free_playing(sigrenderer->channel[i].playing);
 				sigrenderer->channel[i].playing = NULL;
@@ -5118,10 +5108,7 @@
 
 	for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
 		if (sigrenderer->playing[i]) {
-			if (
-#ifdef RAMP_DOWN
-				(sigrenderer->playing[i]->declick_stage == 3) ||
-#endif
+			if ((sigrenderer->playing[i]->declick_stage > 4) ||
 				(sigrenderer->playing[i]->flags & IT_PLAYING_DEAD)) {
 				free_playing(sigrenderer->playing[i]);
 				sigrenderer->playing[i] = NULL;