Created
November 29, 2019 19:27
-
-
Save sideb0ard/90cd1661da4b89cc24f57c39d7b6e0d9 to your computer and use it in GitHub Desktop.
Envelopes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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