Skip to content

Instantly share code, notes, and snippets.

@sideb0ard
Created November 29, 2019 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sideb0ard/90cd1661da4b89cc24f57c39d7b6e0d9 to your computer and use it in GitHub Desktop.
Save sideb0ard/90cd1661da4b89cc24f57c39d7b6e0d9 to your computer and use it in GitHub Desktop.
Envelopes
#include <math.h>
#include <iostream>
#ifndef M_PI
#define M_PI (3.14159265358897932)
#endif
#define TWO_PI (2.0 * M_PI)
enum Envelope
{
Parabolic,
Trapezoidal,
Exponential,
Logarithmic,
};
constexpr Envelope mode = Envelope::Logarithmic;
constexpr float grain_amplitude = 1.0;
constexpr int duration_samples = 1024;
// Parbolic
float amplitude = 0.;
float rdur = 1.0 / duration_samples;
float rdur2 = rdur * rdur;
float slope = 4.0 * grain_amplitude * (rdur - rdur2);
float curve = -8.0 * grain_amplitude * rdur2;
// Trapezoidal
constexpr int attack_pct = 25;
constexpr int release_pct = 25;
constexpr float attack_size_in_samples = duration_samples / 100.0 * attack_pct;
constexpr int attack_to_sustain_idx = attack_size_in_samples;
constexpr float release_size_in_samples =
duration_samples / 100.0 * release_pct;
constexpr int sustain_to_release_idx =
duration_samples - release_size_in_samples;
float amplitude_increment = 0;
float previous_amplitude = 0;
// Raised Cosine Bell
double sy0 = 0;
double sy2 = 0;
double sy1 = 0;
double sb1 = 0;
// Exponential / Logarithmic
float exp_min = 0.1;
float exp_mul = 0;
float exp_now = 0;
float w = TWO_PI;
float ip = 0;
int main()
{
switch (mode)
{
case (Envelope::Parabolic):
break;
case (Envelope::Trapezoidal):
amplitude_increment = grain_amplitude / attack_size_in_samples;
break;
case (Envelope::Exponential):
exp_mul = pow((exp_min + 1) / exp_min, 1 / attack_size_in_samples);
exp_now = exp_min;
break;
case (Envelope::Logarithmic):
exp_mul = pow(exp_min / (exp_min + 1), 1 / attack_size_in_samples);
exp_now = exp_min + 1;
break;
}
for (int i = 0; i < duration_samples; ++i)
{
switch (mode)
{
case (Envelope::Parabolic):
std::cout << i << '\t' << amplitude << std::endl;
amplitude = amplitude + slope;
slope = slope + curve;
break;
case (Envelope::Trapezoidal):
std::cout << i << '\t' << amplitude << std::endl;
amplitude += previous_amplitude + amplitude_increment;
if (i == attack_to_sustain_idx)
amplitude_increment = 0;
else if (i == sustain_to_release_idx)
amplitude_increment =
-(grain_amplitude / release_size_in_samples);
break;
case (Envelope::Exponential):
std::cout << i << '\t' << amplitude << std::endl;
if (i < attack_to_sustain_idx || i > sustain_to_release_idx)
{
exp_now *= exp_mul;
amplitude = (exp_now - exp_min) * grain_amplitude;
}
else if (i == attack_to_sustain_idx)
{
amplitude = grain_amplitude;
}
else if (i == sustain_to_release_idx)
{
exp_now = 1 + exp_min;
exp_mul =
pow(exp_min / (1 + exp_min), 1 / release_size_in_samples);
}
break;
case (Envelope::Logarithmic):
std::cout << i << '\t' << amplitude << std::endl;
if (i < attack_to_sustain_idx || i > sustain_to_release_idx)
{
exp_now *= exp_mul;
amplitude = (1 - (exp_now - exp_min)) * grain_amplitude;
}
else if (i == attack_to_sustain_idx)
{
amplitude = grain_amplitude;
}
else if (i == sustain_to_release_idx)
{
exp_now = exp_min;
exp_mul =
pow((1 + exp_min) / exp_min, 1 / release_size_in_samples);
}
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment