commit 84b25440a67de620be2d45a5b4a034d1e2f46442
parent 090c1d04e0040e4c3463d65019df66c244e952cc
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date: Wed, 7 Jan 2015 00:54:43 +0100
thyns: add env parameters
Diffstat:
3 files changed, 137 insertions(+), 20 deletions(-)
diff --git a/examples/thyns/env.h b/examples/thyns/env.h
@@ -12,61 +12,154 @@ enum thyns_env_state
THYNS_ENV_IDLE = 4,
};
+enum thyns_env_param_index
+{
+ THYNS_ENV_PARAM_ATTACK = 0,
+ THYNS_ENV_PARAM_DECAY,
+ THYNS_ENV_PARAM_SUSTAIN,
+ THYNS_ENV_PARAM_RELEASE,
+ THYNS_ENV_PARAM_COUNT
+};
+
struct thyns_env
{
// state
enum thyns_env_state state;
- double ar; // attack ramp
- double dr; // decay ramp
- double s; // sustain level
- double rr; // release ramp
+ double msr; // 1000 / sr
double v;
+
+ union clap_param_value *values[THYNS_ENV_PARAM_COUNT];
};
-static inline void thyns_env_init(struct thyns_env * restrict env)
+static inline void
+thyns_env_param_info(uint32_t index,
+ union clap_param_value value,
+ const char *prefix,
+ struct clap_param *param)
+{
+#define P(Dst, Args...) snprintf(Dst, sizeof (Dst), Args);
+
+ switch (index) {
+ case THYNS_ENV_PARAM_ATTACK:
+ P(param->id, "%s%s", prefix, "attack");
+ P(param->name, "%s", "attack");
+ P(param->desc, "%s", "Envelope's attack in ms");
+ P(param->display, "%f ms", value.f);
+ param->type = CLAP_PARAM_FLOAT;
+ param->is_per_note = true;
+ param->is_used = true;
+ param->is_periodic = false;
+ param->value = value;
+ param->min.f = 0;
+ param->max.f = 10000;
+ param->scale = CLAP_PARAM_LOG;
+ break;
+
+ case THYNS_ENV_PARAM_DECAY:
+ P(param->id, "%s%s", prefix, "decay");
+ P(param->name, "%s", "decay");
+ P(param->desc, "%s", "Envelope's decay in ms");
+ P(param->display, "%f ms", value.f);
+ param->type = CLAP_PARAM_FLOAT;
+ param->is_per_note = true;
+ param->is_used = true;
+ param->is_periodic = false;
+ param->value = value;
+ param->min.f = 0;
+ param->max.f = 10000;
+ param->scale = CLAP_PARAM_LOG;
+ break;
+
+ case THYNS_ENV_PARAM_SUSTAIN:
+ P(param->id, "%s%s", prefix, "sustain");
+ P(param->name, "%s", "sustain");
+ P(param->desc, "%s", "Envelope's sustain");
+ P(param->display, "%f", value.f);
+ param->type = CLAP_PARAM_FLOAT;
+ param->is_per_note = true;
+ param->is_used = true;
+ param->is_periodic = false;
+ param->value = value;
+ param->min.f = 0;
+ param->max.f = 1;
+ param->scale = CLAP_PARAM_LINEAR;
+ break;
+
+ case THYNS_ENV_PARAM_RELEASE:
+ P(param->id, "%s%s", prefix, "release");
+ P(param->name, "%s", "release");
+ P(param->desc, "%s", "Envelope's release in ms");
+ P(param->display, "%f ms", value.f);
+ param->type = CLAP_PARAM_FLOAT;
+ param->is_per_note = true;
+ param->is_used = true;
+ param->is_periodic = false;
+ param->value = value;
+ param->min.f = 0;
+ param->max.f = 10000;
+ param->scale = CLAP_PARAM_LOG;
+ break;
+ }
+#undef P
+}
+
+static inline void
+thyns_env_params_init(union clap_param_value *values)
+{
+ values[THYNS_ENV_PARAM_ATTACK].f = 100;
+ values[THYNS_ENV_PARAM_DECAY].f = 200;
+ values[THYNS_ENV_PARAM_SUSTAIN].f = 0.7;
+ values[THYNS_ENV_PARAM_RELEASE].f = 200;
+}
+
+static inline void
+thyns_env_init(struct thyns_env * restrict env, double sr)
{
env->state = THYNS_ENV_IDLE;
+ env->msr = 1000.0 / sr;
env->v = 0;
- env->ar = 0.0001;
- env->dr = 0.0001;
- env->s = 0.7;
- env->rr = 0.00001;
}
-static inline void thyns_env_restart(struct thyns_env * restrict env)
+static inline void
+thyns_env_restart(struct thyns_env * restrict env)
{
env->state = THYNS_ENV_ATTACK;
}
-static inline void thyns_env_release(struct thyns_env * restrict env)
+static inline void
+thyns_env_release(struct thyns_env * restrict env)
{
env->state = THYNS_ENV_RELEASE;
}
-static inline double thyns_env_step(struct thyns_env * restrict env)
+static inline double
+thyns_env_step(struct thyns_env * restrict env)
{
switch (env->state) {
case THYNS_ENV_ATTACK:
- env->v += env->ar;
+ env->v += env->values[THYNS_ENV_PARAM_ATTACK]->f * env->msr;
if (env->v >= 1) {
env->v = 1;
env->state = THYNS_ENV_DECAY;
}
break;
- case THYNS_ENV_DECAY:
- env->v -= env->dr;
- if (env->v <= env->s) {
- env->v = env->s;
+ case THYNS_ENV_DECAY: {
+ float s = env->values[THYNS_ENV_PARAM_SUSTAIN]->f;
+ env->v -= env->values[THYNS_ENV_PARAM_DECAY]->f * env->msr;
+ if (env->v <= s) {
+ env->v = s;
env->state = THYNS_ENV_SUSTAIN;
}
break;
+ }
case THYNS_ENV_SUSTAIN:
+ env->v = env->values[THYNS_ENV_PARAM_SUSTAIN]->f;
break;
case THYNS_ENV_RELEASE:
- env->v -= env->rr;
+ env->v -= env->values[THYNS_ENV_PARAM_RELEASE]->f * env->msr;
if (env->v <= 0) {
env->v = 0;
env->state = THYNS_ENV_IDLE;
diff --git a/examples/thyns/params.h b/examples/thyns/params.h
@@ -7,6 +7,8 @@ struct thyns_params
union clap_param_value osc1[THYNS_OSC_PARAM_COUNT];
union clap_param_value osc2[THYNS_OSC_PARAM_COUNT];
union clap_param_value filt[THYNS_FILT_PARAM_COUNT];
+ union clap_param_value amp_env[THYNS_ENV_PARAM_COUNT];
+ union clap_param_value filt_env[THYNS_ENV_PARAM_COUNT];
};
static void
@@ -15,6 +17,8 @@ thyns_params_init(struct thyns_params *params)
thyns_osc_params_init(params->osc1);
thyns_osc_params_init(params->osc2);
thyns_filt_params_init(params->filt);
+ thyns_env_params_init(params->amp_env);
+ thyns_env_params_init(params->filt_env);
}
#endif /* !PARAMS_H */
diff --git a/examples/thyns/voice.h b/examples/thyns/voice.h
@@ -53,11 +53,11 @@ thyns_voice_init(struct thyns_voice *voice, uint32_t sr)
thyns_filt_init(&voice->filt, sr);
voice->filt.cutoff = 4000;
voice->filt.resonance = 1.5;
- thyns_env_init(&voice->filt_env);
+ thyns_env_init(&voice->filt_env, sr);
voice->filt_env_depth = 0.2;
// amp
- thyns_env_init(&voice->amp_env);
+ thyns_env_init(&voice->amp_env, sr);
voice->amp = 0.2;
}
@@ -81,6 +81,16 @@ thyns_voice_params_init(struct thyns_voice *voice,
for (int i = 0; i < THYNS_FILT_PARAM_COUNT; ++i)
voice->filt.values[i] = params->values + off + i;
off += THYNS_FILT_PARAM_COUNT;
+
+ // amp_env
+ for (int i = 0; i < THYNS_ENV_PARAM_COUNT; ++i)
+ voice->amp_env.values[i] = params->values + off + i;
+ off += THYNS_ENV_PARAM_COUNT;
+
+ // filt_env
+ for (int i = 0; i < THYNS_ENV_PARAM_COUNT; ++i)
+ voice->filt_env.values[i] = params->values + off + i;
+ off += THYNS_ENV_PARAM_COUNT;
}
static inline void
@@ -104,6 +114,16 @@ thyns_voice_use_param(struct thyns_voice *voice,
voice->filt.values[index - i] = params->values + index;
}
i += THYNS_FILT_PARAM_COUNT;
+
+ if (index < i + THYNS_ENV_PARAM_COUNT) {
+ voice->amp_env.values[index - i] = params->values + index;
+ }
+ i += THYNS_ENV_PARAM_COUNT;
+
+ if (index < i + THYNS_ENV_PARAM_COUNT) {
+ voice->filt_env.values[index - i] = params->values + index;
+ }
+ i += THYNS_ENV_PARAM_COUNT;
}
static inline void