@@ -38,6 +38,9 @@ public double getValue(AudioState process, State state) {
38
38
Closed {
39
39
@ Override
40
40
public double getValue (AudioState process , State state ) {
41
+ if (state .envelope != null && state .envelope .phase != null ) {
42
+ return Open .getValue (process , state );
43
+ }
41
44
return 0 ;
42
45
}
43
46
};
@@ -87,25 +90,27 @@ public double getModifiedValue(AudioState process, State state, double value) {
87
90
if (mstate .gate == Gate .Closed ) {
88
91
return value ;
89
92
}
90
- Wave modulator = mstate .wave ;
91
93
return value * (1 + mstate .gate .getValue (process , mstate ));
92
94
}
93
95
}
94
96
95
97
public static class ADSR {
96
98
97
- private int attackDuration ;
98
- private int decayDuration ;
99
+ private double attackSpeed ;
100
+ private double decaySpeed ;
99
101
private float attenuation ;
100
- private int releaseDuration ;
102
+ private double releaseSpeed ;
101
103
private Phase phase = Phase .Attack ;
102
- private int progress ;
104
+ private double progress = 0 ;
103
105
104
106
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 = 1000D / (double ) (Math .max (attackDuration , 0 ) * Config .SOUND_SAMPLE_RATE );
109
+ if (attackDuration == 0 ) {
110
+ this .phase = Phase .Decay ;
111
+ }
112
+ this .decaySpeed = ((this .attenuation - 1D ) * 1000D ) / (double ) (Math .max (decayDuration , 0 ) * Config .SOUND_SAMPLE_RATE );
113
+ this .releaseSpeed = (-this .attenuation * 1000D ) / (double ) (Math .max (releaseDuration , 0 ) * Config .SOUND_SAMPLE_RATE );
109
114
}
110
115
111
116
public double getModifiedValue (State state , double value ) {
@@ -114,41 +119,39 @@ public double getModifiedValue(State state, double value) {
114
119
}
115
120
if (state .gate == Gate .Closed && phase != Phase .Release ) {
116
121
phase = Phase .Release ;
117
- progress = 0 ;
118
122
}
119
123
switch (phase ) {
120
124
case Attack : {
121
- value = value * (progress / attackDuration );
122
- if (++progress >= attackDuration ) {
123
- nextPhase (state );
125
+ // value = value * (progress / (double) attackSpeed);
126
+ if ((progress += attackSpeed ) >= 1 ) {
127
+ progress = 1 ;
128
+ nextPhase ();
124
129
}
125
- return value ;
130
+ break ;
126
131
}
127
132
case Decay : {
128
- value = value * (((attenuation - 1 ) * (progress / decayDuration )) + 1 );
129
- if (++progress >= decayDuration ) {
130
- nextPhase (state );
133
+ // value = value * (1 + ((attenuation - 1) * (progress / (double) decaySpeed)));
134
+ if ((progress += decaySpeed ) <= attenuation ) {
135
+ progress = attenuation ;
136
+ nextPhase ();
131
137
}
132
- return value ;
133
- }
134
- case Sustain : {
135
- return value * attenuation ;
138
+ break ;
136
139
}
137
140
case Release : {
138
- value = value * (((- attenuation ) * (progress / releaseDuration )) + attenuation );
139
- if (++ progress >= releaseDuration ) {
141
+ // value = value * (attenuation * (1 - ( progress / (double) releaseSpeed)) );
142
+ if (( progress += releaseSpeed ) <= 0 ) {
140
143
phase = null ;
141
144
progress = 0 ;
142
145
}
143
- return value ;
146
+ break ;
144
147
}
145
148
}
149
+ value *= progress ;
146
150
return value ;
147
151
}
148
152
149
- private void nextPhase (State state ) {
153
+ private void nextPhase () {
150
154
phase = phase .next ();
151
- progress = 0 ;
152
155
}
153
156
154
157
private enum Phase {
0 commit comments