# HG changeset patch # User Matti Hamalainen # Date 1425443539 -7200 # Node ID 725e7caa43a0f0becc167b44f37349048f69ab26 # Parent e466d10dae6d557ab63d6881ac5d06da727d4dd1 Split instrument sample data loading to another function in XM loader. diff -r e466d10dae6d -r 725e7caa43a0 minijss/jloadxm.c --- 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;