changeset 1130:725e7caa43a0

Split instrument sample data loading to another function in XM loader.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 04 Mar 2015 06:32:19 +0200
parents e466d10dae6d
children b349646f19a0
files minijss/jloadxm.c
diffstat 1 files changed, 179 insertions(+), 172 deletions(-) [+]
line wrap: on
line diff
--- a/minijss/jloadxm.c	Wed Mar 04 06:31:54 2015 +0200
+++ b/minijss/jloadxm.c	Wed Mar 04 06:32:19 2015 +0200
@@ -403,12 +403,65 @@
 }
 
 
+static int jssXMLoadInstrumentData(DMResource *inFile, JSSInstrument *inst, int ninst, int nsample)
+{
+    int ret;
+
+    JSSDEBUG("desc....: '%s'\n"
+         "size....: %d\n"
+         "loopS...: %d\n"
+         "loopE...: %d\n"
+         "volume..: %d\n"
+         "flags...: %x\n",
+         inst->desc,
+         inst->size, inst->loopS, inst->loopE,
+         inst->volume, inst->flags);
+
+    if (inst->flags & jsf16bit)
+    {
+        // Read sampledata
+        if (dmfread(inst->data, sizeof(Uint16), inst->size, inFile) != (size_t) inst->size)
+            JSSERROR(DMERR_FREAD, DMERR_FREAD,
+            "Error reading sampledata for instrument #%d/%d, %d words.\n",
+            ninst, nsample, inst->size);
+
+        // Convert data
+        if ((ret = jssDecodeSample16((Uint16 *) inst->data, inst->size,
+#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+            (jsampDelta | jsampSwapEndianess)
+#else
+            (jsampDelta)
+#endif
+            )) != DMERR_OK)
+            return ret;
+    }
+    else
+    {
+        // Read sampledata
+        if (dmfread(inst->data, sizeof(Uint8), inst->size, inFile) != (size_t) inst->size)
+            JSSERROR(DMERR_FREAD, DMERR_FREAD,
+            "Error reading sampledata for instrument #%d/%d, %d bytes.\n",
+            ninst, nsample, inst->size);
+
+        // Convert data
+        if ((ret = jssDecodeSample8((Uint8 *) inst->data, inst->size,
+            (jsampDelta | jsampFlipSign))) != DMERR_OK)
+            return ret;
+    }
+    return DMERR_OK;
+}
+
+
 /* Load XM-format extended instrument from file-stream into JSS module's given inst
  */
 static int jssXMLoadExtInstrument(DMResource *inFile, int ninst, JSSModule *module)
 {
     XMInstrument1 xmI1;
     off_t remainder, pos = dmftell(inFile);
+    int xmConvTable[XM_MaxInstruments + 1];
+    JSSExtInstrument *pEInst;
+    XMInstrument2 xmI2;
+    int i, nsample, ret;
 
     // Get instrument header #1
     if (!dmf_read_le32(inFile, &xmI1.headSize) ||
@@ -418,178 +471,7 @@
         return DMERR_FREAD;
 
     // If there are samples, there is header #2
-    if (xmI1.nsamples > 0)
-    {
-        int i, nsample, tmp;
-        int xmConvTable[XM_MaxInstruments + 1];
-        JSSExtInstrument *pEInst;
-        XMInstrument2 xmI2;
-
-        // Allocate instrument
-        if ((pEInst = jssAllocateExtInstrument()) == NULL)
-        {
-            JSSERROR(DMERR_MALLOC, DMERR_MALLOC,
-            "Could not allocate extended instrument structure #%d\n", ninst);
-        }
-
-        module->extInstruments[ninst] = pEInst;
-
-        // Get instrument header #2
-        if (!dmf_read_le32(inFile, &xmI2.headSize) ||
-            !dmf_read_str(inFile, &xmI2.sNumForNotes, sizeof(xmI2.sNumForNotes)))
-        {
-            JSSERROR(DMERR_FREAD, DMERR_FREAD,
-            "Could not read secondary instrument header #1 for #%d.\n", ninst);
-        }
-
-        for (i = 0; i < XM_MaxEnvPoints; i++)
-        {
-            dmf_read_le16(inFile, &xmI2.volumeEnv.points[i].frame);
-            dmf_read_le16(inFile, &xmI2.volumeEnv.points[i].value);
-        }
-
-        for (i = 0; i < XM_MaxEnvPoints; i++)
-        {
-            dmf_read_le16(inFile, &xmI2.panningEnv.points[i].frame);
-            dmf_read_le16(inFile, &xmI2.panningEnv.points[i].value);
-        }
-
-        if (!dmf_read_byte(inFile, &xmI2.volumeEnv.npoints) ||
-            !dmf_read_byte(inFile, &xmI2.panningEnv.npoints) ||
-
-            !dmf_read_byte(inFile, &xmI2.volumeEnv.sustain) ||
-            !dmf_read_byte(inFile, &xmI2.volumeEnv.loopS) ||
-            !dmf_read_byte(inFile, &xmI2.volumeEnv.loopE) ||
-
-            !dmf_read_byte(inFile, &xmI2.panningEnv.sustain) ||
-            !dmf_read_byte(inFile, &xmI2.panningEnv.loopS) ||
-            !dmf_read_byte(inFile, &xmI2.panningEnv.loopE) ||
-
-            !dmf_read_byte(inFile, &xmI2.volumeEnv.flags) ||
-            !dmf_read_byte(inFile, &xmI2.panningEnv.flags) ||
-
-            !dmf_read_byte(inFile, &xmI2.vibratoType) ||
-            !dmf_read_byte(inFile, &xmI2.vibratoSweep) ||
-            !dmf_read_byte(inFile, &xmI2.vibratoDepth) ||
-            !dmf_read_byte(inFile, &xmI2.vibratoRate) ||
-
-            !dmf_read_le16(inFile, &xmI2.fadeOut) ||
-            !dmf_read_le16(inFile, &xmI2.ARESERVED))
-        {
-            JSSERROR(DMERR_FREAD, DMERR_FREAD,
-            "Could not read secondary instrument header #2 for #%d.\n", ninst);
-        }
-
-        // Skip the extra data after header #2
-        remainder = xmI1.headSize - (dmftell(inFile) - pos);
-        if (remainder > 0)
-        {
-            JSSDEBUG("xmI1#1 Skipping: %li\n", remainder);
-            dmfseek(inFile, remainder, SEEK_CUR);
-        }
-
-        // Check and convert all ext instrument information
-#ifndef JSS_LIGHT
-        pEInst->desc = jssASCIItoStr(xmI1.instName, 0, sizeof(xmI1.instName));
-#endif
-        jssXMConvertEnvelope(&pEInst->volumeEnv, &xmI2.volumeEnv, "vol", ninst);
-        jssXMConvertEnvelope(&pEInst->panningEnv, &xmI2.panningEnv, "pan", ninst);
-
-        switch (xmI2.vibratoType)
-        {
-            case 0: pEInst->vibratoType = jvibSine; break;
-            case 1: pEInst->vibratoType = jvibRamp; break;
-            case 2: pEInst->vibratoType = jvibSquare; break;
-            case 3: pEInst->vibratoType = jvibRandom; break;
-            default:
-                pEInst->vibratoType = jvibSine;
-                JSSWARNING(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
-                "Invalid extinstrument vibrato type %d for inst #%d\n", ninst);
-                break;
-        }
-        pEInst->vibratoSweep = xmI2.vibratoSweep;
-        pEInst->vibratoDepth = xmI2.vibratoDepth;
-        pEInst->vibratoRate  = xmI2.vibratoRate;
-        pEInst->fadeOut      = xmI2.fadeOut;
-        pEInst->nsamples     = xmI1.nsamples;
-
-        // Initialize the SNumForNotes conversion table
-        for (i = 0; i < XM_MaxInstruments; i++)
-            xmConvTable[i] = jsetNotSet;
-
-        // Read sample headers
-        for (nsample = 0; nsample < xmI1.nsamples; nsample++)
-        {
-            int result;
-            if ((result = jssXMLoadInstrument(inFile, module, ninst, nsample, xmConvTable)) != DMERR_OK)
-                return result;
-        }
-
-        // Read sample data
-        for (nsample = 0; nsample < xmI1.nsamples; nsample++)
-        if (xmConvTable[nsample] != jsetNotSet)
-        {
-            JSSInstrument *inst = module->instruments[xmConvTable[nsample]];
-            if (inst)
-            {
-                JSSDEBUG("desc....: '%s'\n"
-                     "size....: %d\n"
-                     "loopS...: %d\n"
-                     "loopE...: %d\n"
-                     "volume..: %d\n"
-                     "flags...: %x\n",
-                     inst->desc,
-                     inst->size, inst->loopS, inst->loopE,
-                     inst->volume, inst->flags);
-
-                if (inst->flags & jsf16bit)
-                {
-                    // Read sampledata
-                    if (dmfread(inst->data, sizeof(Uint16), inst->size, inFile) != (size_t) inst->size)
-                        JSSERROR(DMERR_FREAD, DMERR_FREAD,
-                        "Error reading sampledata for instrument #%d/%d, %d words.\n",
-                        ninst, nsample, inst->size);
-
-                    // Convert data
-                    jssDecodeSample16((Uint16 *) inst->data, inst->size,
-#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
-                               (jsampDelta | jsampSwapEndianess)
-#else
-                               (jsampDelta)
-#endif
-                    );
-                }
-                else
-                {
-                    // Read sampledata
-                    if (dmfread(inst->data, sizeof(Uint8), inst->size, inFile) != (size_t) inst->size)
-                        JSSERROR(DMERR_FREAD, DMERR_FREAD,
-                        "Error reading sampledata for instrument #%d/%d, %d bytes.\n",
-                        ninst, nsample, inst->size);
-
-                    // Convert data
-                    jssDecodeSample8((Uint8 *) inst->data, inst->size,
-                        (jsampDelta | jsampFlipSign));
-                }
-            }
-        }
-
-        // Apply new values to sNumForNotes values
-        for (i = 0; i < XM_MaxNotes; i++)
-        {
-            tmp = xmI2.sNumForNotes[i];
-            if (tmp >= 0 && tmp < xmI1.nsamples)
-                pEInst->sNumForNotes[i] = xmConvTable[tmp];
-            else
-            {
-                pEInst->sNumForNotes[i] = jsetNotSet;
-                JSSWARNING(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
-                "Ext.instrument #%d sNumForNotes[%d] out of range (%d).\n",
-                ninst, i, tmp);
-            }
-        }
-    }
-    else
+    if (xmI1.nsamples == 0)
     {
         // We may STILL need to skip extra data after 1st instr. header
         remainder = xmI1.headSize - (dmftell(inFile) - pos);
@@ -598,6 +480,131 @@
             JSSDEBUG("xmI1#2 Skipping: %li\n", remainder);
             dmfseek(inFile, remainder, SEEK_CUR);
         }
+        return DMERR_OK;
+    }
+
+    // Allocate instrument
+    if ((pEInst = jssAllocateExtInstrument()) == NULL)
+    {
+        JSSERROR(DMERR_MALLOC, DMERR_MALLOC,
+        "Could not allocate extended instrument structure #%d\n", ninst);
+    }
+
+    module->extInstruments[ninst] = pEInst;
+
+    // Get instrument header #2
+    if (!dmf_read_le32(inFile, &xmI2.headSize) ||
+        !dmf_read_str(inFile, &xmI2.sNumForNotes, sizeof(xmI2.sNumForNotes)))
+    {
+        JSSERROR(DMERR_FREAD, DMERR_FREAD,
+        "Could not read secondary instrument header #1 for #%d.\n", ninst);
+    }
+
+    for (i = 0; i < XM_MaxEnvPoints; i++)
+    {
+        dmf_read_le16(inFile, &xmI2.volumeEnv.points[i].frame);
+        dmf_read_le16(inFile, &xmI2.volumeEnv.points[i].value);
+    }
+
+    for (i = 0; i < XM_MaxEnvPoints; i++)
+    {
+        dmf_read_le16(inFile, &xmI2.panningEnv.points[i].frame);
+        dmf_read_le16(inFile, &xmI2.panningEnv.points[i].value);
+    }
+
+    if (!dmf_read_byte(inFile, &xmI2.volumeEnv.npoints) ||
+        !dmf_read_byte(inFile, &xmI2.panningEnv.npoints) ||
+
+        !dmf_read_byte(inFile, &xmI2.volumeEnv.sustain) ||
+        !dmf_read_byte(inFile, &xmI2.volumeEnv.loopS) ||
+        !dmf_read_byte(inFile, &xmI2.volumeEnv.loopE) ||
+
+        !dmf_read_byte(inFile, &xmI2.panningEnv.sustain) ||
+        !dmf_read_byte(inFile, &xmI2.panningEnv.loopS) ||
+        !dmf_read_byte(inFile, &xmI2.panningEnv.loopE) ||
+
+        !dmf_read_byte(inFile, &xmI2.volumeEnv.flags) ||
+        !dmf_read_byte(inFile, &xmI2.panningEnv.flags) ||
+
+        !dmf_read_byte(inFile, &xmI2.vibratoType) ||
+        !dmf_read_byte(inFile, &xmI2.vibratoSweep) ||
+        !dmf_read_byte(inFile, &xmI2.vibratoDepth) ||
+        !dmf_read_byte(inFile, &xmI2.vibratoRate) ||
+
+        !dmf_read_le16(inFile, &xmI2.fadeOut) ||
+        !dmf_read_le16(inFile, &xmI2.ARESERVED))
+    {
+        JSSERROR(DMERR_FREAD, DMERR_FREAD,
+        "Could not read secondary instrument header #2 for #%d.\n", ninst);
+    }
+
+    // Skip the extra data after header #2
+    remainder = xmI1.headSize - (dmftell(inFile) - pos);
+    if (remainder > 0)
+    {
+        JSSDEBUG("xmI1#1 Skipping: %li\n", remainder);
+        dmfseek(inFile, remainder, SEEK_CUR);
+    }
+
+    // Check and convert all ext instrument information
+#ifndef JSS_LIGHT
+    pEInst->desc = jssASCIItoStr(xmI1.instName, 0, sizeof(xmI1.instName));
+#endif
+    jssXMConvertEnvelope(&pEInst->volumeEnv, &xmI2.volumeEnv, "vol", ninst);
+    jssXMConvertEnvelope(&pEInst->panningEnv, &xmI2.panningEnv, "pan", ninst);
+
+    switch (xmI2.vibratoType)
+    {
+        case 0: pEInst->vibratoType = jvibSine; break;
+        case 1: pEInst->vibratoType = jvibRamp; break;
+        case 2: pEInst->vibratoType = jvibSquare; break;
+        case 3: pEInst->vibratoType = jvibRandom; break;
+        default:
+            pEInst->vibratoType = jvibSine;
+            JSSWARNING(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
+            "Invalid extinstrument vibrato type %d for inst #%d\n", ninst);
+            break;
+    }
+    pEInst->vibratoSweep = xmI2.vibratoSweep;
+    pEInst->vibratoDepth = xmI2.vibratoDepth;
+    pEInst->vibratoRate  = xmI2.vibratoRate;
+    pEInst->fadeOut      = xmI2.fadeOut;
+    pEInst->nsamples     = xmI1.nsamples;
+
+    // Initialize the SNumForNotes conversion table
+    for (i = 0; i < XM_MaxInstruments; i++)
+        xmConvTable[i] = jsetNotSet;
+
+    // Read sample headers
+    for (nsample = 0; nsample < xmI1.nsamples; nsample++)
+    {
+        if ((ret = jssXMLoadInstrument(inFile, module, ninst, nsample, xmConvTable)) != DMERR_OK)
+            return ret;
+    }
+
+    // Read sample data
+    for (nsample = 0; nsample < xmI1.nsamples; nsample++)
+    if (xmConvTable[nsample] != jsetNotSet)
+    {
+        JSSInstrument *inst = module->instruments[xmConvTable[nsample]];
+        if ((ret = jssXMLoadInstrumentData(inFile, inst, ninst, nsample)) != DMERR_OK)
+            return ret;
+    }
+
+
+    // Apply new values to sNumForNotes values
+    for (i = 0; i < XM_MaxNotes; i++)
+    {
+        int tmp = xmI2.sNumForNotes[i];
+        if (tmp >= 0 && tmp < xmI1.nsamples)
+            pEInst->sNumForNotes[i] = xmConvTable[tmp];
+        else
+        {
+            pEInst->sNumForNotes[i] = jsetNotSet;
+            JSSWARNING(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
+            "Ext.instrument #%d sNumForNotes[%d] out of range (%d).\n",
+            ninst, i, tmp);
+        }
     }
 
     return DMERR_OK;