]> git.lizzy.rs Git - plan9front.git/commitdiff
games/snes: use 4-point hermite interpolation to resample
authorMichael Forney <mforney@mforney.org>
Mon, 22 Feb 2021 15:12:24 +0000 (16:12 +0100)
committerMichael Forney <mforney@mforney.org>
Mon, 22 Feb 2021 15:12:24 +0000 (16:12 +0100)
This is noticeably better than nearest-neighbor.

sys/src/games/snes/dsp.c

index 4281e1e94ab07a0deeef4b6e7276f43bc7a8afb7..714f252a49bb24245cee639b786439d49c6420de 100644 (file)
@@ -49,7 +49,6 @@ enum { RELEASE, ATTACK, DECAY, SUSTAIN };
 
 enum { Freq = 44100 };
 static s16int sbuf[2*2000], *sbufp;
-static int stime;
 static int fd;
 
 void
@@ -61,16 +60,36 @@ audioinit(void)
        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