aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspl3g <spleefer6@yandex.ru>2025-11-23 20:39:57 +0300
committerspl3g <spleefer6@yandex.ru>2025-11-23 20:39:57 +0300
commitcb52166c672c801bed3c2cbfc7428526d8d59ba1 (patch)
tree30fd0d58ca616e4efd3927630839cba66d2ac028
parentd1f644fd6c2c318591c44f118a6204f703b494e8 (diff)
Finally fix the envelope bug (i hope)
-rw-r--r--src/sounds.c96
1 files changed, 49 insertions, 47 deletions
diff --git a/src/sounds.c b/src/sounds.c
index 89da2b0..9b9e7b3 100644
--- a/src/sounds.c
+++ b/src/sounds.c
@@ -54,9 +54,52 @@ typedef struct {
typedef float (*OscilatorFunc)(float phase);
-float envelope_next(Envelope *env) {
- bool next_state = false;
+float envelope_handle_attack(Envelope *env) {
+ if (env->current_inc == 0) {
+ env->current_inc = (1.0 - env->current_value) / (float)env->params.attack_time;
+ }
+
+ env->current_value += env->current_inc;
+
+ if (env->counter >= env->params.attack_time) {
+ env->counter = env->current_inc = 0;
+ env->state = ENV_DECAY;
+ }
+
+ return env->current_value;
+}
+
+float envelope_handle_decay(Envelope *env) {
+ if (env->current_inc == 0) {
+ env->current_inc = (1.0 - env->params.sustain_level) / (float)env->params.decay_time;
+ }
+
+ env->current_value -= env->current_inc;
+
+ if (env->counter >= env->params.decay_time) {
+ env->counter = env->current_inc = 0;
+ env->state = ENV_SUSTAIN;
+ }
+
+ return env->current_value;
+}
+
+float envelope_handle_release(Envelope *env) {
+ if (env->current_inc == 0) {
+ env->current_inc = env->params.sustain_level / (float)env->params.release_time;
+ }
+
+ env->current_value -= env->current_inc;
+
+ if (env->counter >= env->params.release_time || env->current_value <= 0) {
+ env->counter = env->current_inc = env->current_value = 0;
+ env->state = ENV_OFF;
+ }
+
+ return env->current_value;
+}
+float envelope_next(Envelope *env) {
env->counter++;
switch (env->state) {
@@ -64,60 +107,19 @@ float envelope_next(Envelope *env) {
return 0;
}
case ENV_ATTACK: {
- if (env->counter >= env->params.attack_time) {
- next_state = true;
- }
-
- if (env->current_inc == 0) {
- env->current_inc = (1.0 - env->current_value) / (float)env->params.attack_time;
- }
-
- env->current_value += env->current_inc;
- break;
+ return envelope_handle_attack(env);
}
case ENV_DECAY: {
- if (env->counter >= env->params.decay_time) {
- next_state = true;
- }
-
- if (env->current_inc == 0) {
- env->current_inc = (1.0 - env->params.sustain_level) / (float)env->params.decay_time;
- }
-
- env->current_value -= env->current_inc;
- break;
+ return envelope_handle_decay(env);
}
case ENV_SUSTAIN: {
env->current_value = env->params.sustain_level;
- break;
+ return env->current_value;
}
case ENV_RELEASE: {
- if (env->counter >= env->params.release_time) {
- env->state = ENV_OFF;
- env->counter = env->current_inc = env->current_value = 0;
- return 0;
- }
-
- if (env->current_inc == 0) {
- float from_level;
- if (env->params.sustain_level > env->current_value) {
- from_level = (env->params.sustain_level - env->current_value);
- }else {
- from_level = env->current_value;
- }
- env->current_inc = from_level / (float)env->params.release_time;
- }
-
- env->current_value -= env->current_inc;
- break;
- }
+ return envelope_handle_release(env);
}
-
- if (next_state) {
- env->counter = env->current_inc = 0;
- env->state++;
}
- return env->current_value;
}
void envelope_note_on(EnvelopeParams params, Envelope *env) {