Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 655c8fd

Browse files
committedMay 7, 2016
ADSR now properly releases when the Gate is closed during any phase other than Sustain.
1 parent 297a414 commit 655c8fd

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed
 

‎src/main/java/pl/asie/computronics/util/sound/AudioUtil.java

+26-26
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public double getValue(AudioState process, State state) {
3838
Closed {
3939
@Override
4040
public double getValue(AudioState process, State state) {
41+
if(state.envelope != null && state.envelope.phase != null) {
42+
return Open.getValue(process, state);
43+
}
4144
return 0;
4245
}
4346
};
@@ -87,25 +90,24 @@ public double getModifiedValue(AudioState process, State state, double value) {
8790
if(mstate.gate == Gate.Closed) {
8891
return value;
8992
}
90-
Wave modulator = mstate.wave;
9193
return value * (1 + mstate.gate.getValue(process, mstate));
9294
}
9395
}
9496

9597
public static class ADSR {
9698

97-
private int attackDuration;
98-
private int decayDuration;
99+
private double attackSpeed;
100+
private double decaySpeed;
99101
private float attenuation;
100-
private int releaseDuration;
102+
private double releaseSpeed;
101103
private Phase phase = Phase.Attack;
102-
private int progress;
104+
private double progress = 0;
103105

104106
public ADSR(int attackDuration, int decayDuration, float attenuation, int releaseDuration) {
105-
this.attackDuration = Math.min(attackDuration * Config.SOUND_SAMPLE_RATE / 1000, 1);
106-
this.decayDuration = Math.min(decayDuration * Config.SOUND_SAMPLE_RATE / 1000, 1);
107-
this.attenuation = attenuation;
108-
this.releaseDuration = Math.min(releaseDuration * Config.SOUND_SAMPLE_RATE / 1000, 1);
107+
this.attenuation = Math.min(Math.max(attenuation, 0), 1);
108+
this.attackSpeed = attackDuration > 0 ? 1000D / (double) (attackDuration * Config.SOUND_SAMPLE_RATE) : -1;
109+
this.decaySpeed = decayDuration > 0 ? ((this.attenuation - 1D) * 1000D) / (double) (decayDuration * Config.SOUND_SAMPLE_RATE) : -1;
110+
this.releaseSpeed = releaseDuration > 0 ? (-this.attenuation * 1000D) / (double) (releaseDuration * Config.SOUND_SAMPLE_RATE) : -1;
109111
}
110112

111113
public double getModifiedValue(State state, double value) {
@@ -114,41 +116,39 @@ public double getModifiedValue(State state, double value) {
114116
}
115117
if(state.gate == Gate.Closed && phase != Phase.Release) {
116118
phase = Phase.Release;
117-
progress = 0;
118119
}
120+
value *= progress;
119121
switch(phase) {
120122
case Attack: {
121-
value = value * (progress / attackDuration);
122-
if(++progress >= attackDuration) {
123-
nextPhase(state);
123+
// value = value * (progress / (double) attackSpeed);
124+
if(attackSpeed < 0 || (progress += attackSpeed) >= 1) {
125+
progress = 1;
126+
nextPhase();
124127
}
125-
return value;
128+
break;
126129
}
127130
case Decay: {
128-
value = value * (((attenuation - 1) * (progress / decayDuration)) + 1);
129-
if(++progress >= decayDuration) {
130-
nextPhase(state);
131+
// value = value * (1 + ((attenuation - 1) * (progress / (double) decaySpeed)));
132+
if(decaySpeed < 0 || (progress += decaySpeed) <= attenuation) {
133+
progress = attenuation;
134+
nextPhase();
131135
}
132-
return value;
133-
}
134-
case Sustain: {
135-
return value * attenuation;
136+
break;
136137
}
137138
case Release: {
138-
value = value * (((-attenuation) * (progress / releaseDuration)) + attenuation);
139-
if(++progress >= releaseDuration) {
139+
// value = value * (attenuation * (1 - (progress / (double) releaseSpeed)));
140+
if(releaseSpeed < 0 || (progress += releaseSpeed) <= 0) {
140141
phase = null;
141142
progress = 0;
142143
}
143-
return value;
144+
break;
144145
}
145146
}
146147
return value;
147148
}
148149

149-
private void nextPhase(State state) {
150+
private void nextPhase() {
150151
phase = phase.next();
151-
progress = 0;
152152
}
153153

154154
private enum Phase {

0 commit comments

Comments
 (0)
Please sign in to comment.