code: plan9front

Download patch

ref: 472958e3e7313cbe0cdb8d482045c2be87a23659
parent: 619fbe051bfa4b2492899c96971758a67c4c00a2
author: Michael Forney <mforney@mforney.org>
date: Mon Feb 22 11:12:24 EST 2021

games/snes: use 4-point hermite interpolation to resample

This is noticeably better than nearest-neighbor.

--- a/sys/src/games/snes/dsp.c
+++ b/sys/src/games/snes/dsp.c
@@ -49,7 +49,6 @@
 
 enum { Freq = 44100 };
 static s16int sbuf[2*2000], *sbufp;
-static int stime;
 static int fd;
 
 void
@@ -61,16 +60,36 @@
 	sbufp = sbuf;
 }
 
+static int
+hermite(int *x, int t)
+{
+	int y;
+
+	y = (x[0] - x[6]) / 2 + (x[4] - x[2]) * 3 / 2;
+	y = y * t >> 15;
+	y += x[6] - x[4] * 5 / 2 + x[2] * 2 - x[0] / 2;
+	y = y * t >> 15;
+	y += (x[2] - x[6]) / 2;
+	y = y * t >> 15;
+	y += x[4];
+	return y;
+}
+
 static void
 audiosample(s16int *s)
 {
-	stime -= 1<<16;
+	static int x[8], t;
+
+	x[0] = s[0];
+	x[1] = s[1];
 	do {
-		sbufp[0] = s[0];
-		sbufp[1] = s[1];
+		sbufp[0] = hermite(x, t);
+		sbufp[1] = hermite(x + 1, t);
 		sbufp += 2;
-		stime += (32000<<16)/Freq;
-	} while(stime < 0);
+		t += (32000<<15)/Freq;
+	} while(t < 1<<15);
+	t -= 1<<15;
+	memmove(x + 2, x, sizeof(x) - 2 * sizeof(x[0]));
 }
 
 int