24 |
|
|
25 |
namespace LinuxSampler { namespace gig { |
namespace LinuxSampler { namespace gig { |
26 |
|
|
27 |
const float EGADSR::EndCoeff(CalculateEndCoeff()); |
const float EGADSR::FadeOutCoeff(CalculateFadeOutCoeff()); |
28 |
|
|
29 |
float EGADSR::CalculateEndCoeff() { |
float EGADSR::CalculateFadeOutCoeff() { |
30 |
const float sampleRate = 44100.0; // even if the sample rate will be 192kHz it won't hurt at all |
const float sampleRate = 44100.0; // even if the sample rate will be 192kHz it won't hurt at all |
31 |
const float killSteps = EG_MIN_RELEASE_TIME * sampleRate; |
const float killSteps = EG_MIN_RELEASE_TIME * sampleRate; |
32 |
return 1.0f / killSteps; |
return 1.0f / killSteps; |
63 |
pTransitionEvent = pEvents->first(); |
pTransitionEvent = pEvents->first(); |
64 |
} |
} |
65 |
|
|
66 |
// if the voice was killed in this fragment we only process the time before this kill event and then switch to 'stage_end' |
// if the voice was killed in this fragment we only process the time before this kill event, then switch to 'stage_fadeout' |
67 |
int Samples = (pKillEvent) ? pKillEvent->FragmentPos() : (int) TotalSamples; |
int Samples = (pKillEvent) ? pKillEvent->FragmentPos() : (int) TotalSamples; |
68 |
|
|
69 |
int iSample = TriggerDelay; |
int iSample = TriggerDelay; |
70 |
while (iSample < TotalSamples) { |
while (iSample < TotalSamples) { |
71 |
|
|
72 |
// if the voice was killed in this fragment and we already processed the time before this kill event |
// if the voice was killed in this fragment and we already processed the time before this kill event |
73 |
if (pKillEvent && iSample >= Samples) Stage = stage_end; |
if (pKillEvent && iSample >= Samples) Stage = stage_fadeout; |
74 |
|
|
75 |
switch (Stage) { |
switch (Stage) { |
76 |
case stage_attack: { |
case stage_attack: { |
138 |
Level += Level * Decay2Coeff; |
Level += Level * Decay2Coeff; |
139 |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] *= Level; |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] *= Level; |
140 |
} |
} |
141 |
if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_end; |
if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_fadeout; |
142 |
break; |
break; |
143 |
} |
} |
144 |
case stage_sustain: { |
case stage_sustain: { |
166 |
Level += Level * ReleaseCoeff; |
Level += Level * ReleaseCoeff; |
167 |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] *= Level; |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] *= Level; |
168 |
} |
} |
169 |
if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_end; |
if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_fadeout; |
170 |
break; |
break; |
171 |
} |
} |
172 |
case stage_end: { |
case stage_fadeout: { |
173 |
int to_process = RTMath::Min(int(Level / EndCoeff), TotalSamples - iSample); |
int to_process = RTMath::Min(int(Level / (-FadeOutCoeff)), TotalSamples - iSample); |
174 |
int process_end = iSample + to_process; |
int process_end = iSample + to_process; |
175 |
while (iSample < process_end) { |
while (iSample < process_end) { |
176 |
Level += EndCoeff; |
Level += FadeOutCoeff; |
177 |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] *= Level; |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] *= Level; |
178 |
} |
} |
179 |
|
if (Level <= FadeOutCoeff) Stage = stage_end; |
180 |
|
break; |
181 |
|
} |
182 |
|
case stage_end: { |
183 |
while (iSample < TotalSamples) { |
while (iSample < TotalSamples) { |
184 |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] = 0.0f; |
pEngine->pSynthesisParameters[ModulationDestination][iSample++] = 0.0f; |
185 |
} |
} |