@@ -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 attackDuration ;
100
+ private double decayDuration ;
99
101
private float attenuation ;
100
- private int releaseDuration ;
102
+ private double releaseDuration ;
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 .attackDuration = 1000D / ( double ) ( Math .max ( attackDuration , 1 ) * Config .SOUND_SAMPLE_RATE );
109
+ this .decayDuration = (( this . attenuation - 1D ) * 1000D ) / ( double ) ( Math . max ( decayDuration , 1 ) * Config . SOUND_SAMPLE_RATE ) ;
110
+ this .releaseDuration = (- this . attenuation * 1000D ) / ( double ) ( Math . max ( releaseDuration , 1 ) * Config . SOUND_SAMPLE_RATE );
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 = 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) attackDuration);
124
+ if ((progress += attackDuration ) >= 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) decayDuration)));
132
+ if ((progress += decayDuration ) <= 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) releaseDuration)));
140
+ if (( progress + = releaseDuration ) <= 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