491 |
// *************** DimensionRegion *************** |
// *************** DimensionRegion *************** |
492 |
// * |
// * |
493 |
|
|
494 |
|
uint DimensionRegion::Instances = 0; |
495 |
|
DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL; |
496 |
|
|
497 |
DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) { |
DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) { |
498 |
|
Instances++; |
499 |
|
|
500 |
memcpy(&Crossfade, &SamplerOptions, 4); |
memcpy(&Crossfade, &SamplerOptions, 4); |
501 |
|
if (!pVelocityTables) pVelocityTables = new VelocityTableMap; |
502 |
|
|
503 |
RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA); |
RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA); |
504 |
_3ewa->ReadInt32(); // unknown, allways 0x0000008C ? |
_3ewa->ReadInt32(); // unknown, allways 0x0000008C ? |
650 |
VCFVelocityDynamicRange = vcfvelocity % 5; |
VCFVelocityDynamicRange = vcfvelocity % 5; |
651 |
VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5); |
VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5); |
652 |
VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8()); |
VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8()); |
653 |
|
|
654 |
|
// get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet |
655 |
|
uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling; |
656 |
|
if (pVelocityTables->count(tableKey)) { // if key exists |
657 |
|
pVelocityAttenuationTable = (*pVelocityTables)[tableKey]; |
658 |
|
} |
659 |
|
else { |
660 |
|
pVelocityAttenuationTable = new double[128]; |
661 |
|
switch (VelocityResponseCurve) { // calculate the new table |
662 |
|
case curve_type_nonlinear: |
663 |
|
for (int velocity = 0; velocity < 128; velocity++) { |
664 |
|
pVelocityAttenuationTable[velocity] = |
665 |
|
GIG_VELOCITY_TRANSFORM_NONLINEAR((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling); |
666 |
|
if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0; |
667 |
|
else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0; |
668 |
|
} |
669 |
|
break; |
670 |
|
case curve_type_linear: |
671 |
|
for (int velocity = 0; velocity < 128; velocity++) { |
672 |
|
pVelocityAttenuationTable[velocity] = |
673 |
|
GIG_VELOCITY_TRANSFORM_LINEAR((double)velocity,(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling); |
674 |
|
if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0; |
675 |
|
else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0; |
676 |
|
} |
677 |
|
break; |
678 |
|
case curve_type_special: |
679 |
|
for (int velocity = 0; velocity < 128; velocity++) { |
680 |
|
pVelocityAttenuationTable[velocity] = |
681 |
|
GIG_VELOCITY_TRANSFORM_SPECIAL((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling); |
682 |
|
if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0; |
683 |
|
else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0; |
684 |
|
} |
685 |
|
break; |
686 |
|
case curve_type_unknown: |
687 |
|
default: |
688 |
|
throw gig::Exception("Unknown transform curve type."); |
689 |
|
} |
690 |
|
(*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map |
691 |
|
} |
692 |
|
} |
693 |
|
|
694 |
|
DimensionRegion::~DimensionRegion() { |
695 |
|
Instances--; |
696 |
|
if (!Instances) { |
697 |
|
// delete the velocity->volume tables |
698 |
|
VelocityTableMap::iterator iter; |
699 |
|
for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) { |
700 |
|
double* pTable = iter->second; |
701 |
|
if (pTable) delete[] pTable; |
702 |
|
} |
703 |
|
pVelocityTables->clear(); |
704 |
|
delete pVelocityTables; |
705 |
|
pVelocityTables = NULL; |
706 |
|
} |
707 |
|
} |
708 |
|
|
709 |
|
/** |
710 |
|
* Returns the correct amplitude factor for the given \a MIDIKeyVelocity. |
711 |
|
* All involved parameters (VelocityResponseCurve, VelocityResponseDepth |
712 |
|
* and VelocityResponseCurveScaling) involved are taken into account to |
713 |
|
* calculate the amplitude factor. Use this method when a key was |
714 |
|
* triggered to get the volume with which the sample should be played |
715 |
|
* back. |
716 |
|
* |
717 |
|
* @param MIDI velocity value of the triggered key (between 0 and 127) |
718 |
|
* @returns amplitude factor (between 0.0 and 1.0) |
719 |
|
*/ |
720 |
|
double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) { |
721 |
|
return pVelocityAttenuationTable[MIDIKeyVelocity]; |
722 |
} |
} |
723 |
|
|
724 |
|
|