136 |
CrossfadeVolume = 1.0f; |
CrossfadeVolume = 1.0f; |
137 |
} |
} |
138 |
|
|
139 |
PanLeft = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) / 63.0f; |
PanLeft = Engine::PanCurve[64 - pDimRgn->Pan]; |
140 |
PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f; |
PanRight = Engine::PanCurve[64 + pDimRgn->Pan]; |
141 |
|
|
142 |
finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points) |
finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points) |
143 |
Pos = pDimRgn->SampleStartOffset; |
Pos = pDimRgn->SampleStartOffset; |
223 |
pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); |
pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); |
224 |
} |
} |
225 |
|
|
226 |
|
// setup initial volume in synthesis parameters |
227 |
|
fFinalVolume = getVolume() * EG1.getLevel(); |
228 |
|
finalSynthesisParameters.fFinalVolumeLeft = fFinalVolume * PanLeft * pEngineChannel->GlobalPanLeft; |
229 |
|
finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight * pEngineChannel->GlobalPanRight; |
230 |
|
|
231 |
|
|
232 |
// setup EG 2 (VCF Cutoff EG) |
// setup EG 2 (VCF Cutoff EG) |
233 |
{ |
{ |
703 |
|
|
704 |
void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) { |
void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) { |
705 |
CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value); |
CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value); |
706 |
|
fFinalVolume = getVolume(); |
707 |
|
} |
708 |
|
|
709 |
|
float Voice::getVolume() { |
710 |
#if CONFIG_PROCESS_MUTED_CHANNELS |
#if CONFIG_PROCESS_MUTED_CHANNELS |
711 |
const float effectiveVolume = CrossfadeVolume * Volume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume); |
return pEngineChannel->GetMute() ? 0 : (Volume * CrossfadeVolume * pEngineChannel->GlobalVolume); |
712 |
#else |
#else |
713 |
const float effectiveVolume = CrossfadeVolume * Volume * pEngineChannel->GlobalVolume; |
return Volume * CrossfadeVolume * pEngineChannel->GlobalVolume; |
714 |
#endif |
#endif |
|
fFinalVolume = effectiveVolume; |
|
715 |
} |
} |
716 |
|
|
717 |
void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) { |
void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) { |
763 |
uint killPos; |
uint killPos; |
764 |
if (itKillEvent) killPos = RTMath::Min(itKillEvent->FragmentPos(), pEngine->MaxFadeOutPos); |
if (itKillEvent) killPos = RTMath::Min(itKillEvent->FragmentPos(), pEngine->MaxFadeOutPos); |
765 |
|
|
766 |
|
float fFinalPanLeft = PanLeft * pEngineChannel->GlobalPanLeft; |
767 |
|
float fFinalPanRight = PanRight * pEngineChannel->GlobalPanRight; |
768 |
|
|
769 |
uint i = Skip; |
uint i = Skip; |
770 |
while (i < Samples) { |
while (i < Samples) { |
771 |
int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples); |
int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples); |
772 |
|
|
773 |
// initialize all final synthesis parameters |
// initialize all final synthesis parameters |
774 |
finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend; |
finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend; |
775 |
#if CONFIG_PROCESS_MUTED_CHANNELS |
fFinalVolume = getVolume(); |
|
fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume); |
|
|
#else |
|
|
fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume; |
|
|
#endif |
|
776 |
fFinalCutoff = VCFCutoffCtrl.fvalue; |
fFinalCutoff = VCFCutoffCtrl.fvalue; |
777 |
fFinalResonance = VCFResonanceCtrl.fvalue; |
fFinalResonance = VCFResonanceCtrl.fvalue; |
778 |
|
|
832 |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired); |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired); |
833 |
|
|
834 |
// prepare final synthesis parameters structure |
// prepare final synthesis parameters structure |
|
finalSynthesisParameters.fFinalVolumeLeft = fFinalVolume * PanLeft; |
|
|
finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight; |
|
835 |
finalSynthesisParameters.uiToGo = iSubFragmentEnd - i; |
finalSynthesisParameters.uiToGo = iSubFragmentEnd - i; |
836 |
|
#ifdef CONFIG_INTERPOLATE_VOLUME |
837 |
|
finalSynthesisParameters.fFinalVolumeDeltaLeft = |
838 |
|
(fFinalVolume * fFinalPanLeft - finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo; |
839 |
|
finalSynthesisParameters.fFinalVolumeDeltaRight = |
840 |
|
(fFinalVolume * fFinalPanRight - finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo; |
841 |
|
#else |
842 |
|
finalSynthesisParameters.fFinalVolumeLeft = fFinalVolume * fFinalPanLeft; |
843 |
|
finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * fFinalPanRight; |
844 |
|
#endif |
845 |
// render audio for one subfragment |
// render audio for one subfragment |
846 |
RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop); |
RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop); |
847 |
|
|
848 |
|
// stop the rendering if volume EG is finished |
849 |
|
if (EG1.getSegmentType() == EGADSR::segment_end) break; |
850 |
|
|
851 |
const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch; |
const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch; |
852 |
|
|
853 |
// increment envelopes' positions |
// increment envelopes' positions |