Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ft2-clone for openSUSE:Factory 
checked in at 2026-07-02 20:10:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ft2-clone (Old)
 and      /work/SRC/openSUSE:Factory/.ft2-clone.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ft2-clone"

Thu Jul  2 20:10:03 2026 rev:44 rq:1363051 version:2.20

Changes:
--------
--- /work/SRC/openSUSE:Factory/ft2-clone/ft2-clone.changes      2026-05-04 
12:54:24.247669987 +0200
+++ /work/SRC/openSUSE:Factory/.ft2-clone.new.1982/ft2-clone.changes    
2026-07-02 20:13:18.997416350 +0200
@@ -1,0 +2,16 @@
+Wed Jul  1 17:38:50 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 2.20
+  * Sinc interpolation now uses up 74kB RAM instead of 2.4MB and
+    thus is less hard on the CPU cache. In some cases this means
+    even faster rendering. The way this change works is that the
+    polyphase look-up tables now use 256 phases/branches instead of
+    8192, coupled with linear interpolation between the phases when
+    in use. This method is equal to having many more pre-computed
+    phases than 8192, which in theory also means better precision.
+  * Cubic spline interpolation now doesn't use a look-up table.
+    Again, this is less hard on the CPU cache.
+  * (Hopefully) fixed "Alt Gr" key not working on some systems.
+  * "About" screen rendering has been optimized (big whoop).
+
+-------------------------------------------------------------------

Old:
----
  ft2-clone-2.19.tar.gz

New:
----
  ft2-clone-2.20.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ft2-clone.spec ++++++
--- /var/tmp/diff_new_pack.bIf9cm/_old  2026-07-02 20:13:19.505433937 +0200
+++ /var/tmp/diff_new_pack.bIf9cm/_new  2026-07-02 20:13:19.509434076 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           ft2-clone
-Version:        2.19
+Version:        2.20
 Release:        0
 Summary:        Fasttracker II clone
 License:        BSD-3-Clause AND CC-BY-NC-SA-4.0

++++++ ft2-clone-2.19.tar.gz -> ft2-clone-2.20.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_about.c 
new/ft2-clone-2.20/src/ft2_about.c
--- old/ft2-clone-2.19/src/ft2_about.c  2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/ft2_about.c  2026-07-01 16:33:52.000000000 +0200
@@ -11,21 +11,28 @@
 #include "ft2_random.h"
 
 #define NUM_STARS 1500
-#define STARSHINE_ALPHA_PERCENTAGE 33
+#define STARSHINE_ALPHA_PERCENTAGE 31
 #define ABOUT_SCREEN_X 3
 #define ABOUT_SCREEN_Y 3
 #define ABOUT_SCREEN_W 626
 #define ABOUT_SCREEN_H 167
 #define ABOUT_LOGO_W 541
 #define ABOUT_LOGO_H 78
+#define BG_COLORKEY 0xFF000000
+#define STAR_PIXEL_ID 0xFE000000
 
 typedef struct
 {
-       float x, y, z;
+       int16_t x, y, z;
 } vector_t;
 
 typedef struct
 {
+       float x, y, z;
+} rotate_t;
+
+typedef struct
+{
        vector_t x, y, z;
 } matrix_t;
 
@@ -35,10 +42,32 @@
 static char customText3[128];
 static int16_t customText0X, customText0Y, customText1X, customText1Y;
 static int16_t customText2X, customText2Y, customText3X, customText3Y;
+static int32_t lastStarPos[NUM_STARS];
 static const uint16_t starShineAlpha16 = (65535 * STARSHINE_ALPHA_PERCENTAGE) 
/ 100;
-static vector_t starPoints[NUM_STARS], starRotation;
+static vector_t starPoints[NUM_STARS];
+static rotate_t starRotation;
 static matrix_t starMatrix;
 
+static void clearPixel(uint32_t x, uint32_t y)
+{
+       if (x >= ABOUT_SCREEN_X+ABOUT_SCREEN_W || y >= 
ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
+               return;
+
+       const uint32_t pos = (y * SCREEN_W) + x;
+       if ((video.frameBuffer[pos] & 0xFF000000) == STAR_PIXEL_ID)
+               video.frameBuffer[pos] = BG_COLORKEY;
+}
+
+static void putPixel(uint32_t x, uint32_t y, uint32_t color)
+{
+       if (x >= ABOUT_SCREEN_X+ABOUT_SCREEN_W || y >= 
ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
+               return;
+
+       const uint32_t pos = (y * SCREEN_W) + x;
+       if (video.frameBuffer[pos] == BG_COLORKEY)
+               video.frameBuffer[pos] = color | STAR_PIXEL_ID;
+}
+
 static void blendPixelsXY(uint32_t x, uint32_t y, uint32_t pixelB_r, uint32_t 
pixelB_g, uint32_t pixelB_b, uint16_t alpha)
 {
        uint32_t *p = &video.frameBuffer[(y * SCREEN_W) + x];
@@ -49,7 +78,8 @@
        const int32_t g = ((RGB32_G(pixelA) * invAlpha) + (pixelB_g * alpha)) 
>> 16;
        const int32_t b = ((RGB32_B(pixelA) * invAlpha) + (pixelB_b * alpha)) 
>> 16;
 
-       *p = RGB32(r, g, b);
+       if (*p == BG_COLORKEY)
+               *p = RGB32(r, g, b) | STAR_PIXEL_ID;
 }
 
 static void starfield(void)
@@ -57,25 +87,48 @@
        vector_t *star = starPoints;
        for (int16_t i = 0; i < NUM_STARS; i++, star++)
        {
-               star->z += 0.0001f;
-               if (star->z >= 0.5f)
-                       star->z -= 1.0f;
+               // erase previous star
+               if (lastStarPos[i] != -1)
+               {
+                       const int32_t x = lastStarPos[i] >> 16, y = 
lastStarPos[i] & 0xFFFF;
+                       lastStarPos[i] = -1;
+
+                       // center
+                       clearPixel(x,   y);
+
+                       // sides
+                       clearPixel(x-1, y);
+                       clearPixel(x+1, y);
+                       clearPixel(x,   y-1);
+                       clearPixel(x,   y+1);
+               }
+
+               star->z += 3;
+               if (star->z > 16384)
+                       star->z -= 32768;
 
-               const float z = (starMatrix.x.z * star->x) + (starMatrix.y.z * 
star->y) + (starMatrix.z.z * star->z) + 0.5f;
-               if (z <= 0.0f)
+               int32_t z = (((starMatrix.x.z * star->x) + (starMatrix.y.z * 
star->y) + (starMatrix.z.z * star->z)) >> 15) + 16384;
+               if (z <= 0)
+                       continue;
+               
+               int32_t y = ((((starMatrix.x.y * star->x) + (starMatrix.y.y * 
star->y) + (starMatrix.z.y * star->z)) >> 15) * 400) / z;
+               y += ABOUT_SCREEN_H / 2;
+               if ((uint32_t)y >= ABOUT_SCREEN_H)
                        continue;
 
-               float y = (((starMatrix.x.y * star->x) + (starMatrix.y.y * 
star->y) + (starMatrix.z.y * star->z)) / z) * 400.0f;
-               const int32_t outY = (ABOUT_SCREEN_Y+(ABOUT_SCREEN_H/2)) + 
(int32_t)y;
-               if (outY < ABOUT_SCREEN_Y || outY >= 
ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
+               int32_t x = ((((starMatrix.x.x * star->x) + (starMatrix.y.x * 
star->y) + (starMatrix.z.x * star->z)) >> 15) * 400) / z;
+               x += ABOUT_SCREEN_W / 2;
+               if ((uint32_t)x >= ABOUT_SCREEN_W)
                        continue;
 
-               float x = (((starMatrix.x.x * star->x) + (starMatrix.y.x * 
star->y) + (starMatrix.z.x * star->z)) / z) * 400.0f;
-               const int32_t outX = (ABOUT_SCREEN_X+(ABOUT_SCREEN_W/2)) + 
(int32_t)x;
-               if (outX < ABOUT_SCREEN_X || outX >= 
ABOUT_SCREEN_X+ABOUT_SCREEN_W)
+               const int32_t outX = ABOUT_SCREEN_X + x;
+               const int32_t outY = ABOUT_SCREEN_Y + y;
+               
+               // only draw star if it's not over logo and text
+               if (video.frameBuffer[(outY * SCREEN_W) + outX] != BG_COLORKEY)
                        continue;
 
-               int32_t intensity255 = (int32_t)(z * 256.0f);
+               int32_t intensity255 = z >> 7;
                if (intensity255 > 255)
                        intensity255 = 255;
                intensity255 ^= 255;
@@ -94,6 +147,9 @@
                if (b > 255)
                        b = 255;
 
+               // plot center pixel
+               putPixel(outX, outY, RGB32(r, g, b));
+
                // plot and blend sides of star (basic shine effect)
 
                if (outX-1 >= ABOUT_SCREEN_X)
@@ -108,69 +164,58 @@
                if (outY+1 < ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
                        blendPixelsXY(outX, outY+1, r, g, b, starShineAlpha16);
 
-               // plot center pixel
-               video.frameBuffer[(outY * SCREEN_W) + outX] = RGB32(r, g, b);
+               lastStarPos[i] = (outX << 16) | outY;
        }
 }
 
 static void rotateStarfieldMatrix(void)
 {
 #define F_2PI (float)(2.0 * PI)
+#define SCALE 32767.0f
 
-       const float xrad = starRotation.x * F_2PI;
-       const float xsin = sinf(xrad);
-       const float xcos = cosf(xrad);
-
-       const float yrad = starRotation.y * F_2PI;
-       const float ysin = sinf(yrad);
-       const float ycos = cosf(yrad);
-
-       const float zrad = starRotation.z * F_2PI;
-       const float zsin = sinf(zrad);
-       const float zcos = cosf(zrad);
+       const float rx2p = starRotation.x * F_2PI;
+       const float xsin = sinf(rx2p);
+       const float xcos = cosf(rx2p);
+
+       const float ry2p = starRotation.y * F_2PI;
+       const float ysin = sinf(ry2p);
+       const float ycos = cosf(ry2p);
+
+       const float rz2p = starRotation.z * F_2PI;
+       const float zsin = sinf(rz2p);
+       const float zcos = cosf(rz2p);
 
        // x
-       starMatrix.x.x = (xcos * zcos) + (zsin * xsin * ysin);
-       starMatrix.y.x = xsin * ycos;
-       starMatrix.z.x = (zcos * xsin * ysin) - (xcos * zsin);
+       starMatrix.x.x = (int16_t)(SCALE * ((xcos * zcos) + (zsin * xsin * 
ysin)));
+       starMatrix.y.x = (int16_t)(SCALE * (xsin * ycos));
+       starMatrix.z.x = (int16_t)(SCALE * ((zcos * xsin * ysin) - (xcos * 
zsin)));
 
        // y
-       starMatrix.x.y = (zsin * xcos * ysin) - (xsin * zcos);
-       starMatrix.y.y = xcos * ycos;
-       starMatrix.z.y = (xsin * zsin) + (zcos * xcos * ysin);
+       starMatrix.x.y = (int16_t)(SCALE * ((zsin * xcos * ysin) - (xsin * 
zcos)));
+       starMatrix.y.y = (int16_t)(SCALE * (xcos * ycos));
+       starMatrix.z.y = (int16_t)(SCALE * ((xsin * zsin) + (zcos * xcos * 
ysin)));
 
        // z
-       starMatrix.x.z = ycos * zsin;
-       starMatrix.y.z = 0.0f - ysin;
-       starMatrix.z.z = ycos * zcos;
+       starMatrix.x.z = (int16_t)(SCALE * (ycos * zsin));
+       starMatrix.y.z = (int16_t)(SCALE * (0.0f - ysin));
+       starMatrix.z.z = (int16_t)(SCALE * (ycos * zcos));
 }
 
 void renderAboutScreenFrame(void)
 {
-       clearRect(ABOUT_SCREEN_X, ABOUT_SCREEN_Y, ABOUT_SCREEN_W, 
ABOUT_SCREEN_H);
-
-       // 3D starfield
-
        starfield();
        starRotation.x -= 0.0003f;
        starRotation.y -= 0.0002f;
        starRotation.z += 0.0001f;
        rotateStarfieldMatrix();
 
-       // FT2 logo
-       blit32((SCREEN_W - ABOUT_LOGO_W) / 2, 30, bmp.ft2AboutLogo, 
ABOUT_LOGO_W, ABOUT_LOGO_H);
-
-       // render static texts
-       textOut(customText0X, customText0Y, PAL_FORGRND, customText0);
-       textOut(customText1X, customText1Y, PAL_FORGRND, customText1);
-       textOut(customText2X, customText2Y, PAL_FORGRND, customText2);
-       textOut(customText3X, customText3Y, PAL_FORGRND, customText3);
-
        showPushButton(PB_EXIT_ABOUT); // yes, we also have to redraw the exit 
button per frame :)
 }
 
 void showAboutScreen(void) // called once when about screen is opened
 {
+       memset(lastStarPos, -1, NUM_STARS * sizeof (int32_t));
+
        if (ui.extendedPatternEditor)
                exitPatternEditorExtended();
 
@@ -179,6 +224,21 @@
        drawFramework(0, 0, 632, 173, FRAMEWORK_TYPE1);
        drawFramework(2, 2, 628, 169, FRAMEWORK_TYPE2);
 
+       for (int32_t y = ABOUT_SCREEN_Y; y < ABOUT_SCREEN_Y+ABOUT_SCREEN_H; y++)
+       {
+               for (int32_t x = ABOUT_SCREEN_X; x < 
ABOUT_SCREEN_X+ABOUT_SCREEN_W; x++)
+                       video.frameBuffer[(y * SCREEN_W) + x] = BG_COLORKEY;
+       }
+
+       // FT2 logo
+       blit32((SCREEN_W - ABOUT_LOGO_W) / 2, 30, bmp.ft2AboutLogo, 
ABOUT_LOGO_W, ABOUT_LOGO_H);
+
+       // render static texts
+       textOut(customText0X, customText0Y, PAL_FORGRND, customText0);
+       textOut(customText1X, customText1Y, PAL_FORGRND, customText1);
+       textOut(customText2X, customText2Y, PAL_FORGRND, customText2);
+       textOut(customText3X, customText3Y, PAL_FORGRND, customText3);
+
        showPushButton(PB_EXIT_ABOUT);
        ui.aboutScreenShown = true;
 }
@@ -188,9 +248,9 @@
        vector_t *s = starPoints;
        for (int32_t i = 0; i < NUM_STARS; i++, s++)
        {
-               s->x = (float)((randoml(INT32_MAX) - (INT32_MAX/2)) * (1.0 / 
INT32_MAX));
-               s->y = (float)((randoml(INT32_MAX) - (INT32_MAX/2)) * (1.0 / 
INT32_MAX));
-               s->z = (float)((randoml(INT32_MAX) - (INT32_MAX/2)) * (1.0 / 
INT32_MAX));
+               s->x = (int16_t)(randoml(32768) - 16384);
+               s->y = (int16_t)(randoml(32768) - 16384);
+               s->z = (int16_t)(randoml(32768) - 16384);
        }
 
        sprintf(customText3, "v%s (%s)", PROG_VER_STR, __DATE__);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_audio.c 
new/ft2-clone-2.20/src/ft2_audio.c
--- old/ft2-clone-2.19/src/ft2_audio.c  2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/ft2_audio.c  2026-07-01 16:33:52.000000000 +0200
@@ -840,7 +840,7 @@
        uint32_t samplesLeft = len;
        while (samplesLeft > 0)
        {
-               if (audio.tickSampleCounter == 0) // new replayer tick
+               if (audio.tickSampleCounter <= 0) // new replayer tick
                {
                        replayerBusy = true;
                        if (!musicPaused) // important, don't remove this 
check! (also used for safety)
@@ -850,7 +850,9 @@
 
                                tickReplayer();
                                updateVoices();
-                               fillVisualsSyncBuffer();
+
+                               if (audio.samplesPerTickInt != 0)
+                                       fillVisualsSyncBuffer();
                        }
                        replayerBusy = false;
 
@@ -864,13 +866,13 @@
                        }
                }
 
-               uint32_t samplesToMix = samplesLeft;
-               if (samplesToMix > audio.tickSampleCounter)
+               int32_t samplesToMix = samplesLeft;
+               if (audio.tickSampleCounter > 0 && samplesToMix > 
audio.tickSampleCounter)
                        samplesToMix = audio.tickSampleCounter;
 
                doChannelMixing(bufferPosition, samplesToMix);
                bufferPosition += samplesToMix;
-               
+
                audio.tickSampleCounter -= samplesToMix;
                samplesLeft -= samplesToMix;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_audio.h 
new/ft2-clone-2.20/src/ft2_audio.h
--- old/ft2-clone-2.19/src/ft2_audio.h  2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/ft2_audio.h  2026-07-01 16:33:52.000000000 +0200
@@ -41,7 +41,8 @@
        int32_t inputDeviceNum, outputDeviceNum, lastWorkingAudioFreq, 
lastWorkingAudioBits;
        uint32_t quickVolRampSamples, freq;
 
-       uint32_t tickSampleCounter, samplesPerTickInt, 
samplesPerTickIntTab[(MAX_BPM-MIN_BPM)+1];
+       int32_t tickSampleCounter;
+       uint32_t samplesPerTickInt, samplesPerTickIntTab[(MAX_BPM-MIN_BPM)+1];
        uint64_t tickSampleCounterFrac, samplesPerTickFrac, 
samplesPerTickFracTab[(MAX_BPM-MIN_BPM)+1];
 
        uint32_t audLatencyPerfValInt, tickTimeIntTab[(MAX_BPM-MIN_BPM)+1];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_header.h 
new/ft2-clone-2.20/src/ft2_header.h
--- old/ft2-clone-2.19/src/ft2_header.h 2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/ft2_header.h 2026-07-01 16:33:52.000000000 +0200
@@ -14,7 +14,7 @@
 #endif
 #include "ft2_replayer.h"
 
-#define PROG_VER_STR "2.19"
+#define PROG_VER_STR "2.20"
 
 // do NOT change these! It will only mess things up...
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_keyboard.c 
new/ft2-clone-2.20/src/ft2_keyboard.c
--- old/ft2-clone-2.19/src/ft2_keyboard.c       2026-05-03 13:01:36.000000000 
+0200
+++ new/ft2-clone-2.20/src/ft2_keyboard.c       2026-07-01 16:33:52.000000000 
+0200
@@ -388,6 +388,7 @@
                break;
 
                // play pattern
+               case SDLK_MODE: // Alt Gr is SDLK_MODE on some keyboards/layouts
                case SDLK_RALT:
                {
                        if (!keyb.leftCtrlPressed) // kludge for Mac (toggle 
fullscreen)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_main.c 
new/ft2-clone-2.20/src/ft2_main.c
--- old/ft2-clone-2.19/src/ft2_main.c   2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/ft2_main.c   2026-07-01 16:33:52.000000000 +0200
@@ -157,7 +157,7 @@
 #ifdef __APPLE__
        osxSetDirToProgramDirFromArgs(argv);
 #endif
-       if (!setupExecutablePath() || !loadBMPs() || 
!setupMixerInterpolationTables())
+       if (!setupExecutablePath() || !loadBMPs() || !setupWindowedSincTables())
        {
                cleanUpAndExit();
                return 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_replayer.c 
new/ft2-clone-2.20/src/ft2_replayer.c
--- old/ft2-clone-2.19/src/ft2_replayer.c       2026-05-03 13:01:36.000000000 
+0200
+++ new/ft2-clone-2.20/src/ft2_replayer.c       2026-07-01 16:33:52.000000000 
+0200
@@ -27,7 +27,7 @@
 #include "ft2_sample_loader.h"
 #include "ft2_tables.h"
 #include "ft2_structs.h"
-#include "mixer/ft2_mix_interpolation.h"
+#include "mixer/ft2_windowed_sinc.h"
 
 static uint32_t logTab[4*12*16], frequencyMulFactor, frequencyDivFactor;
 static uint64_t songTickDuration52fp[(MAX_BPM-MIN_BPM)+1];
@@ -2900,7 +2900,7 @@
                instr[131] = NULL;
        }
        
-       freeMixerInterpolationTables();
+       freeWindowedSincTables();
 }
 
 void calcMiscReplayerVars(void)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_replayer.h 
new/ft2-clone-2.20/src/ft2_replayer.h
--- old/ft2-clone-2.19/src/ft2_replayer.h       2026-05-03 13:01:36.000000000 
+0200
+++ new/ft2-clone-2.20/src/ft2_replayer.h       2026-07-01 16:33:52.000000000 
+0200
@@ -3,7 +3,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include "ft2_unicode.h"
-#include "mixer/ft2_mix_interpolation.h"
+#include "mixer/ft2_windowed_sinc.h"
 
 enum
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/ft2_sample_ed.c 
new/ft2-clone-2.20/src/ft2_sample_ed.c
--- old/ft2-clone-2.19/src/ft2_sample_ed.c      2026-05-03 13:01:36.000000000 
+0200
+++ new/ft2-clone-2.20/src/ft2_sample_ed.c      2026-07-01 16:33:52.000000000 
+0200
@@ -30,7 +30,6 @@
 #include "ft2_random.h"
 #include "ft2_replayer.h"
 #include "ft2_smpfx.h"
-#include "mixer/ft2_mix_interpolation.h" // SINC_TAPS, SINC_NEGATIVE_TAPS
 
 static const char sharpNote1Char[12] = { 'C', 'C', 'D', 'D', 'E', 'F', 'F', 
'G', 'G', 'A', 'A', 'B' };
 static const char sharpNote2Char[12] = { '-', '#', '-', '#', '-', '-', '#', 
'-', '#', '-', '#', '-' };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/mixer/ft2_mix_interpolation.c 
new/ft2-clone-2.20/src/mixer/ft2_mix_interpolation.c
--- old/ft2-clone-2.19/src/mixer/ft2_mix_interpolation.c        2026-05-03 
13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/mixer/ft2_mix_interpolation.c        1970-01-01 
01:00:00.000000000 +0100
@@ -1,182 +0,0 @@
-// mixer interpolation LUT generator
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <math.h>
-#include "../ft2_header.h"
-#include "../ft2_video.h" // showErrorMsgBox()
-#include "ft2_mix_interpolation.h"
-
-typedef struct
-{
-       double kaiserBeta, sincCutoff;
-} sincKernel_t;
-
-static sincKernel_t sincKernelConfig[SINC_KERNELS] =
-{
-       /* These parameters have been borrowed from the OpenMPT project
-       ** (with cutoff edit for kernel #1).
-       **
-       ** It's quite difficult to tweak these numbers without causing either
-       ** ringing or aliasing in some cases. If anyone has good experience on
-       ** designing low-tap windowed-sinc kernels for a use case like this, and
-       ** knows of a good way to figure out what numbers to use here, PLEASE
-       ** contact me (contact details can be found at the bottom of 
16-bits.org).
-       */
-
-       // beta,  cutoff
-       { 9.6377, 1.000 }, // kernel #1
-       { 8.5000, 0.500 }, // kernel #2
-       { 7.0000, 0.425 }  // kernel #3
-};
-
-// globalized
-float *fCubicSplineLUT, *fSinc[SINC_KERNELS], *fSinc8[SINC_KERNELS], 
*fSinc16[SINC_KERNELS];
-uint64_t sincRatio1, sincRatio2;
-// ----------
-
-static void calcPolyphaseSincLUT(float *fOut, int32_t numTaps, double 
kaiserBeta, double sincCutoff);
-
-bool setupMixerInterpolationTables(void)
-{
-       // cubic spline (4-point)
-
-       fCubicSplineLUT = (float *)malloc(INTRP_PHASES * CUBIC_SPLINE_TAPS * 
sizeof (float));
-       if (fCubicSplineLUT == NULL)
-       {
-               showErrorMsgBox("Not enough memory!");
-               return false;
-       }
-
-       float *fPtr = fCubicSplineLUT;
-       for (int32_t i = 0; i < INTRP_PHASES; i++)
-       {
-               const double x1 = i * (1.0 / INTRP_PHASES);
-               const double x2 = x1 * x1; // x^2
-               const double x3 = x2 * x1; // x^3
-
-               // Catmull-Rom algorithm (has unity gain)
-               const double t1 = (x1 * -0.5) + (x2 *  1.0) + (x3 * -0.5);
-               const double t2 =               (x2 * -2.5) + (x3 *  1.5) + 1.0;
-               const double t3 = (x1 *  0.5) + (x2 *  2.0) + (x3 * -1.5);
-               const double t4 =               (x2 * -0.5) + (x3 *  0.5);
-
-               *fPtr++ = (float)t1; // tap #1 at sample offset -1
-               *fPtr++ = (float)t2; // tap #2 at sample offset  0 (center)
-               *fPtr++ = (float)t3; // tap #3 at sample offset  1
-               *fPtr++ = (float)t4; // tap #4 at sample offset  2
-       }
-
-       // windowed-sinc (8-point/16-point)
-
-       sincKernel_t *k = sincKernelConfig;
-       for (int32_t i = 0; i < SINC_KERNELS; i++, k++)
-       {
-                fSinc8[i] = (float *)malloc(INTRP_PHASES * SINC8_TAPS  * 
sizeof (float));
-               fSinc16[i] = (float *)malloc(INTRP_PHASES * SINC16_TAPS * 
sizeof (float));
-
-               if (fSinc8[i] == NULL || fSinc16[i] == NULL)
-               {
-                       showErrorMsgBox("Not enough memory!");
-                       return false;
-               }
-
-               calcPolyphaseSincLUT( fSinc8[i], SINC8_TAPS,  k->kaiserBeta, 
k->sincCutoff);
-               calcPolyphaseSincLUT(fSinc16[i], SINC16_TAPS, k->kaiserBeta, 
k->sincCutoff);
-       }
-
-       // resampling ratios for sinc kernel selection
-       sincRatio1 = (uint64_t)(1.1875 * MIXER_FRAC_SCALE); // fSinc[0] if <=
-       sincRatio2 = (uint64_t)(1.5000 * MIXER_FRAC_SCALE); // fSinc[1] if <=, 
else fSinc[2] if >
-
-       return true;
-}
-
-void freeMixerInterpolationTables(void)
-{
-       if (fCubicSplineLUT != NULL)
-       {
-               free(fCubicSplineLUT);
-               fCubicSplineLUT = NULL;
-       }
-
-       for (int32_t i = 0; i < SINC_KERNELS; i++)
-       {
-               if (fSinc8[i] != NULL)
-               {
-                       free(fSinc8[i]);
-                       fSinc8[i] = NULL;
-               }
-
-               if (fSinc16[i] != NULL)
-               {
-                       free(fSinc16[i]);
-                       fSinc16[i] = NULL;
-               }
-       }
-}
-
-// zeroth-order modified Bessel function of the first kind (series 
approximation)
-static inline double besselI0(double z)
-{
-       double s = 1.0, ds = 1.0, d = 2.0;
-       const double zz = z * z;
-
-       do
-       {
-               ds *= zz / (d * d);
-               s += ds;
-               d += 2.0;
-       }
-       while (ds > s*(1E-12));
-
-       return s;
-}
-
-static inline double sinc(double x, double cutoff)
-{
-       if (x == 0.0)
-       {
-               return cutoff;
-       }
-       else
-       {
-               x *= PI;
-               return sin(cutoff * x) / x;
-       }
-}
-
-// note: numTaps must be even!
-static void calcPolyphaseSincLUT(float *fOut, int32_t numTaps, double 
kaiserBeta, double sincCutoff)
-{
-       double tapBuffer[MAX_TAPS];
-       const double besselI0BetaMul = 1.0 / besselI0(kaiserBeta);
-       const int32_t centerPoint = (numTaps / 2) - 1;
-       const double xMul = 1.0 / (numTaps / 2);
-
-       for (int32_t i = 0; i < INTRP_PHASES; i++)
-       {
-               const double phase = i * (1.0 / INTRP_PHASES);
-
-               double tapSum = 0.0;
-               for (int32_t j = 0; j < numTaps; j++)
-               {
-                       const double x = (j - centerPoint) - phase;
-
-                       // Kaiser-Bessel window
-                       const double n = x * xMul;
-                       const double window = besselI0(kaiserBeta * sqrt(1.0 - 
n * n)) * besselI0BetaMul;
-
-                       const double wsinc = sinc(x, sincCutoff) * window;
-                       tapBuffer[j] = wsinc;
-
-                       tapSum += wsinc;
-               }
-
-               // normalize for unity gain before storing taps
-               const double tapMul = 1.0 / tapSum;
-               for (int32_t j = 0; j < numTaps; j++)
-                       *fOut++ = (float)(tapBuffer[j] * tapMul);
-       }
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/mixer/ft2_mix_interpolation.h 
new/ft2-clone-2.20/src/mixer/ft2_mix_interpolation.h
--- old/ft2-clone-2.19/src/mixer/ft2_mix_interpolation.h        2026-05-03 
13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/mixer/ft2_mix_interpolation.h        1970-01-01 
01:00:00.000000000 +0100
@@ -1,38 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-#include "ft2_mix.h" // MIXER_FRAC_BITS
-
-#define SINC_KERNELS 3
-#define SINC8_TAPS 8
-#define SINC16_TAPS 16
-#define CUBIC_SPLINE_TAPS 4
-
-// 8192 phases has a decent trade-off between low aliasing and cache usage
-#define INTRP_PHASES 8192
-
-// log2(INTRP_PHASES)
-#define INTRP_PHASES_BITS 13
-
-// log2(CUBIC_SPLINE_TAPS)
-#define CUBIC_SPLINE_TAPS_BITS 2
-
-// log2(SINC8_TAPS)
-#define SINC8_TAPS_BITS 3
-
-// log2(SINC16_TAPS)
-#define SINC16_TAPS_BITS 4
-
-#define CUBIC_SPLINE_FRACSHIFT 
(MIXER_FRAC_BITS-(INTRP_PHASES_BITS+CUBIC_SPLINE_TAPS_BITS))
-#define CUBIC_SPLINE_FRACMASK 
((CUBIC_SPLINE_TAPS*INTRP_PHASES)-CUBIC_SPLINE_TAPS)
-#define SINC8_FRACSHIFT (MIXER_FRAC_BITS-(INTRP_PHASES_BITS+SINC8_TAPS_BITS))
-#define SINC8_FRACMASK ((SINC8_TAPS*INTRP_PHASES)-SINC8_TAPS)
-#define SINC16_FRACSHIFT (MIXER_FRAC_BITS-(INTRP_PHASES_BITS+SINC16_TAPS_BITS))
-#define SINC16_FRACMASK ((SINC16_TAPS*INTRP_PHASES)-SINC16_TAPS)
-
-extern float *fCubicSplineLUT, *fSinc[SINC_KERNELS], *fSinc8[SINC_KERNELS], 
*fSinc16[SINC_KERNELS];
-extern uint64_t sincRatio1, sincRatio2;
-
-bool setupMixerInterpolationTables(void);
-void freeMixerInterpolationTables(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/mixer/ft2_mix_macros.h 
new/ft2-clone-2.20/src/mixer/ft2_mix_macros.h
--- old/ft2-clone-2.19/src/mixer/ft2_mix_macros.h       2026-05-03 
13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/src/mixer/ft2_mix_macros.h       2026-07-01 
16:33:52.000000000 +0200
@@ -130,13 +130,23 @@
 /*                       CUBIC SPLINE INTERPOLATION                        */
 /* ----------------------------------------------------------------------- */
 
+// Catmull-Rom algorithm
 #define CUBIC_SPLINE_INTERPOLATION(s, f, scale) \
 { \
-       const float *t = fCubicSplineLUT + (((uint32_t)(f) >> 
CUBIC_SPLINE_FRACSHIFT) & CUBIC_SPLINE_FRACMASK); \
-       fSample = ((s[-1] * t[0]) + \
-                  ( s[0] * t[1]) + \
-                  ( s[1] * t[2]) + \
-                  ( s[2] * t[3])) * (1.0f / scale); \
+       const int32_t frac31 = (uint32_t)f >> 1; /* reduce from uint32_t to 
int32_t for fast SIMD usage */ \
+       const float x = frac31 * (1.0f / ((float)INT32_MAX+1.0f)); \
+       \
+       const float v0 = s[-1]; \
+       const float v1 = s[0]; \
+       const float v2 = s[1]; \
+       const float v3 = s[2]; \
+       \
+       const float c1 = v1; \
+       const float c2 = 0.5f * (v2 - v0); \
+       const float c3 = v0 - (2.5f * v1) + (2.0f * v2) - (0.5f * v3); \
+       const float c4 = 0.5f * (v3 - v0) + 1.5f * (v1 - v2); \
+       \
+       fSample = (((c4 * x + c3) * x + c2) * x + c1) * (1.0f / scale); \
 }
 
 #define RENDER_8BIT_SMP_CINTRP \
@@ -173,36 +183,50 @@
 
 #define WINDOWED_SINC8_INTERPOLATION(s, f, scale) \
 { \
-       const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC8_FRACSHIFT) & 
SINC8_FRACMASK); \
-       fSample = ((s[-3] * t[0]) + \
-                  (s[-2] * t[1]) + \
-                  (s[-1] * t[2]) + \
-                  ( s[0] * t[3]) + \
-                  ( s[1] * t[4]) + \
-                  ( s[2] * t[5]) + \
-                  ( s[3] * t[6]) + \
-                  ( s[4] * t[7])) * (1.0f / scale); \
+       const uint32_t frac32 = (uint32_t)f; \
+       const uint32_t lutPhase = frac32 >> INTRP_PHASE_SHIFT; \
+       const float fIntrpFrac = (int32_t)(frac32 & INTRP_PHASE_MASK) * (1.0f / 
INTRP_PHASE_SCALE); \
+       \
+       /* it may look like we go out of bounds for fSinc_2, but we have an 
extra phase after LUT */ \
+       const float *fSinc_1 = v->fSincLUT + ( lutPhase    << SINC8_TAPS_BITS); 
\
+       const float *fSinc_2 = v->fSincLUT + ((lutPhase+1) << SINC8_TAPS_BITS); 
\
+       \
+       float fSum = 0.0f; \
+       for (int32_t j = 0; j < SINC8_TAPS; j++) \
+       { \
+               /* do linear interpolation between phases */ \
+               const float y1 = fSinc_1[j]; \
+               const float y2 = fSinc_2[j]; \
+               \
+               /* out of bounds for s[] is safe here and returns the correct 
samples */ \
+               fSum += s[j-((SINC8_TAPS/2)-1)] * (y1 + ((y2 - y1) * 
fIntrpFrac)); \
+       } \
+       \
+       fSample = fSum * (1.0f / scale); \
 }
 
 #define WINDOWED_SINC16_INTERPOLATION(s, f, scale) \
 { \
-       const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC16_FRACSHIFT) & 
SINC16_FRACMASK); \
-       fSample = (( s[-7] * t[0]) + \
-                  ( s[-6] * t[1]) + \
-                  ( s[-5] * t[2]) + \
-                  ( s[-4] * t[3]) + \
-                  ( s[-3] * t[4]) + \
-                  ( s[-2] * t[5]) + \
-                  ( s[-1] * t[6]) + \
-                  (  s[0] * t[7]) + \
-                  (  s[1] * t[8]) + \
-                  (  s[2] * t[9]) + \
-                  (  s[3] * t[10]) + \
-                  (  s[4] * t[11]) + \
-                  (  s[5] * t[12]) + \
-                  (  s[6] * t[13]) + \
-                  (  s[7] * t[14]) + \
-                  (  s[8] * t[15])) * (1.0f / scale); \
+       const uint32_t frac32 = (uint32_t)f; \
+       const uint32_t lutPhase = frac32 >> INTRP_PHASE_SHIFT; \
+       const float fIntrpFrac = (int32_t)(frac32 & INTRP_PHASE_MASK) * (1.0f / 
INTRP_PHASE_SCALE); \
+       \
+       /* it may look like we go out of bounds for fSinc_2, but we have an 
extra phase after LUT */ \
+       const float *fSinc_1 = v->fSincLUT + ( lutPhase    << 
SINC16_TAPS_BITS); \
+       const float *fSinc_2 = v->fSincLUT + ((lutPhase+1) << 
SINC16_TAPS_BITS); \
+       \
+       float fSum = 0.0f; \
+       for (int32_t j = 0; j < SINC16_TAPS; j++) \
+       { \
+               /* do linear interpolation between phases */ \
+               const float y1 = fSinc_1[j]; \
+               const float y2 = fSinc_2[j]; \
+               \
+               /* out of bounds for s[] is safe here and returns the correct 
samples */ \
+               fSum += s[j-((SINC16_TAPS/2)-1)] * (y1 + ((y2 - y1) * 
fIntrpFrac)); \
+       } \
+       \
+       fSample = fSum * (1.0f / scale); \
 }
 
 #define RENDER_8BIT_SMP_S8INTRP \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/mixer/ft2_windowed_sinc.c 
new/ft2-clone-2.20/src/mixer/ft2_windowed_sinc.c
--- old/ft2-clone-2.19/src/mixer/ft2_windowed_sinc.c    1970-01-01 
01:00:00.000000000 +0100
+++ new/ft2-clone-2.20/src/mixer/ft2_windowed_sinc.c    2026-07-01 
16:33:52.000000000 +0200
@@ -0,0 +1,172 @@
+// polyphase windowed-sinc LUT generator
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <math.h>
+#include "../ft2_header.h"
+#include "../ft2_video.h" // showErrorMsgBox()
+#include "ft2_windowed_sinc.h"
+
+typedef struct
+{
+       double kaiserBeta, sincCutoff;
+} sincKernel_t;
+
+static sincKernel_t sincKernelConfig[SINC_KERNELS] =
+{
+       /* These parameters have been borrowed from the OpenMPT project
+       ** (with cutoff edit for kernel #1).
+       **
+       ** It's quite difficult to tweak these numbers without causing either
+       ** ringing or aliasing in some cases. If anyone has good experience on
+       ** designing low-tap windowed-sinc kernels for a use case like this, and
+       ** knows of a good way to figure out what numbers to use here, PLEASE
+       ** contact me (contact details can be found at the bottom of 
16-bits.org).
+       */
+
+       // beta,  cutoff
+       { 9.6377, 1.000 }, // kernel #1
+       { 8.5000, 0.500 }, // kernel #2
+       { 7.0000, 0.425 }  // kernel #3
+};
+
+// globalized
+float *fSinc[SINC_KERNELS], *fSinc8[SINC_KERNELS], *fSinc16[SINC_KERNELS];
+uint64_t sincRatio1, sincRatio2;
+// ----------
+
+static bool calcPolyphaseSincLUT(float *fOut, int32_t numTaps, int32_t 
numPhases, double kaiserBeta, double sincCutoff);
+
+bool setupWindowedSincTables(void)
+{
+       sincKernel_t *k = sincKernelConfig;
+       for (int32_t i = 0; i < SINC_KERNELS; i++, k++)
+       {
+                fSinc8[i] = (float *)malloc((SINC_OVERSAMPLING+1) *  
SINC8_TAPS * sizeof (float));
+               fSinc16[i] = (float *)malloc((SINC_OVERSAMPLING+1) * 
SINC16_TAPS * sizeof (float));
+
+               if (fSinc8[i] == NULL || fSinc16[i] == NULL)
+               {
+                       showErrorMsgBox("Not enough memory!");
+                       return false;
+               }
+
+               if (!calcPolyphaseSincLUT(fSinc8[i], SINC8_TAPS, 
SINC_OVERSAMPLING, k->kaiserBeta, k->sincCutoff))
+               {
+                       showErrorMsgBox("Not enough memory!");
+                       return false;
+               }
+
+               if (!calcPolyphaseSincLUT(fSinc16[i], SINC16_TAPS, 
SINC_OVERSAMPLING, k->kaiserBeta, k->sincCutoff))
+               {
+                       showErrorMsgBox("Not enough memory!");
+                       return false;
+               }
+       }
+
+       // fixed-point resampling ratios for sinc kernel selection (to get a 
gradual cut-off curve)
+       sincRatio1 = (uint64_t)(1.1875 * MIXER_FRAC_SCALE); // fSinc[0] if <=
+       sincRatio2 = (uint64_t)(1.5000 * MIXER_FRAC_SCALE); // fSinc[1] if <=, 
else fSinc[2] if >
+
+       return true;
+}
+
+void freeWindowedSincTables(void)
+{
+       for (int32_t i = 0; i < SINC_KERNELS; i++)
+       {
+               if (fSinc8[i] != NULL)
+               {
+                       free(fSinc8[i]);
+                       fSinc8[i] = NULL;
+               }
+
+               if (fSinc16[i] != NULL)
+               {
+                       free(fSinc16[i]);
+                       fSinc16[i] = NULL;
+               }
+       }
+}
+
+// zeroth-order modified Bessel function of the first kind (series 
approximation)
+static double besselI0(double z)
+{
+       double s = 1.0, ds = 1.0, d = 2.0;
+       const double zz = z * z;
+
+       do
+       {
+               ds *= zz / (d * d);
+               s += ds;
+               d += 2.0;
+       }
+       while (ds > s*(1E-12));
+
+       return s;
+}
+
+static double sinc(double x, double cutoff)
+{
+       if (x == 0.0)
+       {
+               return cutoff;
+       }
+       else
+       {
+               x *= PI;
+               return sin(cutoff * x) / x;
+       }
+}
+
+/* Polyphase sinc LUT generator w/ Kaiser-Bessel window.
+**
+** Note #1: The 'sincCutoff' parameter ranges from 0.0 to 1.0, where 1.0 is no 
cutoff.
+** Note #2: The 'numTaps' parameter must be an even number.
+*/
+static bool calcPolyphaseSincLUT(float *fOut, int32_t numTaps, int32_t 
numPhases, double kaiserBeta, double sincCutoff)
+{
+       double *tapBuffer = (double *)malloc(numTaps * sizeof (double));
+       if (tapBuffer == NULL)
+               return false;
+
+       const double besselI0BetaMul = 1.0 / besselI0(kaiserBeta);
+       const int32_t centerPoint = (numTaps / 2) - 1;
+       const double phaseMul = 1.0 / numPhases;
+       const double kaiserXMul = 1.0 / (numTaps / 2);
+
+       float *fOutPtr = fOut;
+       for (int32_t i = 0; i < numPhases; i++)
+       {
+               const double phase = i * phaseMul;
+
+               double tapSum = 0.0;
+               for (int32_t j = 0; j < numTaps; j++)
+               {
+                       const double x = (j - centerPoint) - phase;
+
+                       // Kaiser-Bessel window
+                       const double n = x * kaiserXMul;
+                       const double window = besselI0(kaiserBeta * sqrt(1.0 - 
n * n)) * besselI0BetaMul;
+
+                       const double wsinc = sinc(x, sincCutoff) * window;
+                       tapBuffer[j] = wsinc;
+
+                       tapSum += wsinc;
+               }
+
+               // normalize for unity gain before storing taps
+               const double tapMul = 1.0 / tapSum;
+               for (int32_t j = 0; j < numTaps; j++)
+                       *fOutPtr++ = (float)(tapBuffer[j] * tapMul);
+       }
+
+       // store inverted wrap-around taps after end of LUT (for phase 
interpolation)
+       float *fEnd = &fOut[numTaps * numPhases];
+       for (int32_t i = 0; i < numTaps; i++)
+               fEnd[i] = fOut[(numTaps-1) - i];
+
+       free(tapBuffer);
+       return true;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ft2-clone-2.19/src/mixer/ft2_windowed_sinc.h 
new/ft2-clone-2.20/src/mixer/ft2_windowed_sinc.h
--- old/ft2-clone-2.19/src/mixer/ft2_windowed_sinc.h    1970-01-01 
01:00:00.000000000 +0100
+++ new/ft2-clone-2.20/src/mixer/ft2_windowed_sinc.h    2026-07-01 
16:33:52.000000000 +0200
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ft2_mix.h" // MIXER_FRAC_BITS
+
+#define SINC_KERNELS 3
+#define SINC8_TAPS 8
+#define SINC16_TAPS 16
+
+// 256 phases + linear interpolation = near perfect (and low CPU cache usage)
+#define SINC_OVERSAMPLING 256
+
+// log2(SINC_OVERSAMPLING)
+#define SINC_OVERSAMPLING_BITS 8
+
+// log2(SINC8_TAPS)
+#define SINC8_TAPS_BITS 3
+
+// log2(SINC16_TAPS)
+#define SINC16_TAPS_BITS 4
+
+#define INTRP_PHASE_SHIFT (MIXER_FRAC_BITS-SINC_OVERSAMPLING_BITS)
+#define INTRP_PHASE_SCALE (1L << INTRP_PHASE_SHIFT)
+#define INTRP_PHASE_MASK (INTRP_PHASE_SCALE-1)
+
+extern float *fSinc[SINC_KERNELS], *fSinc8[SINC_KERNELS], 
*fSinc16[SINC_KERNELS];
+extern uint64_t sincRatio1, sincRatio2;
+
+bool setupWindowedSincTables(void);
+void freeWindowedSincTables(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ft2-clone-2.19/vs2019_project/ft2-clone/ft2-clone.vcxproj 
new/ft2-clone-2.20/vs2019_project/ft2-clone/ft2-clone.vcxproj
--- old/ft2-clone-2.19/vs2019_project/ft2-clone/ft2-clone.vcxproj       
2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/vs2019_project/ft2-clone/ft2-clone.vcxproj       
2026-07-01 16:33:52.000000000 +0200
@@ -345,7 +345,7 @@
     <ClCompile Include="..\..\src\gfxdata\ft2_bmp_instr.c" />
     <ClCompile Include="..\..\src\gfxdata\ft2_bmp_looppins.c" />
     <ClCompile Include="..\..\src\gfxdata\ft2_bmp_scopes.c" />
-    <ClCompile Include="..\..\src\mixer\ft2_mix_interpolation.c" />
+    <ClCompile Include="..\..\src\mixer\ft2_windowed_sinc.c" />
     <ClCompile Include="..\..\src\mixer\ft2_mix.c" />
     <ClCompile Include="..\..\src\mixer\ft2_silence_mix.c" />
     <ClCompile Include="..\..\src\modloaders\ft2_load_digi.c" />
@@ -423,7 +423,7 @@
     <ClInclude Include="..\..\src\ft2_unicode.h" />
     <ClInclude Include="..\..\src\ft2_video.h" />
     <ClInclude Include="..\..\src\ft2_wav_renderer.h" />
-    <ClInclude Include="..\..\src\mixer\ft2_mix_interpolation.h" />
+    <ClInclude Include="..\..\src\mixer\ft2_windowed_sinc.h" />
     <ClInclude Include="..\..\src\mixer\ft2_mix.h" />
     <ClInclude Include="..\..\src\mixer\ft2_mix_macros.h" />
     <ClInclude Include="..\..\src\mixer\ft2_silence_mix.h" />
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ft2-clone-2.19/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters 
new/ft2-clone-2.20/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters
--- old/ft2-clone-2.19/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters       
2026-05-03 13:01:36.000000000 +0200
+++ new/ft2-clone-2.20/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters       
2026-07-01 16:33:52.000000000 +0200
@@ -130,7 +130,7 @@
     </ClCompile>
     <ClCompile Include="..\..\src\ft2_random.c" />
     <ClCompile Include="..\..\src\ft2_smpfx.c" />
-    <ClCompile Include="..\..\src\mixer\ft2_mix_interpolation.c">
+    <ClCompile Include="..\..\src\mixer\ft2_windowed_sinc.c">
       <Filter>mixer</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\smploaders\ft2_load_mp3.c">
@@ -294,7 +294,7 @@
     <ClInclude Include="..\..\src\ft2_smpfx.h">
       <Filter>headers</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\mixer\ft2_mix_interpolation.h">
+    <ClInclude Include="..\..\src\mixer\ft2_windowed_sinc.h">
       <Filter>mixer</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\smploaders\minimp3.h">

Reply via email to