diff jssmod.c @ 49:033c660c25f5

Restructure module playing, removing 8bit sample mixing (output can still be 8bit, but samples are internally upconverted to 16bit after module loading.) Also prepare for floating point mixing support.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 01 Oct 2012 02:51:41 +0300
parents 064d1d1d5b0f
children 36e2f910219c
line wrap: on
line diff
--- a/jssmod.c	Mon Oct 01 01:29:26 2012 +0300
+++ b/jssmod.c	Mon Oct 01 02:51:41 2012 +0300
@@ -118,37 +118,6 @@
     return TRUE;
 }
 
-
-int jssConvertSampleFromFP(void **dst, void * src, const size_t len, const int flags)
-{
-    // Convert from floating point to 8/16bit
-    size_t count = len;
-    float *in = (float *) src;
-    
-    if (flags & jsf16bit)
-    {
-        Sint16 *out;
-        *dst = out = dmMalloc(sizeof(sizeof(Sint16)) * len);
-        if (out == NULL)
-            return DMERR_MALLOC;
-
-        while (count--)
-            *(out++) = (*(in++) * 32767.0f);
-    }
-    else
-    {
-        Uint8 *out;
-        *dst = out = dmMalloc(sizeof(sizeof(Uint8)) * len);
-        if (out == NULL)
-            return DMERR_MALLOC;
-
-        while (count--)
-            *(out++) = 128 + (int) (*(in++) * 127.0f);
-    }
-    
-    return DMERR_OK;
-}
-
 #endif
 
 
@@ -228,10 +197,11 @@
     return TRUE;
 }
 
-
+#ifdef JSS_MIX_FP
+/* Convert sample data from S16 or U8 to floating point
+ */
 int jssConvertSampleToFP(void **dst, void * src, const size_t len, const int flags)
 {
-    // Convert from 8/16bit to floating point
     size_t count = len;
     float *out;
 
@@ -243,13 +213,86 @@
     {
         Sint16 *in = (Sint16 *) src;
         while (count--)
+        {
             *(out++) = (float) (*(in++)) / 32768.0f;
+        }
     }
     else
     {
         Uint8 *in = (Uint8 *) src;
         while (count--)
+        {
             *(out++) = (float) (*(in++) - 128) / 128.0f;
+        }
+    }
+    
+    return DMERR_OK;
+}
+
+#endif
+
+/* Convert sample data from U8 to S16
+ */
+int jssConvertSampleTo16(void **dst, void * src, const size_t len)
+{
+    size_t count = len;
+    Uint8 *in = (Uint8 *) src;
+    Sint16 *out;
+
+    *dst = out = dmMalloc(sizeof(Sint16) * len);
+    if (out == NULL)
+        return DMERR_MALLOC;
+    
+    while (count--)
+    {
+        *(out++) = (*(in++) * 256) - 32768;
+    }
+    
+    return DMERR_OK;
+}
+
+/* Converts the given module in preparation for playing it.
+ * This involves sample format conversion (8 to 16 bit, or
+ * if floating point mixing is enabled, 8/16 bit to FP.)
+ *
+ * NOTICE! The converted module can only be saved in JSSMOD
+ * format, but this is not recommended.
+ */
+int jssConvertModuleForPlaying(JSSModule *module)
+{
+    int i;
+    if (module == NULL)
+        return DMERR_NULLPTR;
+
+    // Convert instruments
+    for (i = 0; i < module->ninstruments; i++)
+    {
+        JSSInstrument *inst = module->instruments[i];
+        if (inst != NULL && inst->data != NULL)
+        {
+            int res;
+            void *data = NULL;
+#ifdef JSS_MIX_FP
+            if (inst->flags & jsfFP)
+                continue;
+
+            if ((res = jssConvertSampleToFP(&data, inst->data, inst->size, inst->flags)) != DMERR_OK)
+                return res;
+            
+            inst->flags &= !(jsf16bit);
+            inst->flags |= jfsFP;
+#else
+            if (inst->flags & jsf16bit)
+                continue;
+
+            if ((res = jssConvertSampleTo16(&data, inst->data, inst->size)) != DMERR_OK)
+                return res;
+
+            inst->flags |= jsf16bit;
+#endif
+            dmFree(inst->data);
+            inst->data = data;
+        }
     }
     
     return DMERR_OK;