adsr
This commit is contained in:
parent
d8640bed5a
commit
c52509a9d7
|
@ -43,8 +43,6 @@ void dsp_filter_addin(struct dsp_filter filter, struct dsp_filter *in)
|
|||
}
|
||||
|
||||
filter.in[filter.inputs++] = in;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
void am_mod(struct dsp_ammod *mod, short *c, int n)
|
||||
|
@ -52,10 +50,8 @@ void am_mod(struct dsp_ammod *mod, short *c, int n)
|
|||
dsp_run(mod->ina, mod->abuf, n);
|
||||
dsp_run(mod->inb, mod->bbuf, n);
|
||||
|
||||
for (int i = 0; i < n*2; i++) {
|
||||
for (int i = 0; i < n*CHANNELS; i++)
|
||||
c[i] = (mod->abuf[i]*mod->bbuf[i])>>15;
|
||||
//c[i] = mod->abuf[i];
|
||||
}
|
||||
}
|
||||
|
||||
static struct wav make_wav(float freq, int sr, int ch) {
|
||||
|
@ -334,11 +330,10 @@ struct dsp_filter lpf_make(int poles, float freq)
|
|||
|
||||
free(ccof);
|
||||
|
||||
printf("LPF coefficients are:\n");
|
||||
YughInfo("LPF coefficients are:", 0);
|
||||
|
||||
for (int i = 0; i < new->n; i++) {
|
||||
YughInfo("%f, %f\n", new->ccof[i], new->dcof[i]);
|
||||
}
|
||||
for (int i = 0; i < new->n; i++)
|
||||
YughInfo("%f, %f", new->ccof[i], new->dcof[i]);
|
||||
|
||||
struct dsp_filter lpf;
|
||||
lpf.data = new;
|
||||
|
@ -361,9 +356,8 @@ struct dsp_filter hpf_make(int poles, float freq)
|
|||
for (int i = 0; i < new->n; i++)
|
||||
new->ccof[i] = ccof[i] * sf;
|
||||
|
||||
for (int i = 0; i < new->n; i++) {
|
||||
printf("%f, %f\n", new->ccof[i], new->dcof[i]);
|
||||
}
|
||||
for (int i = 0; i < new->n; i++)
|
||||
YughInfo("%f, %f", new->ccof[i], new->dcof[i]);
|
||||
|
||||
free(ccof);
|
||||
|
||||
|
@ -450,3 +444,77 @@ void dsp_delay_filbuf(struct dsp_delay *delay, short *buf, int n)
|
|||
buf[i] = cache[i] + cbuf_shift(&delay->buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get decay constant for a given pole */
|
||||
/* Samples to decay 1 time constant is exp(-1/timeconstant) */
|
||||
double tau2pole(double tau)
|
||||
{
|
||||
return exp(-1/(tau*SAMPLERATE));
|
||||
}
|
||||
|
||||
void dsp_adsr_fillbuf(struct dsp_adsr *adsr, short *out, int n)
|
||||
{
|
||||
short val;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (adsr->time > adsr->rls) {
|
||||
// Totally decayed
|
||||
adsr->out = 0.f;
|
||||
|
||||
goto fin;
|
||||
}
|
||||
|
||||
if (adsr->time > adsr->sus) {
|
||||
// Release phase
|
||||
adsr->out = adsr->rls_t * adsr->out;
|
||||
|
||||
goto fin;
|
||||
}
|
||||
|
||||
if (adsr->time > adsr->dec) {
|
||||
// Sustain phase
|
||||
adsr->out = adsr->sus_pwr;
|
||||
|
||||
goto fin;
|
||||
}
|
||||
|
||||
if (adsr->time > adsr->atk) {
|
||||
// Decay phase
|
||||
adsr->out = (1 - adsr->dec_t) * adsr->sus_pwr + adsr->dec_t * adsr->out;
|
||||
|
||||
goto fin;
|
||||
}
|
||||
|
||||
// Attack phase
|
||||
adsr->out = (1-adsr->atk_t) + adsr->atk_t * adsr->out;
|
||||
|
||||
|
||||
|
||||
fin:
|
||||
|
||||
val = SHRT_MAX * adsr->out;
|
||||
out[i*CHANNELS] = out[i*CHANNELS+1] = val;
|
||||
adsr->time += (double)(1000.f / SAMPLERATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dsp_filter make_adsr(unsigned int atk, unsigned int dec, unsigned int sus, unsigned int rls)
|
||||
{
|
||||
struct dsp_adsr *adsr = calloc(sizeof(*adsr), 1);
|
||||
adsr->atk = atk;
|
||||
/* decay to 3 tau */
|
||||
adsr->atk_t = tau2pole(atk / 3000.f);
|
||||
|
||||
adsr->dec = dec + adsr->atk;
|
||||
adsr->dec_t = tau2pole(dec / 3000.f);
|
||||
|
||||
adsr->sus = sus + adsr->dec;
|
||||
adsr->sus_pwr = 0.8f;
|
||||
|
||||
adsr->rls = rls + adsr->sus;
|
||||
adsr->rls_t = tau2pole(rls / 3000.f);
|
||||
|
||||
return make_dsp(adsr, dsp_adsr_fillbuf);
|
||||
}
|
|
@ -18,7 +18,7 @@ struct dsp_filter {
|
|||
int inputs;
|
||||
struct dsp_filter *in[6];
|
||||
|
||||
short cache[CHANNELS*SAMPLERATE];
|
||||
short cache[CHANNELS*BUF_FRAMES];
|
||||
int dirty;
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,24 @@ struct dsp_filter lpf_make(int poles, float freq);
|
|||
struct dsp_filter bpf_make(int poles, float freq1, float freq2);
|
||||
struct dsp_filter npf_make(int poles, float freq1, float freq2);
|
||||
|
||||
/* atk, dec, sus, rls specify the time, in miliseconds, the phase begins */
|
||||
struct dsp_adsr {
|
||||
unsigned int atk;
|
||||
double atk_t;
|
||||
unsigned int dec;
|
||||
double dec_t;
|
||||
unsigned int sus;
|
||||
float sus_pwr; // Between 0 and 1
|
||||
unsigned int rls;
|
||||
double rls_t;
|
||||
|
||||
double time; /* Current time of the filter */
|
||||
float out;
|
||||
};
|
||||
|
||||
void dsp_adsr_fillbuf(struct dsp_adsr *adsr, short *out, int n);
|
||||
struct dsp_filter make_adsr(unsigned int atk, unsigned int dec, unsigned int sus, unsigned int rls);
|
||||
|
||||
struct dsp_delay {
|
||||
unsigned int ms_delay;
|
||||
struct circbuf buf;
|
||||
|
@ -54,18 +72,23 @@ void dsp_delay_filbuf(struct dsp_delay *delay, short *buf, int n);
|
|||
struct dsp_ammod {
|
||||
struct dsp_filter ina;
|
||||
struct dsp_filter inb;
|
||||
short abuf[BUF_FRAMES*2];
|
||||
short bbuf[BUF_FRAMES*2];
|
||||
short abuf[BUF_FRAMES*CHANNELS];
|
||||
short bbuf[BUF_FRAMES*CHANNELS];
|
||||
};
|
||||
|
||||
struct dsp_compressor {
|
||||
|
||||
};
|
||||
|
||||
struct dsp_filter dsp_make_compressor();
|
||||
void dsp_compressor_fillbuf(struct dsp_compressor *comp, short *out, int n);
|
||||
|
||||
struct dsp_limiter {
|
||||
|
||||
};
|
||||
|
||||
struct dsp_filter dsp_make_limiter();
|
||||
void dsp_limiter_fillbuf(struct dsp_limiter *lim, short *out, int n);
|
||||
|
||||
|
||||
struct phasor {
|
||||
|
|
|
@ -23,8 +23,8 @@ void mYughLog(int category, int priority, int line, const char *file, const char
|
|||
va_end(args);
|
||||
|
||||
char buffer[ERROR_BUFFER] = { '\0' };
|
||||
snprintf(buffer, ERROR_BUFFER, "LEVEL %d :: %s [ %s:%d ] %s\n",
|
||||
priority, msgbuffer, file, line, dt);
|
||||
snprintf(buffer, ERROR_BUFFER, "%s\n[ %s:%d ] %s\n",
|
||||
msgbuffer, file, line, dt);
|
||||
|
||||
printf("%s", buffer);
|
||||
fflush(stdout);
|
||||
|
|
|
@ -58,7 +58,7 @@ void dsp_midi_fillbuf(struct dsp_midi_song *song, void *out, int n)
|
|||
|
||||
void play_song(const char *midi, const char *sf)
|
||||
{
|
||||
gsong.midi = tml_load_filename("sounds/stickerbrush.mid");
|
||||
gsong.midi = tml_load_filename("sounds/littlewonder.mid");
|
||||
gsong.sf = tsf_load_filename("sounds/ff7.sf2");
|
||||
gsong.time = 0.f;
|
||||
|
||||
|
|
|
@ -164,8 +164,7 @@ void sound_init()
|
|||
struct dsp_filter am_filter;
|
||||
|
||||
|
||||
dspammod.ina = s600;
|
||||
dspammod.inb = s20;
|
||||
|
||||
|
||||
am_filter.filter = am_mod;
|
||||
am_filter.data = &dspammod;
|
||||
|
@ -176,7 +175,12 @@ void sound_init()
|
|||
del_filter.filter = dsp_delay_filbuf;
|
||||
del_filter.data = &dspdel;
|
||||
|
||||
//first_free_bus(s600);
|
||||
struct dsp_filter ad = make_adsr(50, 200, 500, 100);
|
||||
|
||||
dspammod.ina = s600;
|
||||
dspammod.inb = ad;
|
||||
|
||||
first_free_bus(am_filter);
|
||||
|
||||
struct dsp_filter wn;
|
||||
wn.filter = gen_pinknoise;
|
||||
|
|
Loading…
Reference in a new issue