changeset 287:1e89cd081956

Use fixed point everywhere in the mixing internals, to avoid going over sample boundaries.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 11 Oct 2012 11:09:26 +0300
parents a17e54015bd9
children e2f286781180
files jmix_c_in.c jmixtmpl_c.h jssmix.c jssmix.h ppl.c
diffstat 5 files changed, 33 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/jmix_c_in.c	Thu Oct 11 10:24:00 2012 +0300
+++ b/jmix_c_in.c	Thu Oct 11 11:09:26 2012 +0300
@@ -20,12 +20,12 @@
 
 #define JMIXER_NAME        jvmMix_Mono_C_FW
 #define JMIXER_NEXT        FP_ADD(tmpPos, tmpDelta);
-#define JMIXER_ENDCOND     (FP_GETH(tmpPos) < endPos)
+#define JMIXER_ENDCOND     (tmpPos.dw < endPos.dw)
 #include "jmixtmpl_c.h"
 
 #define JMIXER_NAME        jvmMix_Mono_C_BW
 #define JMIXER_NEXT        FP_SUB(tmpPos, tmpDelta);
-#define JMIXER_ENDCOND     (FP_GETH(tmpPos) > endPos)
+#define JMIXER_ENDCOND     (tmpPos.dw > endPos.dw)
 #include "jmixtmpl_c.h"
 
 
@@ -49,12 +49,12 @@
 
 #define JMIXER_NAME        jvmMix_Stereo_C_FW
 #define JMIXER_NEXT        FP_ADD(tmpPos, tmpDelta);
-#define JMIXER_ENDCOND     (FP_GETH(tmpPos) < endPos)
+#define JMIXER_ENDCOND     (tmpPos.dw < endPos.dw)
 #include "jmixtmpl_c.h"
 
 #define JMIXER_NAME        jvmMix_Stereo_C_BW
 #define JMIXER_NEXT        FP_SUB(tmpPos, tmpDelta);
-#define JMIXER_ENDCOND     (FP_GETH(tmpPos) > endPos)
+#define JMIXER_ENDCOND     (tmpPos.dw > endPos.dw)
 #include "jmixtmpl_c.h"
 
 
--- a/jmixtmpl_c.h	Thu Oct 11 10:24:00 2012 +0300
+++ b/jmixtmpl_c.h	Thu Oct 11 11:09:26 2012 +0300
@@ -4,7 +4,7 @@
  * (C) Copyright 2006-2007 Tecnic Software productions (TNSP)
  */
 
-int JMIXER_NAME (JSSMixer *mixer, JSSChannel *chn, JMIXER_ADDBUF_TYPE *addBuffer, const int mixLength, const Sint32 endPos)
+int JMIXER_NAME (JSSMixer *mixer, JSSChannel *chn, JMIXER_ADDBUF_TYPE *addBuffer, const int mixLength, const DMFixedPoint endPos)
 #ifdef JMIXER_HEADER
 ;
 #else
--- a/jssmix.c	Thu Oct 11 10:24:00 2012 +0300
+++ b/jssmix.c	Thu Oct 11 11:09:26 2012 +0300
@@ -28,8 +28,8 @@
     int    outFormat;
     int    outChannels;
 
-    int    (*jvmMixChannel_FW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const Sint32);
-    int    (*jvmMixChannel_BW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const Sint32);
+    int    (*jvmMixChannel_FW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const DMFixedPoint);
+    int    (*jvmMixChannel_BW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const DMFixedPoint);
     void   (*jvmPostProcess)(JMIXER_ADDBUF_TYPE *, void *, const int);
 } JSSMixingRoutine;
 
@@ -250,10 +250,10 @@
                 if (chn->chFlags & jsfBiDi)
                 {
                     // Bi-directional loop
-                    if (FP_GETH(chn->chPos) >= chn->chLoopE)
+                    if (chn->chPos.dw >= chn->chLoopE.dw)
                     {
                         DMFixedPoint end;
-                        FP_SETHL(end, chn->chLoopE + chn->chLoopE, 0);
+                        FP_ADD_R(end, chn->chLoopE, chn->chLoopE);
                         FP_SUB_R(chn->chPos, end, chn->chPos);
                         chn->chDirection = FALSE;
                     }
@@ -261,20 +261,18 @@
                 else
                 {
                     // Normal forward loop
-                    if (FP_GETH(chn->chPos) >= chn->chLoopE)
+                    if (chn->chPos.dw >= chn->chLoopE.dw)
                     {
-                        DMFixedPoint diff, end;
-                        FP_SETHL(end, chn->chLoopE, 0);
-                        FP_SUB_R(diff, chn->chPos, end);
-                        FP_SETHL(chn->chPos, chn->chLoopS, 0);
-                        FP_ADD(chn->chPos, diff);
+                        DMFixedPoint diff;
+                        FP_SUB_R(diff, chn->chPos, chn->chLoopE);
+                        FP_ADD_R(chn->chPos, chn->chLoopS, diff);
                     }
                 }
             }
             else
             {
                 // Normal (non-looped) sample
-                if (FP_GETH(chn->chPos) >= chn->chSize)
+                if (chn->chPos.dw >= chn->chSize.dw)
                 {
                     chn->chPlaying = FALSE;
                     return;
@@ -290,10 +288,10 @@
                 if (chn->chFlags & jsfBiDi)
                 {
                     // Bi-directional loop
-                    if (FP_GETH(chn->chPos) <= chn->chLoopS)
+                    if (chn->chPos.dw <= chn->chLoopS.dw)
                     {
                         DMFixedPoint start;
-                        FP_SETHL(start, chn->chLoopS + chn->chLoopS, 0);
+                        FP_ADD_R(start, chn->chLoopS, chn->chLoopS);
                         FP_SUB_R(chn->chPos, start, chn->chPos);
                         chn->chDirection = TRUE;
                     }
@@ -301,10 +299,10 @@
                 else
                 {
                     // Normal forward loop
-                    if (FP_GETH(chn->chPos) <= chn->chLoopS)
+                    if (chn->chPos.dw <= chn->chLoopS.dw)
                     {
                         DMFixedPoint diff;
-                        FP_SETHL(diff, chn->chLoopE - chn->chLoopS, 0);
+                        FP_SUB_R(diff, chn->chLoopE, chn->chLoopS);
                         FP_ADD(chn->chPos, diff);
                     }
                 }
@@ -312,7 +310,7 @@
             else
             {
                 // Normal (non-looped) sample
-                if (FP_GETH(chn->chPos) <= 0)
+                if (chn->chPos.dw <= 0)
                 {
                     chn->chPlaying = FALSE;
                     return;
@@ -326,13 +324,13 @@
             DBG("MIX_FW[%p : %d : ", ab, mixDone);
             if (chn->chFlags & jsfLooped)
             {
-                DBG("%d (%x)] {loop}\n", chn->chLoopE, chn->chLoopE);
+                DBG("%d (%x)] {loop}\n", FP_GETH(chn->chLoopE), FP_GETH(chn->chLoopE));
                 mixResult = mixer->jvmMixChannel_FW((void *) mixer, chn,
                     ab, mixDone, chn->chLoopE);
             }
             else
             {
-                DBG("%d (%x)]\n", chn->chSize, chn->chSize);
+                DBG("%d (%x)]\n", FP_GETH(chn->chSize), FP_GETH(chn->chSize));
                 mixResult = mixer->jvmMixChannel_FW((void *) mixer, chn,
                     ab, mixDone, chn->chSize);
             }
@@ -348,9 +346,10 @@
             }
             else
             {
+                static const DMFixedPoint zero = { 0 };
                 DBG("%d (%x)]\n", 0, 0);
                 mixResult = mixer->jvmMixChannel_BW(mixer, chn,
-                    ab, mixDone, 0);
+                    ab, mixDone, zero);
             }
         }
         
@@ -518,10 +517,10 @@
     JSS_LOCK(mixer);
     c = &mixer->channels[channel];
     
+    FP_SETHL(c->chSize, size, 0);
+    FP_SETHL(c->chLoopS, loopS, 0);
+    FP_SETHL(c->chLoopE, loopE, 0);
     c->chData      = data;
-    c->chSize      = size;
-    c->chLoopS     = loopS;
-    c->chLoopE     = loopE;
     c->chFlags     = flags;
     c->chDirection = TRUE;
     c->chPos.dw    = c->chDeltaO.dw = 0;
--- a/jssmix.h	Thu Oct 11 10:24:00 2012 +0300
+++ b/jssmix.h	Thu Oct 11 11:09:26 2012 +0300
@@ -24,21 +24,20 @@
 typedef struct
 {
     DMFixedPoint
+            chSize,         // Length of sample in UNITS
+            chLoopS,        // Loop start in UNITS
+            chLoopE,        // Loop end in UNITS
+
             chPos,          // Current position in sample, 32:32 fixpoint
             chDeltaO,       // Delta in 32:32 UNSIGNED! (chDirection)
             chVolume,       // Volume
             chDeltaV,
             chPanning,      // Panning
             chDeltaP;
-
     int     chVolumeD,
             chPanningD;
 
     int     chFreq;         // Frequency of sampel in Hz
-    Sint32
-            chSize,         // Length of sample in UNITS
-            chLoopS,        // Loop start in UNITS
-            chLoopE;        // Loop end in UNITS
 
     void    *chData;        // Pointer to data
 
@@ -76,8 +75,8 @@
     void            (*cbFunction)(void *, void *);
 
     // Mixing routine pointers
-    int    (*jvmMixChannel_FW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const Sint32);
-    int    (*jvmMixChannel_BW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const Sint32);
+    int    (*jvmMixChannel_FW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const DMFixedPoint);
+    int    (*jvmMixChannel_BW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const DMFixedPoint);
     void   (*jvmPostProcess)(JMIXER_ADDBUF_TYPE *, void *, const int);
 
     // Device locking
--- a/ppl.c	Thu Oct 11 10:24:00 2012 +0300
+++ b/ppl.c	Thu Oct 11 11:09:26 2012 +0300
@@ -262,7 +262,7 @@
 
     int xc, ym = y0 + (y1 - y0) / 2, vol = FP_GETH(chn->chVolume);
     int pitch = screen->pitch / sizeof(Uint32);
-    int len = chn->chSize;
+    int len = FP_GETH(chn->chSize);
     DMFixedPoint offs = chn->chPos;
     Uint32 coln = dmCol(0.0, 0.8, 0.0), colx = dmCol(1.0, 0, 0);
     Uint32 *pix = screen->pixels;