Skip to content

Instantly share code, notes, and snippets.

@chbtoys
Created July 17, 2022 09:54
Show Gist options
  • Select an option

  • Save chbtoys/83ac32fe2517985efdd056b96ca1d280 to your computer and use it in GitHub Desktop.

Select an option

Save chbtoys/83ac32fe2517985efdd056b96ca1d280 to your computer and use it in GitHub Desktop.
audio programming - beginner level
#ifndef ADSR_H
#define ADSR_H
#include <vector>
#include <cmath>
namespace ADSR
{
class Envelope
{
public:
Envelope(float sampleRate,uint32_t duration)
{
sampleLength=sampleRate*duration;
A_l=0.2;A_r=0.9;D_l=0.1;D_r=0.7;S_l=0.4;S_r=D_r;R_l=0.3;R_r=0.0;
}
~Envelope() {}
void generateenvelope(std::vector<float>& env)
{
env.resize(sampleLength);
uint32_t height=600;
coords[0]=0;// x1
coords[1]=height;// y1
coords[2]=sampleLength*A_l;// x2
coords[3]=height-(height*A_r);// y2
coords[4]=sampleLength*(A_l+D_l);// x3
coords[5]=height-(height*D_r);// y3
coords[6]=sampleLength*(A_l+D_l+S_l);// x4
coords[7]=height-(height*S_r);// y4
coords[8]=sampleLength;// x5
coords[9]=height;// y5
bridge(env,coords[0],coords[1],coords[2],coords[3]);
bridge(env,coords[2],coords[3],coords[4],coords[5]);
bridge(env,coords[4],coords[5],coords[6],coords[7]);
bridge(env,coords[6],coords[7],coords[8],coords[9]);
}
void generateenvelope2(std::vector<float>& env)
{
env.resize(sampleLength);
uint32_t height=600;
coords[0]=0;// x1
coords[1]=height;// y1
coords[2]=sampleLength;// x5
coords[3]=0;// y5
bridge(env,coords[0],coords[1],coords[2],coords[3]);
}
void generateenvelope3(std::vector<float>& env)
{
env.resize(sampleLength);
uint32_t height=600;
coords[0]=0;// x1
coords[1]=0;// y1
coords[2]=sampleLength;// x5
coords[3]=height;// y5
bridge(env,coords[0],coords[1],coords[2],coords[3]);
}
void applyenvelope(std::vector<float>& v,std::vector<float>& env)
{
for (uint32_t i=0;i<env.size();++i)
{
v[i]=v[i]*env[i];
}
}
private:
void setpt(std::vector<float>& env, uint32_t x, uint32_t y)
{
if (((x >= 0) && (x < sampleLength)) && ((y >= 0) && (y < 600)))
{
env[x]=((600.0-float(y))/600.0);
}
}
void bridge(std::vector<float>& env, uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
{
int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
dx = x2 - x1; dy = y2 - y1;
if (dx == 0)
{
if (y2 < y1) std::swap(y1, y2);
for (y = y1; y <= y2; y++)
setpt(env, x1, y);
return;
}
if (dy == 0)
{
if (x2 < x1) std::swap(x1, x2);
for (x = x1; x <= x2; x++)
setpt(env, x, y1);
return;
}
dx1 = std::abs(dx); dy1 = std::abs(dy);
px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
if (dy1 <= dx1)
{
if (dx >= 0)
{
x = x1; y = y1; xe = x2;
}
else
{
x = x2; y = y2; xe = x1;
}
setpt(env, x, y);
for (i = 0; x<xe; i++)
{
x = x + 1;
if (px<0)
px = px + 2 * dy1;
else
{
if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
px = px + 2 * (dy1 - dx1);
}
setpt(env, x, y);
}
}
else
{
if (dy >= 0)
{
x = x1; y = y1; ye = y2;
}
else
{
x = x2; y = y2; ye = y1;
}
setpt(env, x, y);
for (i = 0; y<ye; i++)
{
y = y + 1;
if (py <= 0)
py = py + 2 * dx1;
else
{
if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
py = py + 2 * (dx1 - dy1);
}
setpt(env, x, y);
}
}
}
float A_l;
float A_r;
float D_l;
float D_r;
float S_l;
float S_r;
float R_l;
float R_r;
protected:
uint32_t sampleLength;
uint32_t coords[10];
};
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment