29 |
|
|
30 |
// Modeled after output from SFZ Player 1.97 / Rapture Demo 1.0. |
// Modeled after output from SFZ Player 1.97 / Rapture Demo 1.0. |
31 |
|
|
|
// TODO: implement hold stage correctly |
|
|
|
|
32 |
void EGADSR::update(event_t Event, uint SampleRate) { |
void EGADSR::update(event_t Event, uint SampleRate) { |
33 |
if (atEnd(Event)) return; |
if (atEnd(Event)) return; |
34 |
|
|
39 |
enterReleaseStage(); |
enterReleaseStage(); |
40 |
break; |
break; |
41 |
case event_stage_end: |
case event_stage_end: |
42 |
if (HoldAttack) |
if (HoldSteps) |
43 |
enterAttackHoldStage(); |
enterAttackHoldStage(); |
44 |
else |
else |
45 |
enterDecayStage(SampleRate); |
enterDecayStage(SampleRate); |
94 |
} |
} |
95 |
} |
} |
96 |
|
|
97 |
// TODO: HoldAttack should be HoldTime and float |
void EGADSR::trigger(uint PreAttack, float AttackTime, float HoldTime, float DecayTime, uint SustainLevel, float ReleaseTime, uint SampleRate) { |
|
|
|
|
void EGADSR::trigger(uint PreAttack, float AttackTime, bool HoldAttack, float DecayTime, uint SustainLevel, float ReleaseTime, uint SampleRate) { |
|
98 |
this->SustainLevel = SustainLevel / 1000.0; |
this->SustainLevel = SustainLevel / 1000.0; |
99 |
this->HoldAttack = HoldAttack; |
this->HoldSteps = int(HoldTime * SampleRate); |
100 |
this->DecayTime = DecayTime; |
this->DecayTime = DecayTime; |
101 |
|
|
102 |
if (ReleaseTime < CONFIG_EG_MIN_RELEASE_TIME) ReleaseTime = CONFIG_EG_MIN_RELEASE_TIME; // to avoid click sounds at the end of the sample playback |
if (ReleaseTime < CONFIG_EG_MIN_RELEASE_TIME) ReleaseTime = CONFIG_EG_MIN_RELEASE_TIME; // to avoid click sounds at the end of the sample playback |
116 |
Coeff = (1.0f - Level) / StepsLeft; |
Coeff = (1.0f - Level) / StepsLeft; |
117 |
} else { // attack is zero - immediately jump to the next stage |
} else { // attack is zero - immediately jump to the next stage |
118 |
Level = 1.0f; |
Level = 1.0f; |
119 |
if (HoldAttack) enterAttackHoldStage(); |
if (HoldSteps) enterAttackHoldStage(); |
120 |
else enterDecayStage(SampleRate); |
else enterDecayStage(SampleRate); |
121 |
} |
} |
122 |
} |
} |
123 |
|
|
125 |
Stage = stage_attack_hold; |
Stage = stage_attack_hold; |
126 |
Segment = segment_lin; |
Segment = segment_lin; |
127 |
Coeff = 0.0f; // don't rise anymore |
Coeff = 0.0f; // don't rise anymore |
128 |
const int intMax = (unsigned int) -1 >> 1; |
StepsLeft = HoldSteps; |
|
StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case) |
|
129 |
} |
} |
130 |
|
|
131 |
void EGADSR::enterDecayStage(const uint SampleRate) { |
void EGADSR::enterDecayStage(const uint SampleRate) { |
137 |
Coeff = exp(slope); |
Coeff = exp(slope); |
138 |
StepsLeft = int(log(std::max(SustainLevel, float(CONFIG_EG_BOTTOM)) / Level) / slope); |
StepsLeft = int(log(std::max(SustainLevel, float(CONFIG_EG_BOTTOM)) / Level) / slope); |
139 |
if (StepsLeft > 0) return; |
if (StepsLeft > 0) return; |
|
|
|
|
enterSustainStage(); |
|
|
} else { |
|
|
enterSustainStage(); |
|
140 |
} |
} |
141 |
|
Level = SustainLevel; |
142 |
|
enterSustainStage(); |
143 |
} |
} |
144 |
|
|
145 |
void EGADSR::enterSustainStage() { |
void EGADSR::enterSustainStage() { |