diff options
author | Michael Forney <mforney@mforney.org> | 2021-02-22 16:12:24 +0100 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-02-22 16:12:24 +0100 |
commit | 472958e3e7313cbe0cdb8d482045c2be87a23659 (patch) | |
tree | 243d9231eb17e8cdb2ad0c3b21e045d80fe44f9f | |
parent | 619fbe051bfa4b2492899c96971758a67c4c00a2 (diff) | |
download | plan9front-472958e3e7313cbe0cdb8d482045c2be87a23659.tar.xz |
games/snes: use 4-point hermite interpolation to resample
This is noticeably better than nearest-neighbor.
-rw-r--r-- | sys/src/games/snes/dsp.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/sys/src/games/snes/dsp.c b/sys/src/games/snes/dsp.c index 4281e1e94..714f252a4 100644 --- a/sys/src/games/snes/dsp.c +++ b/sys/src/games/snes/dsp.c @@ -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 |