MADErr MADFG2Mad(const char *MADPtr, size_t size, MADMusic *theMAD, MADDriverSettings *init) { short i, x; long inOutCount = 0, OffSetToSample = 0; int z = 0; bool MADConvert = false; MADFourChar oldMadIdent = 0; int finetune[16] = { 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280 }; /**** Old MADFG variables ****/ oldMADSpec *oldMAD; oldMAD = (oldMADSpec*)MADPtr; MOToldMADSpec(oldMAD); /**** HEADER ****/ oldMadIdent = oldMAD->MADIdentification; if (oldMadIdent == 'MADF') MADConvert = true; else if (oldMadIdent == 'MADG') MADConvert = false; else return MADFileNotSupportedByThisPlug; OffSetToSample += sizeof(oldMADSpec); // Conversion inOutCount = sizeof(MADSpec); theMAD->header = (MADSpec*) calloc(inOutCount, 1); if (theMAD->header == NULL) return MADNeedMemory; theMAD->header->MAD = 'MADK'; memcpy(theMAD->header->name, oldMAD->NameSignature, 32); theMAD->header->numPat = oldMAD->PatMax; theMAD->header->numChn = oldMAD->Tracks; theMAD->header->numPointers = oldMAD->numPointers; memcpy(theMAD->header->oPointers, oldMAD->oPointers, 128); theMAD->header->speed = 6; theMAD->header->tempo = 125; strncpy(theMAD->header->infos, "Converted by PlayerPRO MAD-F-G Plug (\251Antoine ROSSET <*****@*****.**>)", sizeof(theMAD->header->infos)); theMAD->sets = (FXSets*)calloc(MAXTRACK * sizeof(FXSets), 1); if (theMAD->sets == NULL) { free(theMAD->header); return MADNeedMemory; } for (i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[i].copyId = i; /**** Patterns *******/ for (i = 0; i < oldMAD->PatMax; i++) { MADFourChar CompMode = 0; struct MusicPattern *tempPat, *tempPat2; struct oldPatHeader tempPatHeader; /** Lecture du header de la partition **/ if (!MADConvert) { inOutCount = sizeof(struct oldPatHeader); memcpy(&tempPatHeader, MADPtr + OffSetToSample, inOutCount); MOToldPatHeader(&tempPatHeader); } else tempPatHeader.PatternSize = 64; /*************************************************/ /** Lecture du header + contenu de la partition **/ /*************************************************/ CompMode = tempPatHeader.CompressionMode; if (CompMode == 'MAD1') { inOutCount = sizeof(struct MusicPattern) + tempPatHeader.PatBytes; } else { inOutCount = sizeof(struct MusicPattern) + oldMAD->Tracks * tempPatHeader.PatternSize * sizeof(struct Command); } tempPat = (struct MusicPattern*)malloc(inOutCount); if (tempPat == NULL) { int y; for (y = 0; y < i; y++) { if (theMAD->partition[y]) { free(theMAD->partition[y]); } } free(theMAD->header); free(theMAD->sets); return MADNeedMemory; } if (MADConvert) { tempPat = (struct MusicPattern*)((uintptr_t) tempPat + sizeof(struct oldPatHeader)); inOutCount -= sizeof(struct oldPatHeader); } memcpy(tempPat, MADPtr + OffSetToSample, inOutCount); OffSetToSample += inOutCount; MOToldPatHeader(&tempPat->header); if (MADConvert) { tempPat = (struct MusicPattern*) ((uintptr_t) tempPat - sizeof(struct oldPatHeader)); tempPat->header.PatternSize = 64; tempPat->header.CompressionMode = 'NONE'; for (x = 0; x < 20; x++) tempPat->header.PatternName[x] = 0; tempPat->header.unused2 = 0; } if (tempPat->header.CompressionMode == 'MAD1') { tempPat2 = oldDecompressPartitionMAD1(tempPat, oldMAD->Tracks, init); free(tempPat); tempPat = tempPat2; } /**************/ /* CONVERSION */ /**************/ theMAD->partition[i] = (PatData*) calloc(sizeof(PatHeader) + theMAD->header->numChn * tempPat->header.PatternSize * sizeof(Cmd), 1); if (theMAD->partition[i] == NULL) { int y; if (tempPat) { free(tempPat); } for (y = 0; y < i; y++) { if (theMAD->partition[y]) { free(theMAD->partition[y]); } } free(theMAD->header); free(theMAD->sets); return MADNeedMemory; } theMAD->partition[i]->header.size = tempPat->header.PatternSize; theMAD->partition[i]->header.compMode = 'NONE'; memcpy(theMAD->partition[i]->header.name, tempPat->header.PatternName, 20); theMAD->partition[i]->header.patBytes = 0; theMAD->partition[i]->header.unused2 = 0; for (x = 0; x < theMAD->partition[i]->header.size; x++) { for (z = 0; z < theMAD->header->numChn; z++) { struct Command *oldCmd; Cmd *aCmd; aCmd = GetMADCommand(x, z, theMAD->partition[i]); oldCmd = GetOldCommand(x, z, tempPat); aCmd->ins = oldCmd->InstrumentNo; if (oldCmd->AmigaPeriod == 0) aCmd->note = 0xFF; else aCmd->note = oldCmd->AmigaPeriod + 22; aCmd->cmd = oldCmd->EffectCmd; aCmd->arg = oldCmd->EffectArg; aCmd->vol = 0xFF; if (aCmd->cmd == 0x0C) { aCmd->vol = 0x10 + (aCmd->arg & 0x00FF); aCmd->cmd = 0; aCmd->arg = 0; } } } free(tempPat); } for (i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[i] = NULL; for (i = 0; i < MAXTRACK; i++) { if (i % 2 == 0) theMAD->header->chanPan[i] = MAX_PANNING/4; else theMAD->header->chanPan[i] = MAX_PANNING - MAX_PANNING/4; theMAD->header->chanVol[i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; /**** Instruments header *****/ theMAD->fid = (InstrData*) calloc(sizeof(InstrData) * (long) MAXINSTRU, 1); if (!theMAD->fid) { int y; for (y = 0; y < MAXPATTERN; y++) { if (theMAD->partition[y]) { free(theMAD->partition[y]); } } free(theMAD->header); free(theMAD->sets); return MADNeedMemory; } theMAD->sample = (sData**) calloc(sizeof(sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, 1); if (!theMAD->sample) { int y; for (y = 0; y < MAXPATTERN; y++) { if (theMAD->partition[y]) { free(theMAD->partition[y]); } } free(theMAD->header); free(theMAD->sets); free(theMAD->sample); return MADNeedMemory; } for (i = 0; i < MAXINSTRU; i++) theMAD->fid[i].firstSample = i * MAXSAMPLE; for (i = 0; i < 64; i++) { InstrData *curIns = &theMAD->fid[i]; memcpy(curIns->name, oldMAD->fid[i].Filename, 32); curIns->type = 0; if (oldMAD->fid[i].insSize > 0) { sData *curData; curIns->numSamples = 1; curIns->volFade = DEFAULT_VOLFADE; curData = theMAD->sample[i * MAXSAMPLE + 0] = (sData*)calloc(sizeof(sData), 1); if (curData == NULL) { int y; for (y = 0; y < MAXPATTERN; y++) { if (theMAD->partition[y]) { free(theMAD->partition[y]); } } free(theMAD->header); free(theMAD->sets); for (y = 0; y > MAXINSTRU * MAXSAMPLE; y++) { if (theMAD->sample[y]) { if (theMAD->sample[y]->data) { free(theMAD->sample[y]->data); } free(theMAD->sample[y]); } } free(theMAD->sample); return MADNeedMemory; } curData->size = oldMAD->fid[i].insSize; curData->loopBeg = oldMAD->fid[i].loopStart; curData->loopSize = oldMAD->fid[i].loopLenght; curData->vol = oldMAD->fid[i].volume; curData->c2spd = finetune[oldMAD->fid[i].fineTune]; curData->loopType = 0; curData->amp = oldMAD->fid[i].amplitude; curData->realNote = 0; curData->data = (char*)malloc(curData->size); if (curData->data == NULL) { int y; for (y = 0; y < MAXPATTERN; y++) { if (theMAD->partition[y]) { free(theMAD->partition[y]); } } free(theMAD->header); free(theMAD->sets); for (y = 0; y > MAXINSTRU * MAXSAMPLE; y++) { if (theMAD->sample[y]) { if (theMAD->sample[y]->data) { free(theMAD->sample[y]->data); } free(theMAD->sample[y]); } } free(theMAD->sample); return MADNeedMemory; } memcpy(curData->data, MADPtr + OffSetToSample, curData->size); OffSetToSample += curData->size; if (curData->amp == 16) { int ll; short *shortPtr = (short*) curData->data; for (ll = 0; ll < curData->size/2; ll++) MADBE16(&shortPtr[ll]); } } else curIns->numSamples = 0; } return MADNoErr; }
char* PPConvertMad2Mod(MADMusic *theMAD, MADDriverSettings *init, size_t *PtrSize) { int i, x, z, maxInstru; int OffSetToSample, InstruSize, *alpha; char *theInstrument[64], *destPtr; bool CheckGoodMod; char redut[4]; short MODTuning[75] = { // -> Tuning 0 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906, 856,808,762,720,678,640,604,570,538,508,480,453, 428,404,381,360,339,320,302,285,269,254,240,226, 214,202,190,180,170,160,151,143,135,127,120,113, 107,101,95,90,85,80,75,71,67,63,60,56 }; /**** Variables for MAD file ****/ Cmd *aCmd; /**** Variables for MOD file ****/ MODDef *theMOD; char* maxMOD; struct MODCom *n; /********************************/ maxInstru = 31; InstruSize = 0; for (i = 0; i < maxInstru ; i++) { if (theMAD->fid[i].numSamples > 0) { int dstSize; theInstrument[i] = theMAD->sample[i*MAXSAMPLE + 0]->data; dstSize = theMAD->sample[i*MAXSAMPLE + 0]->size; if (theMAD->sample[i*MAXSAMPLE + 0]->c2spd < 7895) dstSize = (dstSize * 8363L) / theMAD->sample[i*MAXSAMPLE + 0]->c2spd; InstruSize += dstSize; } } /******** MAD is ready to be converted **********/ /******** Copy information in the MOD file ***/ *PtrSize = 0x43c + InstruSize + theMAD->header->numChn * 64L * theMAD->header->numPat * sizeof(struct MODCom); theMOD = (MODDef*) malloc(*PtrSize + 25000L); if (theMOD == NULL) return NULL; maxMOD = ((char*) theMOD + *PtrSize); theMOD->longFmtSignature = 'M.K.'; if (theMAD->header->numChn > 4) { if (theMAD->header->numChn >= 10) { redut[0] = 0x30 + (theMAD->header->numChn / 10); redut[1] = 0x30 + (theMAD->header->numChn - ((theMAD->header->numChn / 10) * 10)); redut[2] = 'C'; redut[3] = 'H'; } else { redut[0] = 0x30 + theMAD->header->numChn; redut[1] = 'C'; redut[2] = 'H'; redut[3] = 'N'; } alpha = (int*) redut; theMOD->longFmtSignature = *alpha; } for(i=0; i<20; i++) theMOD->NameSignature[i] = theMAD->header->name[i]; CheckGoodMod = false; theMOD->numPointers = theMAD->header->numPointers; for(i=0; i<128; i++) { theMOD->oPointers[i] = theMAD->header->oPointers[i]; if (theMOD->oPointers[i] == theMAD->header->numPat - 1) CheckGoodMod = true; } if (!CheckGoodMod) theMOD->oPointers[theMOD->numPointers + 1] = theMAD->header->numPat - 1; for(i=0; i<maxInstru; i++) { if (theMAD->fid[i].numSamples > 0) { sData *curData = theMAD->sample[i*MAXSAMPLE + 0]; short temp; for (x = 0; x < 22; x++) theMOD->fid[i].Filename[x] = theMAD->fid[i].name[x]; if (curData->size/2L > 0xFFFFUL) theMOD->fid[i].numWords = 0xFFFFUL; else theMOD->fid[i].numWords = (short) (curData->size / 2L); temp = (curData->c2spd - NOFINETUNE) / 50; if (temp < 0) temp += 16; theMOD->fid[i].fineTune = temp; theMOD->fid[i].volume = curData->vol; theMOD->fid[i].loopWord = curData->loopBeg / 2; theMOD->fid[i].loopWords = curData->loopSize / 2; if (curData->c2spd > 8757 || curData->c2spd < 7895) { theMOD->fid[i].fineTune = 0; theMOD->fid[i].loopWord = ((curData->loopBeg / 2L) * 8363) / curData->c2spd; theMOD->fid[i].loopWords = ((curData->loopSize / 2L) * 8363) / curData->c2spd; theMOD->fid[i].numWords = (theMOD->fid[i].numWords * 8363L) / curData->c2spd; } } else { for (x = 0; x < 22; x++) theMOD->fid[i].Filename[x] = 0; theMOD->fid[i].numWords = 0; theMOD->fid[i].fineTune = 0; theMOD->fid[i].volume = 64; theMOD->fid[i].loopWord = 0; theMOD->fid[i].loopWords = 0; } } InstruSize = 0; OffSetToSample = (int) 0x43c + theMAD->header->numPat * sizeof(struct MODCom) * 64L * theMAD->header->numChn; for(i=0; i<maxInstru; i++) { sData *curData = theMAD->sample[i*MAXSAMPLE + 0]; if (theMAD->fid[i].numSamples > 0) { destPtr = (char*) ((uintptr_t) theMOD + (uintptr_t) OffSetToSample + (uintptr_t) InstruSize); if (curData->c2spd > 8757 || curData->c2spd < 7895) { ConvertSampleC4SPD(theInstrument[i], curData->size, curData->amp, curData->c2spd, destPtr, 8363); } else memcpy(destPtr, theInstrument[i], (long) (theMOD->fid[i].numWords) * 2L); if (destPtr + (theMOD->fid[i].numWords) * 2L > maxMOD) //DebugStr("\pOut"); return NULL; if (theMOD->fid[i].numWords > 0) { if (curData->amp == 16) { Convert16to8(destPtr, destPtr, (theMOD->fid[i].numWords) * 2); theMOD->fid[i].loopWord /=2; theMOD->fid[i].loopWords /=2; theMOD->fid[i].numWords /= 2; } if (curData->stereo) { for (x = 0 ; x < (theMOD->fid[i].numWords) * 2L; x+=2) { destPtr[x / 2] = ((int) destPtr[x] + (int) destPtr[x + 1]) / 2L; } theMOD->fid[i].loopWord /=2; theMOD->fid[i].loopWords /=2; theMOD->fid[i].numWords /= 2; } } InstruSize += (long) (theMOD->fid[i].numWords) * 2L; } } for(i=0; i<theMAD->header->numPat; i++) { Cmd nullCmd; nullCmd.ins = 0; nullCmd.note = 0xFF; nullCmd.cmd = 0; nullCmd.arg = 0; nullCmd.vol = 0xFF; nullCmd.unused = 0; for(x=0; x < 64; x++) { for(z=0; z < theMAD->header->numChn; z++) { //short note; if (x < theMAD->partition[i]->header.size) { aCmd = GetMADCommand(x, z, theMAD->partition[i]); } else aCmd = &nullCmd; n = GetMODCommand(x, z, i, theMAD->header->numChn, (char*) theMOD->patterns); if ((char*) n > maxMOD) //DebugStr("\pOut"); return NULL; if ((char*) n < (char*) theMOD) //DebugStr("\pOut"); return NULL; n->a = aCmd->ins & 0xF0; n->c = (aCmd->ins & 0x0F)<<4; if (aCmd->note != 0xFF && aCmd->note != 0xFE) { short curNote; if (aCmd->ins != 0) { if (theMAD->fid[aCmd->ins-1].numSamples > 0) curNote = aCmd->note + theMAD->sample[(aCmd->ins-1)*MAXSAMPLE + 0]->relNote; else curNote = aCmd->note; } else curNote = aCmd->note; curNote -= 24; if (curNote > 0 && curNote < 65) curNote = MODTuning[curNote]; else curNote = 0; n->b = curNote & 0xFF; n->a = n->a + (curNote>>8); } else { n->b = 0; n->a = n->a + 0x0; } if (aCmd->vol != 0xFF && aCmd->cmd == 0 && aCmd->arg == 0) { if (aCmd->vol >= 0x10 && aCmd->vol <= 0x50) { n->c = n->c + 0xC; n->d = aCmd->vol - 0x10; } } else { n->c = n->c + (aCmd->cmd & 0x0F); n->d = aCmd->arg; } } }
static OSErr ConvertULT2Mad( Ptr theULT, long MODSize, MADMusic *theMAD, MADDriverSettings *init) { long i, PatMax, x, z, channel, Row; long sndSize, starting, RES; Ptr MaxPtr; OSErr theErr; Ptr theInstrument[ 64], destPtr; Byte tempChar, *theULTCopy; short Note, Octave, maxTrack; /**** Variables pour le MAD ****/ Cmd *aCmd; /**** Variables pour le ULT ****/ ULTForm ULTinfo; ULTSuite ULTSuite; /********************************/ for( i = 0 ; i < 64; i ++) { theInstrument[ i] = NULL; } /**** Header principal *****/ theULTCopy = (Byte*) theULT; BlockMoveData( theULTCopy, &ULTinfo, sizeof( ULTinfo)); // if( ULTinfo.reserved != 0) return MADFileNotSupportedByThisPlug; // RES in v.1.4 see doc ULTSuite.NOS = *(theULTCopy + sizeof( ULTinfo) + ULTinfo.reserved * 32L); /**** Ins Num *****/ if( sizeof( ULTIns) != 64) DebugStr("\pULTIns != 64"); ULTSuite.ins = (ULTIns*) NewPtrClear( ULTSuite.NOS * sizeof( ULTIns)); BlockMoveData( theULTCopy + sizeof( ULTinfo) + ULTinfo.reserved * 32L + 1, ULTSuite.ins, ULTSuite.NOS * sizeof( ULTIns)); /**** Copy last infos *****/ BlockMoveData( theULTCopy + sizeof( ULTinfo) + ULTinfo.reserved * 32L + 1 + (ULTSuite.NOS * sizeof( ULTIns)), &ULTSuite.pattSeq, 256 + 2); // ******** Le ULT a ŽtŽ lu et analysŽ *********** // ******** Copie des informations dans le MAD *** theMAD->header = (MADSpec*) MADPlugNewPtrClear( sizeof( MADSpec), init); if( theMAD->header == NULL) return MADNeedMemory; theMAD->header->MAD = 'MADK'; for(i=0; i<32; i++) theMAD->header->name[i] = 0; for(i=0; i<32; i++) theMAD->header->name[i] = ULTinfo.name[i]; mystrcpy( theMAD->header->infos, "\pConverted by PlayerPRO ULT Plug (©Antoine ROSSET <*****@*****.**>)"); theMAD->header->numPat = ULTSuite.NOP; theMAD->header->numPointers = 1; // CHANGE theMAD->header->speed = 6; theMAD->header->tempo = 125; theMAD->sets = (FXSets*) NewPtrClear( MAXTRACK * sizeof(FXSets)); for( i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[ i].copyId = i; for(i=0; i<128; i++) theMAD->header->oPointers[ i] = 0; for(i=0; i<128; i++) { theMAD->header->oPointers[ i] = ULTSuite.pattSeq[i]; if( theMAD->header->oPointers[ i] < 0 || theMAD->header->oPointers[ i] >= 128) theMAD->header->oPointers[ i] = 0; } for( i = 0; i < MAXTRACK; i++) { if( i % 2 == 0) theMAD->header->chanPan[ i] = MAX_PANNING/4; else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4; theMAD->header->chanVol[ i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; // ******************** // ***** INSTRUMENTS ***** // ******************** theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init); if( !theMAD->fid) return MADNeedMemory; theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init); if( !theMAD->sample) return MADNeedMemory; for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE; for(i = 0 ; i < MAXINSTRU; i++) { for( x = 0; x < MAXSAMPLE; x++) theMAD->sample[ i*MAXSAMPLE + x] = NULL; theMAD->fid[i].numSamples = 0; } for(i=0; i<ULTSuite.NOS; i++) { InstrData *curIns = &theMAD->fid[ i]; curIns->type = 0; { sData *curData; curIns->numSamples = 1; curIns->volFade = DEFAULT_VOLFADE; curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init); if( curData == NULL) return MADNeedMemory; ULTSuite.ins[i].loopStart = Tdecode32( &ULTSuite.ins[i].loopStart); ULTSuite.ins[i].loopEnd = Tdecode32( &ULTSuite.ins[i].loopEnd); ULTSuite.ins[i].sizeStart = Tdecode32( &ULTSuite.ins[i].sizeStart); ULTSuite.ins[i].sizeEnd = Tdecode32( &ULTSuite.ins[i].sizeEnd); ULTSuite.ins[i].finetune = Tdecode16( &ULTSuite.ins[i].finetune); curData->size = ULTSuite.ins[i].sizeEnd - ULTSuite.ins[i].sizeStart; // * 2 ??? curData->loopBeg = ULTSuite.ins[i].loopStart; curData->loopSize = ULTSuite.ins[i].loopEnd - ULTSuite.ins[i].loopStart; curData->vol = ULTSuite.ins[i].volume; curData->c2spd = ULTSuite.ins[i].finetune; curData->loopType = 0; switch( ULTSuite.ins[i].Bidi) { case 4: case 12: case 28: curData->amp = 16; break; default: curData->amp = 8; break; } curData->relNote = 0; for( x = 0; x < 28; x++) theMAD->fid[i].name[x] = ULTSuite.ins[i].name[x]; curData->data = MADPlugNewPtr( curData->size, init); if( curData->data == NULL) return MADNeedMemory; else { BlockMoveData( theULT + ULTSuite.ins[i].sizeStart, curData->data, curData->size); } } // else curIns->numSamples = 0; } theMAD->header->numChn = ULTSuite.NOC; for( i = 0; i < MAXPATTERN; i++) theMAD->partition[ i] = NULL; for( i = 0; i < theMAD->header->numPat ; i++) { theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * 64 * sizeof( Cmd), init); if( theMAD->partition[ i] == NULL) return MADNeedMemory; theMAD->partition[ i]->header.size = 64; theMAD->partition[ i]->header.compMode = 'NONE'; for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0; MaxPtr = (Ptr) theMAD->partition[ i]; MaxPtr += sizeof( PatHeader) + theMAD->header->numChn * 64 * sizeof( Cmd); for( Row = 0; Row < 64; Row++) { for(z = 0; z < theMAD->header->numChn; z++) { aCmd = GetMADCommand( Row, z, theMAD->partition[ i]); aCmd->note = 0xFF; aCmd->ins = 0; aCmd->cmd = 0; aCmd->arg = 0; aCmd->vol = 0xFF; } } } DisposePtr( (Ptr) ULTSuite.ins); return noErr; }
static MADErr PPConvertMod2Mad(char* aMOD, size_t MODSize, MADMusic *theMAD, MADDriverSettings* init) { short i, PatMax, x, tracksNo, z, maxInstru; int sndSize, OffSetToSample, MPatSize, temp, inOutCount; char *theInstrument[64], *MaxPtr; int lastIns[32], lastNote[32]; int finetune[16] = { 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280 }; /**** Variables for MAD File *****/ Cmd *aCmd; /**** Variables for MOD File *****/ MODDef *theMOD; struct MODPat *PatInt; MODDef *MODInt; struct MODCom *n; /********************************/ theMOD = ((MODDef*) aMOD); MaxPtr = (char*) theMOD; MaxPtr += MODSize; temp = *((int*)(aMOD + 0x438)); // Signature... AnalyseSignatureMOD(-1, temp, &maxInstru, &MPatSize, &tracksNo, theMOD); if (maxInstru == 0) { return MADFileNotSupportedByThisPlug; // This file is NOT a Mod file !!!!!! This should NEVER happen ! } else if (maxInstru == 15) // Old Mods format with 15 instruments { MODInt = (MODDef*) ((char*) theMOD - (char*) 0x1E0); PatInt = (struct MODPat*) ((char*) MODInt->patterns - (char*) 0x4); PatMax = 0; for(i=0; i<128; i++) { if (MODInt->oPointers[i] < 0) MODInt->oPointers[i] = 0; if (MODInt->oPointers[i] > 128) MODInt->oPointers[i] = 0; if (MODInt->oPointers[i] >= PatMax) PatMax = MODInt->oPointers[i]; } PatMax++; //if (MODInt->numPointers > 64) MODInt->numPointers = 64; //for(i=64; i<128; i++) MODInt->oPointers[i] = 0; OffSetToSample = (int) 0x258 + PatMax * MPatSize; } else // Mods format with 32 instruments { MODInt = theMOD; PatInt = MODInt->patterns; PatMax = 0; for(i=0; i<128; i++) { if (MODInt->oPointers[i] < 0) MODInt->oPointers[i] = 0; if (MODInt->oPointers[i] > 128) MODInt->oPointers[i] = 0; if (MODInt->oPointers[i] >= PatMax) PatMax = MODInt->oPointers[i]; } PatMax++; OffSetToSample = (int) 0x43c + PatMax * MPatSize; } for (i = 0; i < maxInstru ; i++) { theInstrument[i] = (char*) ((uintptr_t) theMOD + (int) OffSetToSample); PPBE16(&theMOD->fid[i].numWords); PPBE16(&theMOD->fid[i].loopWord); PPBE16(&theMOD->fid[i].loopWords); sndSize = ((int) theMOD->fid[i].numWords) * 2L; if (theInstrument[i] + sndSize > MaxPtr) { theMOD->fid[i].numWords = MaxPtr - theInstrument[i]; theMOD->fid[i].numWords /= 2L; if (theMOD->fid[i].numWords < 0) theMOD->fid[i].numWords = 0; sndSize = ((int) theMOD->fid[i].numWords) * 2L; } OffSetToSample += sndSize; if (theMOD->fid[i].loopWords > 2 && sndSize > 0) { if ((int) theMOD->fid[i].loopWord + (int) theMOD->fid[i].loopWords > (int) theMOD->fid[i].numWords) { theMOD->fid[i].loopWords = (int) theMOD->fid[i].numWords - (int) theMOD->fid[i].loopWord; if ((int) theMOD->fid[i].loopWord + (int) theMOD->fid[i].loopWords > (int) theMOD->fid[i].numWords) { theMOD->fid[i].loopWord = 0; theMOD->fid[i].loopWords = 0; } } } else { theMOD->fid[i].loopWord = 0; theMOD->fid[i].loopWords = 0; } } /***************************************************************/ /******** MOD is ready to be converted into MAD File ***********/ /***************************************************************/ inOutCount = sizeof(MADSpec); theMAD->header = (MADSpec*) calloc(inOutCount, 1); if (theMAD->header == NULL) return MADNeedMemory; strncpy(theMAD->header->infos, "Converted by PlayerPRO UMX Plug (\251Antoine ROSSET <*****@*****.**>)", sizeof(theMAD->header->infos)); theMAD->header->MAD = 'MADK'; theMAD->header->MODMode = true; for(i=0; i<22; i++) theMAD->header->name[i] = theMOD->NameSignature[i]; theMAD->header->tempo = 125; theMAD->header->speed = 6; theMAD->header->numPat = PatMax; theMAD->header->numPointers = MODInt->numPointers; for(i=0; i<128; i++) theMAD->header->oPointers[i] = MODInt->oPointers[i]; theMAD->header->numChn = tracksNo; x = 1; for (i = 0; i < MAXTRACK; i++) { if (x > 0) theMAD->header->chanPan[i] = MAX_PANNING/4; else theMAD->header->chanPan[i] = MAX_PANNING - MAX_PANNING/4; x--; if (x == -2) x = 2; theMAD->header->chanVol[i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; theMAD->sets = (FXSets*) calloc(MAXTRACK * sizeof(FXSets), 1); for (i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[i].copyId = i; ///////////////////////////////// // Instruments & samples ///////////////////////////////// theMAD->fid = (InstrData*) calloc(sizeof(InstrData) * (long) MAXINSTRU, 1); if (!theMAD->fid) return MADNeedMemory; theMAD->sample = (sData**) calloc(sizeof(sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, 1); if (!theMAD->sample) return MADNeedMemory; for(i = 0; i < maxInstru; i++) { for (x = 0; x < 22; x++) theMAD->fid[i].name[x] = theMOD->fid[i].Filename[x]; theMAD->fid[i].type = 0; theMAD->fid[i].volFade = DEFAULT_VOLFADE; if (theMOD->fid[i].numWords > 0) { sData *curData; theMAD->fid[i].numSamples = 1; curData = theMAD->sample[i*MAXSAMPLE + 0] = (sData*) calloc(sizeof(sData), 1); curData->size = theMOD->fid[i].numWords * 2L; curData->loopBeg = theMOD->fid[i].loopWord*2L; curData->loopSize = theMOD->fid[i].loopWords*2L; curData->vol = theMOD->fid[i].volume; curData->c2spd = finetune[theMOD->fid[i].fineTune&0xf]; curData->loopType = 0; curData->amp = 8; curData->relNote = 0; //for (x = 0; x < 22; x++) curData->name[x] = theMOD->fid[i].Filename[x]; curData->data = (char*)malloc(curData->size); if (curData->data == NULL) return MADNeedMemory; memcpy(curData->data, theInstrument[i], curData->size); if (theInstrument[i] + curData->size> MaxPtr) //DebugStr("\pMax char* Instru"); return MADIncompatibleFile; } else theMAD->fid[i].numSamples = 0; } for (i = 0; i < MAXINSTRU; i++) theMAD->fid[i].firstSample = i * MAXSAMPLE; for (i=0; i < 32; i++) { lastIns[i] = 0; lastNote[i] = 0; } for(i=0; i<theMAD->header->numPat; i++) { theMAD->partition[i] = (PatData*) calloc(sizeof(PatHeader) + theMAD->header->numChn * 64L * sizeof(Cmd), 1); if (theMAD->partition[i] == NULL) return MADNeedMemory; theMAD->partition[i]->header.size = 64L; theMAD->partition[i]->header.compMode = 'NONE'; for (x = 0; x < 20; x++) theMAD->partition[i]->header.name[x] = 0; theMAD->partition[i]->header.patBytes = 0; theMAD->partition[i]->header.unused2 = 0; for(x=0; x<64; x++) { for(z=0; z<theMAD->header->numChn; z++) { aCmd = GetMADCommand( x, z, theMAD->partition[i]); ///////////// n = GetMODCommand(x, z, i, theMAD->header->numChn, (char*) PatInt); if ((char*) n > MaxPtr) //DebugStr("\pMax char* GetMODCommand"); return MADIncompatibleFile; aCmd->ins = (n->a&0x10)|(n->c>>4); aCmd->note = FoundNote((((unsigned short)n->a&0xf)<<8)+n->b); if (aCmd->note == 0xFF && aCmd->ins != 0) { if (aCmd->ins != lastIns[z]) { aCmd->note = lastNote[z]; } } if (aCmd->note != 0xFF) lastNote[z] = aCmd->note; if (aCmd->ins) lastIns[z] = aCmd->ins; aCmd->cmd = n->c & 0x0F; if (aCmd->cmd == 0x0A) { if (n->d == 0) { aCmd->cmd = 0; } } if (aCmd->cmd == 0x0C) { aCmd->vol = 0x10 + (n->d); if (aCmd->arg > 0x50) aCmd->vol = 0x50; aCmd->cmd = 0; aCmd->arg = 0; } else { aCmd->arg = n->d; aCmd->vol = 0xFF; } } } } for (i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[i] = NULL; return MADNoErr; }
static MADErr ConvertULT2Mad(char* theULT, size_t MODSize, MADMusic *theMAD, MADDriverSettings *init) { size_t i, x, z, Row; char *MaxPtr; char *theInstrument[64]; MADByte *theULTCopy; /**** Variables pour le MAD ****/ Cmd *aCmd; /**** Variables pour le ULT ****/ ULTForm ULTinfo; ULTSuite ULTSuite; /********************************/ memset(theInstrument, 0, sizeof(theInstrument)); /**** Header principal *****/ theULTCopy = (MADByte*)theULT; memcpy(&ULTinfo, theULTCopy, sizeof(ULTinfo)); //if (ULTinfo.reserved != 0) return MADFileNotSupportedByThisPlug; // RES in v.1.4 see doc ULTSuite.NOS = *(theULTCopy + sizeof(ULTinfo) + ULTinfo.reserved * 32L); /**** Ins Num *****/ if (sizeof(ULTIns) != 64) //DebugStr("\pULTIns != 64"); return MADIncompatibleFile; ULTSuite.ins = (ULTIns*)calloc(sizeof(ULTIns), ULTSuite.NOS); memcpy(ULTSuite.ins, theULTCopy + sizeof(ULTinfo) + ULTinfo.reserved * 32 + 1, ULTSuite.NOS * sizeof(ULTIns)); /**** Copy last infos *****/ memcpy(&ULTSuite.pattSeq, theULTCopy + sizeof(ULTinfo) + ULTinfo.reserved * 32 + 1 + (ULTSuite.NOS * sizeof(ULTIns)), 256 + 2); // ******** Le ULT a été lu et analysé *********** // ******** Copie des informations dans le MAD *** theMAD->header = (MADSpec*) calloc(sizeof(MADSpec), 1); if (theMAD->header == NULL) return MADNeedMemory; theMAD->header->MAD = 'MADK'; for (i = 0; i < 32; i++) theMAD->header->name[i] = 0; for (i = 0; i < 32; i++) theMAD->header->name[i] = ULTinfo.name[i]; strncpy(theMAD->header->infos, "Converted by PlayerPRO ULT Plug (\251Antoine ROSSET <*****@*****.**>)", sizeof(theMAD->header->infos)); theMAD->header->numPat = ULTSuite.NOP; theMAD->header->numPointers = 1; // CHANGE theMAD->header->speed = 6; theMAD->header->tempo = 125; theMAD->sets = (FXSets*) calloc(MAXTRACK * sizeof(FXSets), 1); for (i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[i].copyId = i; for (i = 0; i < 128; i++) theMAD->header->oPointers[i] = 0; for (i = 0; i < 128; i++) { theMAD->header->oPointers[i] = ULTSuite.pattSeq[i]; if (theMAD->header->oPointers[i] < 0 || theMAD->header->oPointers[i] >= 128) theMAD->header->oPointers[i] = 0; } for (i = 0; i < MAXTRACK; i++) { if (i % 2 == 0) theMAD->header->chanPan[i] = MAX_PANNING / 4; else theMAD->header->chanPan[i] = MAX_PANNING - MAX_PANNING / 4; theMAD->header->chanVol[i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; // ******************** // ***** INSTRUMENTS ***** // ******************** theMAD->fid = (InstrData*) calloc(sizeof(InstrData) * (long) MAXINSTRU, 1); if (!theMAD->fid) return MADNeedMemory; theMAD->sample = (sData**) calloc(sizeof(sData*), MAXINSTRU * MAXSAMPLE); if (!theMAD->sample) return MADNeedMemory; for (i = 0; i < MAXINSTRU; i++) theMAD->fid[i].firstSample = i * MAXSAMPLE; for (i = 0 ; i < MAXINSTRU; i++) { for (x = 0; x < MAXSAMPLE; x++) theMAD->sample[i*MAXSAMPLE + x] = NULL; theMAD->fid[i].numSamples = 0; } for (i = 0; i < ULTSuite.NOS; i++) { InstrData *curIns = &theMAD->fid[i]; curIns->type = 0; { sData *curData; curIns->numSamples = 1; curIns->volFade = DEFAULT_VOLFADE; curData = theMAD->sample[i*MAXSAMPLE + 0] = (sData*) calloc(sizeof(sData), 1); if (curData == NULL) return MADNeedMemory; PPLE32(&ULTSuite.ins[i].loopStart); PPLE32(&ULTSuite.ins[i].loopEnd); PPLE32(&ULTSuite.ins[i].sizeStart); PPLE32(&ULTSuite.ins[i].sizeEnd); PPLE16(&ULTSuite.ins[i].finetune); curData->size = ULTSuite.ins[i].sizeEnd - ULTSuite.ins[i].sizeStart; // * 2 ??? curData->loopBeg = ULTSuite.ins[i].loopStart; curData->loopSize = ULTSuite.ins[i].loopEnd - ULTSuite.ins[i].loopStart; curData->vol = ULTSuite.ins[i].volume; curData->c2spd = ULTSuite.ins[i].finetune; curData->loopType = 0; switch (ULTSuite.ins[i].Bidi) { case 4: case 12: case 28: curData->amp = 16; break; default: curData->amp = 8; break; } curData->relNote = 0; for (x = 0; x < 28; x++) theMAD->fid[i].name[x] = ULTSuite.ins[i].name[x]; curData->data = malloc(curData->size); if (curData->data == NULL) { return MADNeedMemory; } else { memcpy(curData->data, theULT + ULTSuite.ins[i].sizeStart, curData->size); } } //else curIns->numSamples = 0; } theMAD->header->numChn = ULTSuite.NOC; for (i = 0; i < MAXPATTERN; i++) theMAD->partition[i] = NULL; for (i = 0; i < theMAD->header->numPat; i++) { theMAD->partition[i] = (PatData*)calloc(sizeof(PatHeader) + theMAD->header->numChn * 64 * sizeof(Cmd), 1); if (theMAD->partition[i] == NULL) return MADNeedMemory; theMAD->partition[i]->header.size = 64; theMAD->partition[i]->header.compMode = 'NONE'; for (x = 0; x < 20; x++) theMAD->partition[i]->header.name[x] = 0; MaxPtr = (char*) theMAD->partition[i]; MaxPtr += sizeof(PatHeader) + theMAD->header->numChn * 64 * sizeof(Cmd); for (Row = 0; Row < 64; Row++) { for(z = 0; z < theMAD->header->numChn; z++) { aCmd = GetMADCommand(Row, z, theMAD->partition[i]); aCmd->note = 0xFF; aCmd->ins = 0; aCmd->cmd = 0; aCmd->arg = 0; aCmd->vol = 0xFF; } } } free(ULTSuite.ins); return MADNoErr; }
static MADErr ConvertOKTA2Mad(char* theOkta, long MODSize, MADMusic *theMAD, MADDriverSettings *init) { short i, x, z, TrueTracks; char *MaxPtr, *theOktaPos; char *theInstrument[120] /*, *destPtr*/; //MADErr theErr; //short PatMax, channel; //long sndSize, OffSetToSample, OldTicks, temp, starting; //unsigned short tempS; //char tempChar; /**** Variables pour le MAD ****/ Cmd *aCmd; /**** Variables pour le Okta ****/ OktaHeader *Okta; OktaInstru *samps, *s, instru[120]; OktaPattern *OktaCmd; sectheader *aSect; //long SectLength; short pbod_count, sbod_count; MADFourChar OKTAHeader = 0; /********************************/ for (i = 0 ; i < 64; i ++) theInstrument[i] = NULL; theMAD->header = (MADSpec*)calloc(sizeof(MADSpec), 1); Okta = (struct OktaHeader*)malloc(sizeof(struct OktaHeader)); sbod_count = 0; pbod_count = 0; MaxPtr = theOkta + MODSize; theOktaPos = theOkta; OKTAHeader = (*(MADFourChar*)theOkta); MADBE32(&OKTAHeader); if (OKTAHeader != 'OKTA') //DebugStr("\pError in OKTA"); return MADIncompatibleFile; theOktaPos += 8L; while(theOktaPos < MaxPtr) { aSect = (sectheader*) theOktaPos; MADLE32 (&aSect->length); theOktaPos += 8L; MADBE32(&aSect->name); switch(aSect->name) { case 'CMOD': Okta->splitted[0] = theOktaPos[1]; Okta->splitted[1] = theOktaPos[3]; Okta->splitted[2] = theOktaPos[5]; Okta->splitted[3] = theOktaPos[7]; Okta->linesize = ((4 +Okta->splitted[0] + Okta->splitted[1] + Okta->splitted[2] + Okta->splitted[3]) * 4); break; case 'SAMP': samps = (OktaInstru*) theOktaPos; for (i = 0; i * sizeof(OktaInstru) < aSect->length; i++) { instru[i] = samps[i]; MADLE32(&instru[i ].length); MADLE16(&instru[i ].repeat); instru[i ].repeat *= 2; MADLE16(&instru[i ].replen); instru[i ].replen *= 2; } Okta->samp_count = i; break; case 'SPEE': Okta->speed = *((short*)theOktaPos); MADLE16(&Okta->speed); break; case 'SLEN': Okta->slen = *((short*)theOktaPos); MADLE16(&Okta->slen); break; case 'PLEN': Okta->plen = *((short*)theOktaPos); MADLE16(&Okta->plen); break; case 'PATT': Okta->patt = (unsigned char*)theOktaPos; break; case 'PBOD': Okta->pbodlen[pbod_count] = *((short*)theOktaPos); MADLE16(&Okta->pbodlen[pbod_count]); if (pbod_count == 0) theMAD->header->numChn = (aSect->length - 2L) / (Okta->pbodlen[pbod_count] * 4L); else { if (theMAD->header->numChn != (aSect->length - 2L) / (Okta->pbodlen[pbod_count] * 4L)) { //DebugStr("\pNon-standard OKTA - numChn"); return MADIncompatibleFile; } } Okta->pbod[pbod_count++] = (theOktaPos + 2L); break; case 'SBOD': s = &instru[sbod_count]; if (Okta->splitted[0] || Okta->splitted[1] || Okta->splitted[2] || Okta->splitted[3]) { } s->length = aSect->length; //if (s->length < aSect->length) theInstrument[sbod_count] = theOktaPos; if (s->replen == 0) { } else if (s->repeat != 0) { } else { } sbod_count++; break; default: //DebugStr("\pUnknow section"); return MADIncompatibleFile; break; } theOktaPos += aSect->length; } /******** Le Okta a été lu et analysé ***********/ /******** Copie des informations dans le MAD ***/ theMAD->header->MAD = 'MADK'; for(i=0; i<32; i++) theMAD->header->name[i] = 0; for(i=0; i<20; i++) theMAD->header->name[i] = Okta->magic[i]; theMAD->header->numPat = pbod_count; theMAD->header->numPointers = pbod_count; theMAD->header->tempo = 125; theMAD->header->speed = Okta->speed; strncpy(theMAD->header->infos, "Converted by PlayerPRO OKTA Plug (\251Antoine ROSSET <*****@*****.**>)", sizeof(theMAD->header->infos)); for (i = 0; i < 128; i++) theMAD->header->oPointers[i] = 0; for (i = 0; i < pbod_count; i++) theMAD->header->oPointers[i] = Okta->patt[i]; for (i = 0; i < MAXTRACK; i++) { if (i % 2 == 0) theMAD->header->chanPan[i] = MAX_PANNING/4; else theMAD->header->chanPan[i] = MAX_PANNING - MAX_PANNING/4; theMAD->header->chanVol[i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; theMAD->sets = (FXSets*) calloc(MAXTRACK * sizeof(FXSets), 1); for (i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[i].copyId = i; // INSTRUMENTS theMAD->fid = (InstrData*) calloc(sizeof(InstrData) * (long) MAXINSTRU, 1); if (!theMAD->fid) return MADNeedMemory; theMAD->sample = (sData**) calloc(sizeof(sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, 1); if (!theMAD->sample) return MADNeedMemory; for (i = 0; i < MAXINSTRU; i++) theMAD->fid[i].firstSample = i * MAXSAMPLE; for(i=0; i< sbod_count; i++) { for (x = 0; x < 22; x++) theMAD->fid[i].name[x] = instru[i].name[x]; theMAD->fid[i].type = 0; if (instru[i].length > 0) { sData *curData; theMAD->fid[i].numSamples = 1; theMAD->fid[i].volFade = DEFAULT_VOLFADE; curData = theMAD->sample[i*MAXSAMPLE + 0] = (sData*) calloc(sizeof(sData), 1); curData->size = instru[i].length; curData->loopBeg = instru[i].repeat; curData->loopSize = instru[i].replen; curData->vol = instru[i].vol; curData->c2spd = NOFINETUNE; curData->loopType = 0; curData->amp = 8; curData->relNote = 0; curData->data = (char*)malloc(curData->size); if (curData->data == NULL) return MADNeedMemory; memcpy(curData->data, theInstrument[i], curData->size); } else theMAD->fid[i].numSamples = 0; } //*** TEMPORAIRE ***** TrueTracks = theMAD->header->numChn; theMAD->header->numChn /= 2; theMAD->header->numChn *= 2; if (theMAD->header->numChn != TrueTracks) theMAD->header->numChn += 2; for(i=0; i<MAXPATTERN;i++) theMAD->partition[i] = NULL; for(i=0; i<theMAD->header->numPat; i++) { theMAD->partition[i] = (PatData*) calloc(sizeof(PatHeader) + theMAD->header->numChn * Okta->pbodlen[i] * sizeof(Cmd), 1); theMAD->partition[i]->header.size = Okta->pbodlen[i]; theMAD->partition[i]->header.compMode = 'NONE'; for (x = 0; x < 20; x++) theMAD->partition[i]->header.name[x] = 0; theMAD->partition[i]->header.patBytes = 0; theMAD->partition[i]->header.unused2 = 0; MaxPtr = (char*) theMAD->partition[i]; MaxPtr += sizeof(PatHeader) + theMAD->header->numChn * Okta->pbodlen[i] * sizeof(Cmd); for (x = 0; x < Okta->pbodlen[i]; x++) { for(z=0; z<theMAD->header->numChn; z++) { aCmd = GetMADCommand(x, z, theMAD->partition[i]); if ((char*) aCmd >= MaxPtr) //Debugger(); return MADIncompatibleFile; aCmd->note = 0xFF; aCmd->ins = 0; aCmd->cmd = 0; aCmd->arg = 0; aCmd->vol = 0xFF; if (z < TrueTracks) { OktaCmd = (OktaPattern*) (Okta->pbod[i] + x * TrueTracks * 4L + 4L*z); if (OktaCmd->b1 > 0) { aCmd->note = OktaCmd->b1 - 1; aCmd->note += 24; if (aCmd->note < 0 || aCmd->note >= NUMBER_NOTES) aCmd->note = 0xFF; aCmd->ins = OktaCmd->b2 + 1; } switch(OktaCmd->b3) { case 31: if (OktaCmd->b4 <= 0x40) { aCmd->vol = OktaCmd->b4 + 0x10; } break; case 25: OktaCmd->b4 &= 0xf; if( OktaCmd->b4 != 0) { aCmd->cmd = MADEffectSpeed; aCmd->arg = OktaCmd->b4; } break; } /* if (i == 0 && x == 0 && z == 0) { aCmd->cmd = MADEffectSpeed; aCmd->arg = Okta->speed; }*/ } } } } free(Okta); return MADNoErr; }
static MADErr Convert6692Mad(char* AlienFile, size_t MODSize, MADMusic *theMAD, MADDriverSettings *init) { SixSixNine *the669; short i, x, z; size_t OffSetToSample; uintptr_t temp; char *MaxPtr; char *theInstrument[64], *destPtr; short Note, Octave; MADByte *thePasByte; /**** Variables pour le MAD ****/ Cmd *aCmd; /**** Variables pour le MOD ****/ struct PatSix *PatInt; struct PatCmd *theCommand; struct SampleInfo *SInfo; /********************************/ the669 = (SixSixNine*)AlienFile; theMAD->header = (MADSpec*)calloc(sizeof(MADSpec), 1); if (!theMAD->header) return MADNeedMemory; MaxPtr = (char*)((uintptr_t)the669 + MODSize); OffSetToSample = 0x1f1 + the669->NOS * 25 + the669->NOP * 0x600L; for (i = 0; i < the669->NOS ; i++) { temp = (uintptr_t) the669; temp += 0x1f1L + i*25L + 13L; SInfo = (SampleInfo*)temp; PPLE16(&SInfo->length); PPLE16(&SInfo->loopStart); PPLE16(&SInfo->loopEnd); theInstrument[i] = (char*)((uintptr_t)the669 + OffSetToSample); OffSetToSample += SInfo->length; } /******** Le 669 a été lu et analysé ***********/ /******** Copie des informations dans le MAD ***/ theMAD->header->MAD = 'MADK'; strncpy(theMAD->header->name, the669->message, sizeof(theMAD->header->name)); strncpy(theMAD->header->infos, "Converted by PlayerPRO 669 Plug (\251Antoine ROSSET <*****@*****.**>)", sizeof(theMAD->header->infos)); theMAD->header->numPointers = 128; //the669->loopOrder; theMAD->header->tempo = 125; theMAD->header->speed = 6; theMAD->header->numPat = the669->NOP; for (i = 0; i < 128; i++) { theMAD->header->oPointers[i] = the669->orderList[i]; if (theMAD->header->oPointers[i] >= theMAD->header->numPat) theMAD->header->oPointers[i] = theMAD->header->numPat - 1; } theMAD->header->numChn = 8; theMAD->sets = (FXSets*)calloc(sizeof(FXSets), MAXTRACK); if (!theMAD->sets) { free(theMAD->header); return MADNeedMemory; } //TODO: dispatch this for (i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[i].copyId = i; //TODO: dispatch this for (i = 0; i < MAXTRACK; i++) { if (i % 2 == 0) theMAD->header->chanPan[i] = MAX_PANNING / 4; else theMAD->header->chanPan[i] = MAX_PANNING - MAX_PANNING / 4; theMAD->header->chanVol[i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; theMAD->fid = (InstrData*) calloc(sizeof(InstrData), MAXINSTRU); if (!theMAD->fid) { free(theMAD->sets); free(theMAD->header); return MADNeedMemory; } theMAD->sample = (sData**) calloc(sizeof(sData*), MAXINSTRU * MAXSAMPLE); if (!theMAD->sample) { free(theMAD->fid); free(theMAD->sets); free(theMAD->header); return MADNeedMemory; } //TODO: dispatch this for (i = 0; i < MAXINSTRU; i++) theMAD->fid[i].firstSample = i * MAXSAMPLE; for(i = 0; i < the669->NOS; i++) { temp = (uintptr_t) the669; temp += 0x1f1 + i * 25 + 13; SInfo = (SampleInfo*)temp; if (SInfo->length > 0) { sData *curData; theMAD->fid[i].numSamples = 1; theMAD->fid[i].volFade = DEFAULT_VOLFADE; curData = theMAD->sample[i * MAXSAMPLE + 0] = (sData*)calloc(sizeof(sData), 1); if (!curData) { for (i = 0; i < MAXINSTRU * MAXSAMPLE; i++) { if (theMAD->sample[i]) { if (theMAD->sample[i]->data) { free(theMAD->sample[i]->data); } free(theMAD->sample[i]); } } free(theMAD->sample); free(theMAD->fid); free(theMAD->sets); free(theMAD->header); return MADNeedMemory; } curData->size = SInfo->length; curData->loopBeg = 0; curData->loopSize = 0; curData->vol = 64; curData->c2spd = NOFINETUNE; curData->loopType = 0; curData->amp = 8; curData->relNote = 0; //strncpy(curData->name, instru[i]->name, sizeof(curData->name)); //for (x = 0; x < 22; x++) curData->name[x] = instru[i]->name[x]; curData->data = malloc(curData->size); if (curData->data == NULL) { for (i = 0; i < MAXINSTRU * MAXSAMPLE; i++) { if (theMAD->sample[i]) { if (theMAD->sample[i]->data) free(theMAD->sample[i]->data); free(theMAD->sample[i]); } } free(theMAD->sample); free(theMAD->fid); free(theMAD->sets); free(theMAD->header); return MADNeedMemory; } memcpy(curData->data, theInstrument[i], curData->size); destPtr = curData->data; for (temp = 0; temp < curData->size; temp++) *(destPtr + temp) -= 0x80; } else theMAD->fid[i].numSamples = 0; } temp = (uintptr_t)the669; temp += 0x1f1 + (uintptr_t)the669->NOS * 0x19; PatInt = (struct PatSix*)temp; /***** TEMPORAIRE ********/ theMAD->header->numChn = 8; //theMAD->header->PatMax = 1; for (i = 0; i < theMAD->header->numPat; i++) { theMAD->partition[i] = (PatData*)calloc(sizeof(PatHeader) + theMAD->header->numChn * 64 * sizeof(Cmd), 1); if (!theMAD->partition[i]) { for (i = 0; i < MAXPATTERN; i++) { if (theMAD->partition[i]) { free(theMAD->partition[i]); } } for (i = 0; i < MAXINSTRU * MAXSAMPLE; i++) { if (theMAD->sample[i]) { if (theMAD->sample[i]->data) { free(theMAD->sample[i]->data); } free(theMAD->sample[i]); } } free(theMAD->sample); free(theMAD->fid); free(theMAD->sets); free(theMAD->header); return MADNeedMemory; } theMAD->partition[i]->header.size = 64; theMAD->partition[i]->header.compMode = 'NONE'; //TODO: dispatch this for (x = 0; x < 20; x++) theMAD->partition[i]->header.name[x] = 0; theMAD->partition[i]->header.patBytes = 0; theMAD->partition[i]->header.unused2 = 0; for (x = 0 ; x < 64; x++) { for (z = 0; z<theMAD->header->numChn; z++) { aCmd = GetMADCommand(x, z, theMAD->partition[i]); theCommand = &PatInt[i].Cmds[x][z]; if ((char*)theCommand >= MaxPtr) { for (i = 0; i < MAXPATTERN; i++) { if (theMAD->partition[i]) { free(theMAD->partition[i]); } } for (i = 0; i < MAXINSTRU * MAXSAMPLE; i++) { if (theMAD->sample[i]) { if (theMAD->sample[i]->data) { free(theMAD->sample[i]->data); } free(theMAD->sample[i]); } free(theMAD->sample); free(theMAD->fid); free(theMAD->sets); free(theMAD->header); } return MADIncompatibleFile; } thePasByte = (MADByte*) theCommand; if (thePasByte[0] == 0xFF) { aCmd->cmd = 0; aCmd->arg = 0; aCmd->ins = 0; aCmd->note = 0xFF; aCmd->vol = 0xFF; } else if (thePasByte[0] == 0xFE) { aCmd->ins = 0; aCmd->note = 0xFF; aCmd->cmd = 0; aCmd->arg = 0; aCmd->vol = theCommand->Volume; aCmd->vol = (aCmd->vol * 64) / 15; } else { aCmd->ins = theCommand->Instru + 1; aCmd->note = theCommand->AmigaPeriod; Note = (aCmd->note & 0xF0) >> 4; Octave = (aCmd->note & 0x0F); aCmd->note = Note*12 + Octave; if (aCmd->note == 0) aCmd->note = 0xFF; else aCmd->note += 24; aCmd->vol = theCommand->Volume; aCmd->vol = (aCmd->vol * 64) / 15; } if (thePasByte[2] == 0xFF) { aCmd->cmd = 0; aCmd->arg = 0; } else { aCmd->cmd = 0; aCmd->arg = 0; } } } } return MADNoErr; }
OSErr MADFG2Mad( Ptr MADPtr, long size, MADMusic *theMAD, MADDriverSettings *init) { //TODO: byteswap on Intel! short i, x; long inOutCount = 0, OffSetToSample = 0, z = 0; OSErr theErr = noErr; Boolean MADConvert = false; Ptr tempPtr = NULL; long finetune[16] = { 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280 }; /**** Old MADFG variables ****/ oldMADSpec *oldMAD; oldMAD = (oldMADSpec*) MADPtr; /**** HEADER ****/ OSType oldMadIdent = oldMAD->MADIdentification; MOT32(&oldMadIdent); if( oldMadIdent == 'MADF') MADConvert = true; else if( oldMadIdent == 'MADG') MADConvert = false; else return MADFileNotSupportedByThisPlug; OffSetToSample += sizeof( oldMADSpec); // Conversion inOutCount = sizeof( MADSpec); theMAD->header = (MADSpec*) MADPlugNewPtrClear( inOutCount, init); if( theMAD->header == NULL) return MADNeedMemory; theMAD->header->MAD = 'MADK'; BlockMoveData( oldMAD->NameSignature, theMAD->header->name, 32); theMAD->header->numPat = oldMAD->PatMax; theMAD->header->numChn = oldMAD->Tracks; theMAD->header->numPointers = oldMAD->numPointers; BlockMoveData( oldMAD->oPointers, theMAD->header->oPointers, 128); theMAD->header->speed = 6; theMAD->header->tempo = 125; mystrcpy( theMAD->header->infos, "\pConverted by PlayerPRO MAD-F-G Plug (©Antoine ROSSET <*****@*****.**>)"); theMAD->sets = (FXSets*) NewPtrClear( MAXTRACK * sizeof(FXSets)); for( i = 0; i < MAXTRACK; i++) theMAD->header->chanBus[ i].copyId = i; /**** Patterns *******/ for( i = 0; i < oldMAD->PatMax; i++) { struct MusicPattern *tempPat, *tempPat2; struct oldPatHeader tempPatHeader; /** Lecture du header de la partition **/ if( !MADConvert) { inOutCount = sizeof( struct oldPatHeader); BlockMoveData( MADPtr + OffSetToSample, &tempPatHeader, inOutCount); MOT32(&tempPatHeader.PatternSize); } else tempPatHeader.PatternSize = 64L; /*************************************************/ /** Lecture du header + contenu de la partition **/ /*************************************************/ OSType CompMode = tempPatHeader.CompressionMode; MOT32(&CompMode); if( CompMode == 'MAD1') { inOutCount = sizeof( struct MusicPattern) + tempPatHeader.PatBytes; } else { inOutCount = sizeof( struct MusicPattern) + oldMAD->Tracks * tempPatHeader.PatternSize * sizeof( struct Command); } tempPat = (struct MusicPattern*) MADPlugNewPtr( inOutCount, init); if( tempPat == NULL) DebugStr("\pMemory Prob1"); if( MADConvert) { tempPat = (struct MusicPattern*) ((Ptr) tempPat + sizeof( struct oldPatHeader)); inOutCount -= sizeof( struct oldPatHeader); } BlockMoveData( MADPtr + OffSetToSample, tempPat, inOutCount); OffSetToSample += inOutCount; MOT32(&tempPat->header.PatternSize); MOT32(&tempPat->header.CompressionMode); if( MADConvert) { tempPat = (struct MusicPattern*) ((Ptr) tempPat - sizeof( struct oldPatHeader)); tempPat->header.PatternSize = 64L; tempPat->header.CompressionMode = 'NONE'; for( x = 0; x < 20; x++) tempPat->header.PatternName[ x] = 0; tempPat->header.unused2 = 0; } if( tempPat->header.CompressionMode == 'MAD1') { tempPat2 = oldDecompressPartitionMAD1( tempPat, oldMAD->Tracks, init); DisposePtr( (Ptr) tempPat); tempPat = tempPat2; } /**************/ /* CONVERSION */ /**************/ theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * tempPat->header.PatternSize * sizeof( Cmd), init); if( theMAD->partition[ i] == NULL) return MADNeedMemory; theMAD->partition[ i]->header.size = tempPat->header.PatternSize; theMAD->partition[ i]->header.compMode = 'NONE'; BlockMoveData( tempPat->header.PatternName, theMAD->partition[ i]->header.name, 20); theMAD->partition[ i]->header.patBytes = 0; theMAD->partition[ i]->header.unused2 = 0; for( x = 0; x < theMAD->partition[ i]->header.size; x++) { for( z = 0; z < theMAD->header->numChn; z++) { struct Command *oldCmd; Cmd *aCmd; aCmd = GetMADCommand( x, z, theMAD->partition[ i]); oldCmd = GetOldCommand( x, z, tempPat); aCmd->ins = oldCmd->InstrumentNo; if( oldCmd->AmigaPeriod == 0) aCmd->note = 0xFF; else aCmd->note = oldCmd->AmigaPeriod + 22; aCmd->cmd = oldCmd->EffectCmd; aCmd->arg = oldCmd->EffectArg; aCmd->vol = 0xFF; if( aCmd->cmd == 0x0C) { aCmd->vol = 0x10 + (aCmd->arg & 0x00FF); aCmd->cmd = 0; aCmd->arg = 0; } } } } for( i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[ i] = NULL; for( i = 0; i < MAXTRACK; i++) { if( i % 2 == 0) theMAD->header->chanPan[ i] = MAX_PANNING/4; else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4; theMAD->header->chanVol[ i] = MAX_VOLUME; } theMAD->header->generalVol = 64; theMAD->header->generalSpeed = 80; theMAD->header->generalPitch = 80; /**** Instruments header *****/ theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init); if( !theMAD->fid) return MADNeedMemory; theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init); if( !theMAD->sample) return MADNeedMemory; for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE; for( i = 0; i < 64; i++) { InstrData *curIns = &theMAD->fid[ i]; BlockMoveData( oldMAD->fid[ i].Filename, curIns->name, 32); curIns->type = 0; if( oldMAD->fid[ i].insSize > 0) { sData *curData; curIns->numSamples = 1; curIns->volFade = DEFAULT_VOLFADE; curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init); curData->size = oldMAD->fid[ i].insSize; curData->loopBeg = oldMAD->fid[ i].loopStart; curData->loopSize = oldMAD->fid[ i].loopLenght; curData->vol = oldMAD->fid[ i].volume; curData->c2spd = finetune[ oldMAD->fid[ i].fineTune]; curData->loopType = 0; curData->amp = oldMAD->fid[ i].amplitude; curData->relNote = 0; curData->data = MADPlugNewPtr( curData->size, init); if( curData->data == NULL) return MADNeedMemory; BlockMoveData( MADPtr + OffSetToSample, curData->data, curData->size); OffSetToSample += curData->size; } else curIns->numSamples = 0; } return noErr; }