static XGMCommand* XGMCommand_createPCMCommand(XGM* xgm, VGM* vgm, VGMCommand* command, int channel) { unsigned char* data = malloc(2); XGMSample* xgmSample; unsigned char prio; data[0] = XGM_PCM; prio = 0; if (VGMCommand_isStreamStartLong(command)) { int address; int size; Sample* vgmSample; address = VGMCommand_getStreamSampleAddress(command); size = VGMCommand_getStreamSampleSize(command); // vgmSample = VGM_getSample(vgm, address, size); vgmSample = VGM_getSample(vgm, address); // use stream id as priority prio = 3 - (VGMCommand_getStreamId(command) & 0x3); xgmSample = XGM_getSampleByAddress(xgm, address); if (vgmSample != NULL) { double len; int lenInFrame; len = VGMCommand_getStreamSampleSize(command); lenInFrame = ceil(len / ((double) vgmSample->rate / (double) vgm->rate)); } else if (!silent) printf("Warning: can't find original VGM sample for VGM command at offset %6X\n", command->offset); } else if (VGMCommand_isStreamStart(command)) { // use stream id as priority prio = 3 - (VGMCommand_getStreamId(command) & 0x3); xgmSample = XGM_getSampleByIndex(xgm, VGMCommand_getStreamBlockId(command) + 1); if (xgmSample == NULL) xgmSample = XGM_getSampleByIndex(xgm, prio + 1); } else if (VGMCommand_isStreamStop(command)) { // use stream id as priority prio = 3 - (VGMCommand_getStreamId(command) & 0x3); // stop command data[1] = 0; return XGMCommand_create(data, 2); } else { // assume stop command by default data[1] = 0; return XGMCommand_create(data, 2); } // no sample found --> use empty sample if (xgmSample == NULL) { if (!silent) printf("Warning: no corresponding sample found for VGM command at offset %6X in XGM\n", command->offset); data[1] = 0; } else data[1] = xgmSample->index; // channel == -1 --> we use inverse of priority for channel if (channel == -1) data[0] |= 3 - prio; else data[0] |= (channel & 0x3); // set prio data[0] |= prio << 2; return XGMCommand_create(data, 2); }
LList* XGMCommand_createPCMCommands(XGM* xgm, VGM* vgm, LList* commands) { LList* result; LList* src; result = NULL; src = commands; while(src != NULL) { VGMCommand* command = src->element; if (VGMCommand_isStreamStartLong(command) || VGMCommand_isStreamStart(command) || VGMCommand_isStreamStop(command)) result = insertAfterLList(result, XGMCommand_createPCMCommand(xgm, vgm, command, -1)); src = src->next; } return getHeadLList(result); }
List* XGMCommand_createPCMCommands(XGM* xgm, VGM* vgm, List* commands) { List* result; int i; // allocate result = createList(); for(i = 0; i < commands->size; i++) { VGMCommand* command = getFromList(commands, i); if (VGMCommand_isStreamStartLong(command) || VGMCommand_isStreamStart(command) || VGMCommand_isStreamStop(command)) addToList(result, XGMCommand_createPCMCommand(xgm, vgm, command, -1)); } return result; }