diff jssmod.c @ 0:32250b436bca

Initial re-import.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 28 Sep 2012 01:54:23 +0300
parents
children 048536ad01e0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jssmod.c	Fri Sep 28 01:54:23 2012 +0300
@@ -0,0 +1,380 @@
+/*
+ * miniJSS - Module structure and handling routines
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2006-2007 Tecnic Software productions (TNSP)
+ */
+#include "jssmod.h"
+#include <string.h>
+
+
+#ifndef JSS_LIGHT
+/* Take given data until maxlen reached, make a string
+ */
+char *jssASCIItoStr(char * sdata, const char endByte, const size_t maxLen)
+{
+    size_t i, k;
+    char *res;
+
+    for (i = 0; sdata[i] && i < maxLen; i++);
+
+    res = (char *) dmMalloc(i + 1);
+    if (res == NULL)
+        return NULL;
+
+    for (k = 0; sdata[k] != endByte && k < i; k++)
+        res[k] = sdata[k];
+
+    res[k] = 0;
+
+    return res;
+}
+
+
+/* Encodes a given 8-bit sample
+ */
+BOOL jssEncodeSample8(Uint8 * sdata, const size_t srcSize, const int ops)
+{
+    size_t ssize = srcSize;
+    Sint8 t, value = 0;
+    
+    while (ssize--)
+    {
+        t = *sdata;
+        
+        if (ops & jsampFlipSign)
+            t ^= 0x80;
+
+        if (ops & jsampDelta)
+        {
+            int n = t - value;
+            value = t;
+            t = n;
+        }
+        
+        *(sdata++) = t;
+    }
+
+    return TRUE;
+}
+
+
+/* Decodes a given 16-bit sample
+ */
+BOOL jssEncodeSample16(Uint16 * srcData, const size_t srcSize, const int ops)
+{
+    // "Split" the 16-bit samples into 8-bit halves
+    if (ops & jsampSplit)
+    {
+        // Allocate temporary processing buffer
+        size_t ssize, bufSize = srcSize * sizeof(Sint16);
+        Uint8 *bp1, *bp2;
+        Sint16 t, *sdata, *tmpBuf = dmMalloc(bufSize);
+        if (tmpBuf == NULL) return FALSE;
+
+        sdata = tmpBuf;
+        bp1 = (Uint8 *) srcData;
+        bp2 = bp1 + srcSize;
+        ssize = srcSize;
+
+        while (ssize--)
+        {
+            t = (*sdata++);
+            *bp1++ = t >> 8;
+            *bp2++ = t & 0xff;
+        }
+        
+        memcpy(srcData, tmpBuf, bufSize);
+        dmFree(tmpBuf);
+        
+        return jssEncodeSample8((Uint8 *) srcData, bufSize, ops);
+    }
+    else
+    {
+        Sint16 t, p, value = 0, *sdata = (Sint16 *) srcData;
+        size_t ssize = srcSize;
+        
+        while (ssize--)
+        {
+            if (ops & jsampSwapEndianess)
+            {
+                p = *sdata;
+                t = ((p >> 8) & 0xff) | ((p & 0xff) << 8);
+            } else
+                t = *sdata;
+            
+            if (ops & jsampDelta)
+            {
+                int n = t - value;
+                value = t;
+                t = n;
+            }
+            
+            if (ops & jsampFlipSign)
+                t ^= 0x8000;
+            
+            *(sdata++) = t;
+        }
+    }
+    return TRUE;
+}
+#endif
+
+
+/* Decodes a given 8-bit sample
+ */
+BOOL jssDecodeSample8(Uint8 * sdata, const size_t srcSize, const int ops)
+{
+    size_t ssize = srcSize;
+    Sint8 t, value = 0;
+    
+    while (ssize--)
+    {
+        t = *sdata;
+        
+        if (ops & jsampDelta)
+            t = value = t + value;
+        
+        if (ops & jsampFlipSign)
+            t ^= 0x80;
+        
+        *(sdata++) = t;
+    }
+    return TRUE;
+}
+
+
+/* Decodes a given 16-bit sample
+ */
+BOOL jssDecodeSample16(Uint16 * srcData, const size_t srcSize, const int ops)
+{
+    if (ops & jsampSplit)
+    {
+        size_t ssize, bufSize = srcSize * sizeof(Uint16);
+        Uint8 *bp1, *bp2;
+        Sint16 *tmpBuf, *sdata;
+        
+        if (!jssDecodeSample8((Uint8 *) srcData, bufSize, ops))
+            return FALSE;
+        
+        tmpBuf = dmMalloc(bufSize);
+        if (tmpBuf == NULL) return FALSE;
+        memcpy(tmpBuf, srcData, bufSize);
+        
+        sdata = (Sint16 *) srcData;
+        bp1 = (Uint8 *) tmpBuf;
+        bp2 = bp1 + srcSize;
+        ssize = srcSize;
+        while (ssize--)
+        {
+            *sdata++ = (*bp1++ << 8) | (*bp2++ & 0xff);
+        }
+        
+        dmFree(tmpBuf);
+    }
+    else
+    {
+        Sint16 t, p, value = 0, *sdata = (Sint16 *) srcData;
+        size_t ssize = srcSize;
+        while (ssize--)
+        {
+            if (ops & jsampSwapEndianess)
+            {
+                p = *sdata;
+                t = ((p >> 8) & 0xff) | ((p & 0xff) << 8);
+            } else
+                t = *sdata;
+            
+            if (ops & jsampDelta)
+                t = value = t + value;
+            
+            if (ops & jsampFlipSign)
+                t ^= 0x8000;
+            
+            *(sdata++) = t;
+        }
+    }
+    return TRUE;
+}
+
+
+/* Allocates a new module structure or returns errorvalue if failed.
+ * Memory is allocated only for the basic structure. Sample- and pattern
+ * areas must be allocated separately with appropriate routines.
+ */
+JSSModule *jssAllocateModule(void)
+{
+    int i;
+    JSSModule *module;
+
+    // Allocate module structure
+    module = dmMalloc0(sizeof(JSSModule));
+    if (module == NULL)
+        return NULL;
+
+    // Initialize structure
+    for (i = 0; i < jsetNChannels; i++)
+        module->defPanning[i] = jchPanMiddle;
+
+    for (i = 0; i < jsetMaxOrders; i++)
+        module->orderList[i] = jsetOrderEnd;
+
+    // Allocate mutex
+#ifdef JSS_SUP_THREADS
+    module->mutex = dmCreateMutex();
+#endif
+
+    return module;
+}
+
+
+/* Frees a given module structure, freeing all memory areas
+ * that were allocated for it (including patterns, samples, etc.)
+ */
+int jssFreeModule(JSSModule * module)
+{
+    int i;
+
+    if (module == NULL)
+        return DMERR_NULLPTR;
+    
+    // Free strings
+#ifndef JSS_LIGHT
+    dmFree(module->moduleName);
+    dmFree(module->trackerName);
+#endif
+
+    // Free patterns
+    for (i = 0; i < module->npatterns; i++)
+    {
+        if (module->patterns[i])
+        {
+            JSSPattern *pat = module->patterns[i];
+            dmFree(pat->data);
+            dmFree(pat);
+            module->patterns[i] = NULL;
+        }
+    }
+
+    // Free instruments
+    for (i = 0; i < module->ninstruments; i++)
+    {
+        if (module->instruments[i])
+        {
+            JSSInstrument *inst = module->instruments[i];
+#ifndef JSS_LIGHT
+            dmFree(inst->desc);
+#endif
+            dmFree(inst->data);
+            dmFree(inst);
+            module->instruments[i] = NULL;
+        }
+    }
+
+    // Free extended instruments
+    for (i = 0; i < module->nextInstruments; i++)
+    {
+        if (module->extInstruments[i])
+        {
+            JSSExtInstrument *ext = module->extInstruments[i];
+#ifndef JSS_LIGHT
+            dmFree(ext->desc);
+#endif
+            dmFree(ext);
+            module->extInstruments[i] = NULL;
+        }
+    }
+
+    // Free mutex
+#ifdef JSS_SUP_THREADS
+    dmDestroyMutex(module->mutex);
+#endif
+    
+    // Free the module structure
+    memset(module, 0, sizeof(JSSModule));
+    dmFree(module);
+
+    return DMERR_OK;
+}
+
+
+/* Allocates and initializes a internal pattern structure.
+ */
+JSSPattern *jssAllocatePattern(int nrows, int nchannels)
+{
+    int i, j;
+    JSSPattern *res;
+    JSSNote *pnote;
+
+    // Check arguments
+    if (nrows <= 0 || nchannels <= 0)
+        JSSERROR(DMERR_INVALID_ARGS, NULL, "Invalid nrows=%i or nchannels=%i.\n", nrows, nchannels);
+
+    // Allocate a pattern structure
+    res = dmMalloc0(sizeof(JSSPattern));
+    if (res == NULL)
+        JSSERROR(DMERR_MALLOC, NULL, "Could not allocate pattern structure.\n");
+
+    // Allocate notedata
+    res->data = dmCalloc(nrows * nchannels, sizeof(JSSNote));
+    if (res->data == NULL)
+    {
+        dmFree(res);
+        JSSERROR(DMERR_MALLOC, NULL, "Could not allocate pattern data (nrows=%i, nchannels=%i).\n", nrows,
+             nchannels);
+    }
+
+    // Initialize
+    res->nrows = nrows;
+    res->nchannels = nchannels;
+
+    pnote = res->data;
+    for (j = 0; j < nrows; j++)
+    {
+        for (i = 0; i < nchannels; i++)
+        {
+            pnote->note = pnote->instrument = pnote->volume =
+                pnote->effect = pnote->param = jsetNotSet;
+
+            pnote++;
+        }
+    }
+
+    // OK, return pointer to struct
+    return res;
+}
+
+
+/* Allocates and initializes internal "normal" instrument structure.
+ */
+JSSInstrument *jssAllocateInstrument(void)
+{
+    JSSInstrument *res;
+
+    // Allocate a instrument structure
+    res = dmMalloc0(sizeof(JSSInstrument));
+    if (res == NULL)
+        return NULL;
+
+    return res;
+}
+
+
+/* Allocates and initializes "extended" instrument structure.
+ */
+JSSExtInstrument *jssAllocateExtInstrument(void)
+{
+    int i;
+    JSSExtInstrument *res;
+
+    // Allocate a instrument structure
+    res = dmMalloc0(sizeof(JSSExtInstrument));
+    if (res == NULL)
+        return NULL;
+
+    for (i = 0; i < jsetNNotes; i++)
+    {
+        res->sNumForNotes[i] = jsetNotSet;
+    }
+    
+    return res;
+}