@@ -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,24 @@ 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 = 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 ;
109
111
}
110
112
111
113
public double getModifiedValue (State state , double value ) {
@@ -114,41 +116,39 @@ public double getModifiedValue(State state, double value) {
114
116
}
115
117
if (state .gate == Gate .Closed && phase != Phase .Release ) {
116
118
phase = Phase .Release ;
117
- progress = 0 ;
118
119
}
120
+ value *= progress ;
119
121
switch (phase ) {
120
122
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 ();
124
127
}
125
- return value ;
128
+ break ;
126
129
}
127
130
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 ();
131
135
}
132
- return value ;
133
- }
134
- case Sustain : {
135
- return value * attenuation ;
136
+ break ;
136
137
}
137
138
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 ) {
140
141
phase = null ;
141
142
progress = 0 ;
142
143
}
143
- return value ;
144
+ break ;
144
145
}
145
146
}
146
147
return value ;
147
148
}
148
149
149
- private void nextPhase (State state ) {
150
+ private void nextPhase () {
150
151
phase = phase .next ();
151
- progress = 0 ;
152
152
}
153
153
154
154
private enum Phase {
0 commit comments