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; }
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; }