shithub: ft2-clone

Download patch

ref: 4e1aaeb982ef59dc209047651ef578f96963f03b
parent: f8c0ccfded8a6d486a63061a31e39156332a21c7
author: Olav Sørensen <olav.sorensen@live.no>
date: Thu May 21 10:45:39 EDT 2020

Fix XFade bug on 16-bit pingpong samples

This bug was accidentally ported over from the original FT2 code.

--- a/src/ft2_header.h
+++ b/src/ft2_header.h
@@ -12,7 +12,7 @@
 #endif
 #include "ft2_replayer.h"
 
-#define PROG_VER_STR "1.24"
+#define PROG_VER_STR "1.25"
 
 // do NOT change these! It will only mess things up...
 
--- a/src/ft2_sample_ed.c
+++ b/src/ft2_sample_ed.c
@@ -254,7 +254,7 @@
 	}
 }
 
-inline int16_t getSampleValueNr(int8_t *ptr, uint8_t typ, int32_t pos)
+inline int16_t getSampleValue(int8_t *ptr, uint8_t typ, int32_t pos)
 {
 	assert(pos >= 0);
 	if (ptr == NULL)
@@ -271,7 +271,7 @@
 	}
 }
 
-inline void putSampleValueNr(int8_t *ptr, uint8_t typ, int32_t pos, int16_t val)
+inline void putSampleValue(int8_t *ptr, uint8_t typ, int32_t pos, int16_t val)
 {
 	assert(pos >= 0);
 	if (ptr == NULL)
@@ -2178,7 +2178,7 @@
 
 			if (x2 <= y1 || x2 >= s->repS+s->repL)
 			{
-				okBox(0, "System message", "Not enough sample data outside loop!");
+				okBox(0, "System message", "Invalid range!");
 				return;
 			}
 
@@ -2189,21 +2189,25 @@
 			d2 = y1 - x1;
 			d3 = x2 - y1;
 
-			if (d1 < 1 || d2 < 1 || d3 < 1)
+			if (d1 < 2 || d2 < 2 || d3 < 2)
 			{
-				okBox(0, "System message", "Not enough sample data outside loop!");
+				okBox(0, "System message", "Invalid range!");
 				return;
 			}
 
 			if (y1-d1 < 0 || y1+d1 >= s->len)
 			{
-				okBox(0, "System message", "Invalid range!");
+				okBox(0, "System message", "Not enough sample data outside loop!");
 				return;
 			}
 
-			dist = 1;
 			if (is16Bit)
-				dist++;
+			{
+				y1 >>= 1;
+				d1 >>= 1;
+				d2 >>= 1;
+				d3 >>= 1;
+			}
 
 			pauseAudio();
 			restoreSample(s);
@@ -2211,8 +2215,8 @@
 			i = 0;
 			while (i < d1)
 			{
-				a = getSampleValueNr(s->pek, t, y1 + dist * (-i - 1));
-				b = getSampleValueNr(s->pek, t, y1 + dist * i);
+				a = getSampleValue(s->pek, t, (y1 - i - 1) << is16Bit);
+				b = getSampleValue(s->pek, t, (y1 + i) << is16Bit);
 
 				dS1 = 1.0 - i / (double)d2; dS2 = 2.0 - dS1;
 				dS3 = 1.0 - i / (double)d3; dS4 = 2.0 - dS3;
@@ -2223,10 +2227,10 @@
 				tmp32 = (int32_t)round((b * dS4 + a * dS3) / (dS3 + dS4));
 				d = (int16_t)tmp32;
 
-				if (i < d2) putSampleValueNr(s->pek, t, y1 + dist * (-i - 1), c);
-				if (i < d3) putSampleValueNr(s->pek, t, y1 + dist * i, d);
+				if (i < d2) putSampleValue(s->pek, t, (y1 - i - 1) << is16Bit, c);
+				if (i < d3) putSampleValue(s->pek, t, (y1 + i) << is16Bit, d);
 
-				i += dist;
+				i++;
 			}
 
 			fixSample(s);
@@ -2239,7 +2243,7 @@
 			y1 += s->repL;
 			if (x1 >= y1 || x2 <= y1 || x2 >= s->len)
 			{
-				okBox(0, "System message", "Not enough sample data outside loop!");
+				okBox(0, "System message", "Invalid range!");
 				return;
 			}
 
@@ -2250,19 +2254,25 @@
 			d2 = y1 - x1;
 			d3 = x2 - y1;
 
-			if (d1 < 1 || d2 < 1 || d3 < 1)
+			if (d1 < 2 || d2 < 2 || d3 < 2)
 			{
-				okBox(0, "System message", "Not enough sample data outside loop!");
+				okBox(0, "System message", "Invalid range!");
 				return;
 			}
 
 			if (y1-d1 < 0 || y1+d1 >= s->len)
 			{
-				okBox(0, "System message", "Invalid range!");
+				okBox(0, "System message", "Not enough sample data outside loop!");
 				return;
 			}
 
-			dist = is16Bit ? 2 : 1;
+			if (is16Bit)
+			{
+				y1 >>= 1;
+				d1 >>= 1;
+				d2 >>= 1;
+				d3 >>= 1;
+			}
 
 			pauseAudio();
 			restoreSample(s);
@@ -2270,8 +2280,8 @@
 			i = 0;
 			while (i < d1)
 			{
-				a = getSampleValueNr(s->pek, t, y1 - i - dist);
-				b = getSampleValueNr(s->pek, t, y1 + i);
+				a = getSampleValue(s->pek, t, (y1 - i - 1) << is16Bit);
+				b = getSampleValue(s->pek, t, (y1 + i) << is16Bit);
 
 				dS1 = 1.0 - i / (double)d2; dS2 = 2.0 - dS1;
 				dS3 = 1.0 - i / (double)d3; dS4 = 2.0 - dS3;
@@ -2282,10 +2292,10 @@
 				tmp32 = (int32_t)round((b * dS4 + a * dS3) / (dS3 + dS4));
 				d = (int16_t)tmp32;
 
-				if (i < d2) putSampleValueNr(s->pek, t, y1 - i - dist, c);
-				if (i < d3) putSampleValueNr(s->pek, t, y1 + i, d);
+				if (i < d2) putSampleValue(s->pek, t, (y1 - i - 1) << is16Bit, c);
+				if (i < d3) putSampleValue(s->pek, t, (y1 + i) << is16Bit, d);
 
-				i += dist;
+				i++;
 			}
 
 			fixSample(s);
@@ -2304,11 +2314,11 @@
 
 		if (x1 < 0 || x2 <= x1 || x2 >= s->len)
 		{
-			okBox(0, "System message", "Not enough sample data outside loop!");
+			okBox(0, "System message", "Invalid range!");
 			return;
 		}
 
-		i = (x2 - x1 + 1) / 2;
+		i = (x2 - x1 + 1) >> 1;
 		y1 = s->repS - i;
 		y2 = s->repS + s->repL - i;
 
@@ -2320,7 +2330,7 @@
 
 		if (y1 < 0 || y2+(x2-x1) >= s->len)
 		{
-			okBox(0, "System message", "Invalid range!");
+			okBox(0, "System message", "Not enough sample data outside loop!");
 			return;
 		}
 
@@ -2330,7 +2340,7 @@
 
 		if (y1+(x2-x1) <= s->repS || d1 == 0 || d3 == 0 || d1 > s->repL)
 		{
-			okBox(0, "System message", "Not enough sample data outside loop!");
+			okBox(0, "System message", "Invalid range!");
 			return;
 		}
 
@@ -2343,8 +2353,8 @@
 		i = 0;
 		while (i < x2-x1)
 		{
-			a = getSampleValueNr(s->pek, t, y1 + i);
-			b = getSampleValueNr(s->pek, t, y2 + i);
+			a = getSampleValue(s->pek, t, y1 + i);
+			b = getSampleValue(s->pek, t, y2 + i);
 
 			dS2 = i / (double)d1;
 			dS1 = 1.0 - dS2;
@@ -2372,8 +2382,8 @@
 				d = (int16_t)tmp32;
 			}
 
-			putSampleValueNr(s->pek, t, y1 + i, c);
-			putSampleValueNr(s->pek, t, y2 + i, d);
+			putSampleValue(s->pek, t, y1 + i, c);
+			putSampleValue(s->pek, t, y2 + i, d);
 
 			i += dist;
 		}
--- a/src/ft2_sample_ed.h
+++ b/src/ft2_sample_ed.h
@@ -48,8 +48,8 @@
 void sampRepeatDown(void);
 void sampReplenUp(void);
 void sampReplenDown(void);
-int16_t getSampleValueNr(int8_t *ptr, uint8_t typ, int32_t pos);
-void putSampleValueNr(int8_t *ptr, uint8_t typ, int32_t pos, int16_t val);
+int16_t getSampleValue(int8_t *ptr, uint8_t typ, int32_t pos);
+void putSampleValue(int8_t *ptr, uint8_t typ, int32_t pos, int16_t val);
 void writeSample(bool forceSmpRedraw);
 void handleSampleDataMouseDown(bool mouseButtonHeld);
 void updateSampleEditorSample(void);
--- a/src/ft2_sample_ed_features.c
+++ b/src/ft2_sample_ed_features.c
@@ -987,8 +987,8 @@
 	{
 		int32_t index16 = i << 1;
 
-		x1 = (i >= mix8Size) ? 0 : getSampleValueNr(mixPtr, mixTyp, src16Bits ? index16 : i);
-		x2 = (i >= dest8Size) ? 0 : getSampleValueNr(destPtr, destTyp, dst16Bits ? index16 : i);
+		x1 = (i >= mix8Size) ? 0 : getSampleValue(mixPtr, mixTyp, src16Bits ? index16 : i);
+		x2 = (i >= dest8Size) ? 0 : getSampleValue(destPtr, destTyp, dst16Bits ? index16 : i);
 
 		if (!src16Bits) x1 <<= 8;
 		if (!dst16Bits) x2 <<= 8;
@@ -999,7 +999,7 @@
 		if (!dst16Bits)
 			smp32 >>= 8;
 
-		putSampleValueNr(destPek, destTyp, dst16Bits ? index16 : i, (int16_t)smp32);
+		putSampleValue(destPek, destTyp, dst16Bits ? index16 : i, (int16_t)smp32);
 	}
 
 	if (instr[destIns]->samp[destSmp].origPek != NULL)