--- libgig/trunk/src/gig.cpp 2005/06/19 15:18:59 666 +++ libgig/trunk/src/gig.cpp 2005/07/26 11:13:53 728 @@ -132,35 +132,24 @@ { // Note: The 24 bits are truncated to 16 bits for now. - // Note: The calculation of the initial value of y is strange - // and not 100% correct. What should the first two parameters - // really be used for? Why are they two? The correct value for - // y seems to lie somewhere between the values of the first - // two parameters. - // - // Strange thing #2: The formula in SKIP_ONE gives values for - // y that are twice as high as they should be. That's why - // COPY_ONE shifts an extra step, and also why y is - // initialized with a sum instead of a mean value. - - int y, dy, ddy; - + int y, dy, ddy, dddy; const int shift = 8 - truncatedBits; - const int shift1 = shift + 1; -#define GET_PARAMS(params) \ - y = (get24(params) + get24((params) + 3)); \ - dy = get24((params) + 6); \ - ddy = get24((params) + 9) +#define GET_PARAMS(params) \ + y = get24(params); \ + dy = y - get24((params) + 3); \ + ddy = get24((params) + 6); \ + dddy = get24((params) + 9) #define SKIP_ONE(x) \ - ddy -= (x); \ - dy -= ddy; \ - y -= dy + dddy -= (x); \ + ddy -= dddy; \ + dy = -dy - ddy; \ + y += dy #define COPY_ONE(x) \ SKIP_ONE(x); \ - *pDst = y >> shift1; \ + *pDst = y >> shift; \ pDst += dstStep switch (compressionmode) { @@ -1145,7 +1134,9 @@ VCFEnabled = vcfcutoff & 0x80; // bit 7 VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits VCFCutoffController = static_cast(_3ewa->ReadUint8()); - VCFVelocityScale = _3ewa->ReadUint8(); + uint8_t vcfvelscale = _3ewa->ReadUint8(); + VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7 + VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits _3ewa->ReadInt8(); // unknown uint8_t vcfresonance = _3ewa->ReadUint8(); VCFResonance = vcfresonance & 0x7f; // lower 7 bits @@ -1172,7 +1163,6 @@ // this models a strange behaviour or bug in GSt: two of the // velocity response curves for release time are not used even // if specified, instead another curve is chosen. - if ((curveType == curve_type_nonlinear && depth == 0) || (curveType == curve_type_special && depth == 4)) { curveType = curve_type_nonlinear; @@ -1180,6 +1170,20 @@ } pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0); + curveType = VCFVelocityCurve; + depth = VCFVelocityDynamicRange; + + // even stranger GSt: two of the velocity response curves for + // filter cutoff are not used, instead another special curve + // is chosen. This curve is not used anywhere else. + if ((curveType == curve_type_nonlinear && depth == 0) || + (curveType == curve_type_special && depth == 4)) { + curveType = curve_type_special; + depth = 5; + } + pVelocityCutoffTable = GetVelocityTable(curveType, depth, + VCFCutoffController == vcf_cutoff_ctrl_none ? VCFVelocityScale : 0); + SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360)); } @@ -1350,6 +1354,10 @@ return pVelocityReleaseTable[MIDIKeyVelocity]; } + double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) { + return pVelocityCutoffTable[MIDIKeyVelocity]; + } + double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) { // line-segment approximations of the 15 velocity curves @@ -1383,9 +1391,13 @@ const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127, 127, 127 }; + // this is only used by the VCF velocity curve + const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106, + 91, 127, 127, 127 }; + const int* const curves[] = { non0, non1, non2, non3, non4, lin0, lin1, lin2, lin3, lin4, - spe0, spe1, spe2, spe3, spe4 }; + spe0, spe1, spe2, spe3, spe4, spe5 }; double* const table = new double[128];