XGM* XGM_createFromData(unsigned char* data, int dataSize) { int s; XGM* result = XGM_create(); if (!silent) printf("Parsing XGM file...\n"); if (strncasecmp(&data[0x00], "XGM ", 4)) { printf("Error: XGM file not recognized !\n"); return NULL; } // sample id table LList* samples = NULL; for (s = 1; s < 0x40; s++) { int offset = getInt16(data, (s * 4) + 0); int len = getInt16(data, (s * 4) + 2); // ignore empty sample if ((offset != 0xFFFF) && (len != 0x0100)) { offset <<= 8; len <<= 8; // add sample samples = insertAfterLList(samples, XGMSample_create(s, data + (offset + 0x104), len, offset)); } } result->samples = getHeadLList(samples); // calculate music data offset (sample block size + 0x104) int offset = (getInt16(data, 0x100) << 8) + 0x104; // int version = data[0x102]; result->pal = data[0x103] & 1; // get music data length int len = getInt(data, offset); if (verbose) { printf("XGM sample number: %d\n", getSizeLList(result->samples)); printf("XGM start music data: %6X len: %d\n", offset + 4, len); } // build command list XGM_parseMusic(result, data + offset + 4, len); if (!silent) printf("XGM duration: %d frames (%d seconds)\n", XGM_computeLenInFrame(result), XGM_computeLenInSecond(result)); // GD3 tags ? if (data[0x103] & 2) result->gd3 = GD3_createFromData(data + offset + 4 + len); return result; }
XGM* XGC_create(XGM* xgm) { XGM* result = XGM_create(); LList* s; LList* d; if (!silent) printf("Converting to XGC...\n"); // copy pal/ntsc information result->pal = xgm->pal; // simple copy for sample s = xgm->samples; d = result->samples; while(s != NULL) { XGMSample* sample = s->element; d = insertAfterLList(d, sample); s = s->next; } result->samples = getHeadLList(d); // and extract music data XGC_extractMusic(result, xgm); // shift all samples to 2 frames for PAL and 3 frames ahead for NTSC (because of PCM buffer length) if (result->pal) XGC_shiftSamples(result, 2); else XGC_shiftSamples(result, 3); // display play PCM command // if (verbose) // { // LList* curCom = result->commands; // while(curCom != NULL) // { // XGMCommand* command = curCom->element; // // if (XGCCommand_isPCM(command)) // printf("play sample %2X at frame %d\n", XGCCommand_getPCMId(command), XGC_getTimeInFrame(result, command)); // // curCom = curCom->next; // } // } if (verbose) { printf("Sample size: %d\n", XGM_getSampleDataSize(result)); printf("Music data size: %d\n", XGM_getMusicDataSize(result)); printf("Number of sample: %d\n", getSizeLList(result->samples)); } if (!silent) printf("XGC duration: %d frames (%d seconds)\n", XGC_computeLenInFrame(result), XGC_computeLenInSecond(result)); return result; }
XGM* XGM_createFromVGM(VGM* vgm) { XGM* result = XGM_create(); if (!silent) printf("Converting VGM to XGM...\n"); if (vgm->rate == 60) result->pal = 0; else if (vgm->rate == 50) result->pal = 1; else result->pal = -1; result->gd3 = vgm->gd3; // extract samples from VGM XGM_extractSamples(result, vgm); // and extract music data XGM_extractMusic(result, vgm); // display play PCM command // if (verbose) // { // LList* curCom = result->commands; // while(curCom != NULL) // { // XGMCommand* command = curCom->element; // // if (XGMCommand_isPCM(command)) // printf("play sample %2X at frame %d\n", XGMCommand_getPCMId(command), XGM_getTimeInFrame(result, command)); // // curCom = curCom->next; // } // } if (verbose) { printf("XGM sample number: %d\n", getSizeLList(result->samples)); printf("Sample size: %d\n", XGM_getSampleDataSize(result)); printf("Music data size: %d\n", XGM_getMusicDataSize(result)); } if (!silent) printf("XGM duration: %d frames (%d seconds)\n", XGM_computeLenInFrame(result), XGM_computeLenInSecond(result)); return result; }