LList* insertAllBeforeLList(LList* linkedElement, LList* elements) { LList* src = getTailLList(elements); LList* dst = linkedElement; while(src != NULL) { dst = insertBeforeLList(dst, src->element); src = src->prev; } // return last inserted element return dst; }
static void XGM_extractSamples(XGM* xgm, VGM* vgm) { int index; LList* sampleXgm; // index should be equal to current size + 1 index = getSizeLList(xgm->samples) + 1; sampleXgm = getTailLList(xgm->samples); // extract samples LList* b = vgm->sampleBanks; while(b != NULL) { SampleBank* sampleBank = b->element; LList* s = sampleBank->samples; // can't have more than 64 samples in XGM music while((s != NULL) && (index < 64)) { XGMSample* sample = XGMSample_createFromVGMSample(sampleBank, s->element); // valid sample if (sample != NULL) { sample->index = index++; sampleXgm = insertAfterLList(sampleXgm, sample); } s = s->next; } // can't extract all samples (XGM music doesn't not support more than 63 samples) if ((s != NULL) && (index >= 64)) { if (!silent) { printf("Error: XGM does not support music with more than 63 samples !\n"); printf("Input VGM file probably has improper PCM data extraction, try to use another VGM source.\n"); } // interrupt sample extraction break; } b = b->next; } xgm->samples = getHeadLList(sampleXgm); }
void XGC_shiftSamples(XGM* source, int sft) { int i; if (sft == 0) return; XGMCommand* loopCommand = XGM_getLoopCommand(source); XGMCommand* loopPointedCommand = XGM_getLoopPointedCommand(source); LList* sampleCommands[sft]; LList* loopSampleCommands[sft]; for (i = 0; i < sft; i++) { sampleCommands[i] = NULL; loopSampleCommands[i] = NULL; } int loopFrameIndex = sft; int frameRead = 0; int frameWrite = 0; LList* com = getTailLList(source->commands); while (com != NULL) { XGMCommand* command = com->element; // this is the command pointed by the loop if (command == loopPointedCommand) loopFrameIndex = 0; if (XGMCommand_isPCM(command)) { sampleCommands[frameRead] = insertAfterLList(sampleCommands[frameRead], command); removeFromLList(com); } else if (XGCCommand_isFrameSize(command)) { frameRead = (frameRead + 1) % sft; frameWrite = (frameWrite + 1) % sft; // add sample commands stored for this frame while (sampleCommands[frameWrite] != NULL) { // get current sample XGMCommand* sampleCommand = sampleCommands[frameWrite]->element; // next sample to store sampleCommands[frameWrite] = sampleCommands[frameWrite]->prev; // insert sample command just before current frame (and bypass it) com = insertBeforeLList(com, sampleCommand); // store for the loop samples restore if (loopFrameIndex < sft) loopSampleCommands[loopFrameIndex] = insertAfterLList(loopSampleCommands[loopFrameIndex], XGCCommand_createFromCommand(sampleCommand)); } loopFrameIndex++; } com = com->prev; } // add last remaining samples com = source->commands; for (i = 0; i < sft; i++) { while (sampleCommands[i] != NULL) { insertAfterLList(com, sampleCommands[i]->element); // next sample to store sampleCommands[i] = sampleCommands[i]->prev; } } com = getTailLList(source->commands); // avoid the last command (end or loop) if (com != NULL) com = com->prev; loopFrameIndex = 0; while (loopFrameIndex < sft) { XGMCommand* command = com->element; if (XGCCommand_isFrameSize(command)) { // add sample command to previous frame while (loopSampleCommands[loopFrameIndex] != NULL) { XGMCommand* sampleCommand = loopSampleCommands[loopFrameIndex]->element; // next sample to store loopSampleCommands[loopFrameIndex] = loopSampleCommands[loopFrameIndex]->prev; // add sample command to current frame insertAfterLList(com, sampleCommand); } loopFrameIndex++; } com = com->prev; } // recompute offset & frame size XGC_computeAllOffset(source); XGC_computeAllFrameSize(source); // fix address in loop command if ((loopCommand != NULL) && (loopPointedCommand != NULL)) { int offset = loopPointedCommand->offset; loopCommand->data[1] = offset >> 0; loopCommand->data[2] = offset >> 8; loopCommand->data[3] = offset >> 16; }