void ConvertV2M(const unsigned char *inptr, const int inlen, unsigned char **outptr, int *outlen) { int i, p; // check version int vdelta = CheckV2MVersion(inptr, inlen); if (!vdelta) // if same, simply clone { *outptr = new uint8_t[inlen + 4]; memset(*outptr, 0, inlen + 4); *outlen = inlen + 4; memcpy(*outptr, inptr, inlen); return; } else if (vdelta < 0) // if invalid... { *outptr = 0; *outlen = 0; return; } vdelta = v2version - vdelta; // fake base.maxp int maxp2 = ((int*)base.patchmap)[0]/4; if (maxp2 != base.maxp) { printf2("warning: patch count inconsistency: we:%d, they:%d\n", base.maxp, maxp2); base.maxp = maxp2; } // calc new size int gdiff = v2gsizes[v2version] - v2gsizes[vdelta]; int pdiff = v2vsizes[v2version] - v2vsizes[vdelta]; int newsize = inlen + gdiff + base.maxp*pdiff; printf2("old size: %d, new size: %d\n", inlen, newsize); // init new v2m *outlen = newsize + 4; uint8_t *newptr = *outptr = new uint8_t[newsize + 4]; memset(newptr, 0, newsize + 4); // copy midi data memcpy(newptr, inptr, base.midisize); // new globals length... newptr += base.midisize; *(int *)newptr = v2ngparms; printf2("glob size: old %d, new %d\n", base.globsize, *(int *)newptr); newptr += 4; // copy/remap globals memcpy(newptr, v2initglobs, v2ngparms); const uint8_t *oldgptr = base.globals; for (i = 0; i < v2ngparms; i++) { if (v2gparms[i].version <= vdelta) newptr[i] = *oldgptr++; } newptr += v2ngparms; // new patch data length *(int *)newptr = base.patchsize + base.maxp*pdiff; printf2("patch size: old %d, new %d\n", base.patchsize, *(int *)newptr); newptr += 4; base.newpatchmap = newptr; int *poffsets = (int *)base.patchmap; int *noffsets = (int *)newptr; //const int ros = v2vsizes[vdelta] - 255*3 - 1; //uint8_t *nptr2 = newptr; // copy patch table... // gcc 5.3 seems to vectorize the loop, but // the loop is not correct for base.maxp == 10 at least // adding volatile to the iterator breaks the auto-vec for (volatile int q = 0; q < base.maxp; q++) { noffsets[q] = poffsets[q] + (q * pdiff); } newptr += 4*base.maxp; // for each patch... for (p = 0; p < base.maxp; p++) { const uint8_t *src = base.patchmap + poffsets[p]; //const uint8_t *dest_soll = nptr2 + noffsets[p]; printf2("p%d ist:%08x soll:%08x\n", p, newptr, dest_soll); // fill patch with default values memcpy(newptr, v2initsnd, v2nparms); // copy/remap patch data for (i = 0; i < v2nparms; i++) { if (v2parms[i].version <= vdelta) { *newptr = *src++; /* if (vdelta < 2 && (i == 33 || i == 36 || i == 39 || i == 42)) // fix envelopes *newptr=transEnv(*newptr); */ } newptr++; } // copy mod number const int modnum = *newptr ++= *src++; // printf2("patch %d: %d mods\n",p,modnum); // copy/remap modulations for (i = 0; i < modnum; i++) { newptr[0] = src[0]; newptr[1] = src[1]; newptr[2] = src[2]; for (int k = 0; k <= newptr[2]; k++) if (v2parms[k].version > vdelta) newptr[2]++; newptr += 3; src += 3; } } // copy speech *(uint32_t*)newptr = base.spsize; newptr += 4; memcpy(newptr, base.speechdata, base.spsize); newptr += base.spsize; printf2("est size: %d, real size: %d\n", newsize, newptr - *outptr); }
void ConvertV2M(const unsigned char *inptr, const int inlen, unsigned char **outptr, int *outlen) { int i,p; // check version sInt vdelta=CheckV2MVersion(inptr,inlen); if (!vdelta) // if same, simply clone { *outptr=new sU8[inlen]; *outlen=inlen; memcpy(*outptr,inptr,*outlen); return; } else if (vdelta<0) // if invalid... { *outptr=0; *outlen=0; return; } vdelta=v2version-vdelta; // calc new size int newsize=inlen+v2gsizes[v2version]-v2gsizes[vdelta]+base.maxp*(v2vsizes[v2version]-v2vsizes[vdelta]); // init new v2m *outlen=newsize; sU8 *newptr=*outptr=new sU8[newsize]; // copy midi data memcpy(newptr,inptr,base.midisize); // new globals length... newptr+=base.midisize; *(sInt *)newptr=v2ngparms; newptr+=4; // copy/remap globals memcpy(newptr,v2initglobs,v2ngparms); const sU8 *oldgptr=base.globals; for (i=0; i<v2ngparms; i++) { if (v2gparms[i].version<=vdelta) newptr[i]=*oldgptr++; } newptr+=v2ngparms; // new patch data length *(sInt *)newptr=base.patchsize+base.maxp*(v2vsizes[v2version]-v2vsizes[vdelta]); newptr+=4; sInt *poffsets=(sInt *)base.patchmap; sInt *noffsets=(sInt *)newptr; const int ros=v2vsizes[vdelta]-255*3-1; // copy patch table... for (p=0; p<base.maxp; p++) noffsets[p]=poffsets[p]+p*(v2vsizes[v2version]-v2vsizes[vdelta]); newptr+=4*base.maxp; // for each patch... for (p=0; p<base.maxp; p++) { const sU8 *src=base.patchmap+poffsets[p]; // fill patch with default values memcpy(newptr,v2initsnd,v2nparms); // copy/remap patch data for (i=0; i<v2nparms; i++) { if (v2parms[i].version<=vdelta) { *newptr=*src++; if (vdelta<2 && (i==33 || i==36 || i==39 || i==42)) // fix envelopes *newptr=transEnv(*newptr); } newptr++; } // copy mod number const sInt modnum=*newptr++=*src++; // copy/remap modulations for (i=0; i<modnum; i++) { newptr[0]=src[0]; newptr[1]=src[1]; newptr[2]=src[2]; for (int k=0; k<=newptr[2]; k++) if (v2parms[k].version>vdelta) newptr[2]++; newptr+=3; src+=3; } } }