add lfo, pitch bend, key stack (for unison trills), filter lfo, filter EG intensity, 24db/oct filter
parent
7c84b45a03
commit
693332aa07
@ -1,10 +1,11 @@
|
||||
CFLAGS=$(shell pkg-config alsa jack --cflags)
|
||||
LDFLAGS=$(shell pkg-config alsa jack --libs)
|
||||
PKGS=alsa jack gtk+-3.0
|
||||
CFLAGS=$(shell pkg-config $(PKGS) --cflags)
|
||||
LDFLAGS=$(shell pkg-config $(PKGS) --libs)
|
||||
ifeq ($(DEBUG),true)
|
||||
CFLAGS+=-Wall -g
|
||||
endif
|
||||
|
||||
programs=vampisynth
|
||||
vampisynth_SRCS=synth.c envelope.c filter.c oscillator.c voice.c main.c
|
||||
vampisynth_SRCS=synth.c envelope.c filter.c oscillator.c voice.c sineosc.c main.c
|
||||
|
||||
include common.mk/common.mk
|
||||
|
@ -1,30 +1,72 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
void filter_init(struct Filter *filter, float cutoff, float resonance) {
|
||||
filter->v0 = filter->v1 = 0;
|
||||
memset(filter, 0, sizeof(struct Filter));
|
||||
filter->cutoff = cutoff;
|
||||
filter->resonance = resonance;
|
||||
}
|
||||
|
||||
void filter_set_cutoff(struct Filter *filter, float cutoff) {
|
||||
filter->cutoff = cutoff;
|
||||
if(filter->cutoff > 0.9) filter->cutoff = 0.9;
|
||||
else if(filter->cutoff < 0.0) filter->cutoff = 0.0;
|
||||
}
|
||||
|
||||
void filter_set_resonance(struct Filter *filter, float resonance) {
|
||||
filter->resonance = resonance;
|
||||
}
|
||||
|
||||
// http://www.musicdsp.org/showone.php?id=25
|
||||
// float filter_sample(struct Filter *filter, float input) {
|
||||
// float q = 1.0f - filter->cutoff;
|
||||
// float p = filter->cutoff + 0.8f * filter->cutoff * q;
|
||||
// float f = p + p - 1.0f;
|
||||
// q = filter->resonance * (1.0f + 0.5f * q * (1.0f - q + 5.6f * q * q));
|
||||
|
||||
// #define OVERSAMPLE 2
|
||||
// float output = 0;
|
||||
// for(int i = 0; i < OVERSAMPLE; i++) {
|
||||
// input -= q * filter->b4; //feedback
|
||||
// float t1 = filter->b1; filter->b1 = (input + filter->b0) * p - filter->b1 * f;
|
||||
// float t2 = filter->b2; filter->b2 = (filter->b1 + t1) * p - filter->b2 * f;
|
||||
// t1 = filter->b3; filter->b3 = (filter->b2 + t2) * p - filter->b3 * f;
|
||||
// filter->b4 = (filter->b3 + t1) * p - filter->b4 * f;
|
||||
// filter->b4 = filter->b4 - filter->b4 * filter->b4 * filter->b4 * 0.166667f; //clipping
|
||||
// filter->b0 = input;
|
||||
// output += filter->b4;
|
||||
// }
|
||||
// return output / (float)OVERSAMPLE;
|
||||
// }
|
||||
|
||||
// mad's filter code
|
||||
float filter_sample(struct Filter *filter, float input) {
|
||||
float c = pow(0.5, (128-filter->cutoff) / 16.0);
|
||||
float r = pow(0.5, (filter->resonance+24) / 16.0);
|
||||
if(++filter->last_calc >= 16) {
|
||||
filter->last_calc = 0;
|
||||
filter->cutoff_calc = pow (0.5, 8.5 - (filter->cutoff)*8 );
|
||||
filter->resonance_calc = filter->resonance;
|
||||
}
|
||||
float cutoff = filter->cutoff_calc;
|
||||
float resonance = filter->resonance_calc;
|
||||
|
||||
float outputs[2]; // oversample
|
||||
for(int i = 0; i < 2; i++) {
|
||||
filter->v0 = (1-r*c)*filter->v0 - (c)*filter->v1 + (c)*input;
|
||||
outputs[i] = filter->v1 = (1-r*c)*filter->v1 + (c)*filter->v0;
|
||||
#define OVERSAMPLE 2
|
||||
float output = 0;
|
||||
for(int i = 0; i < OVERSAMPLE; i++) {
|
||||
float in = filter->resonance_input;
|
||||
if(in > 1) in = 1;
|
||||
if(in < -1) in = -1;
|
||||
in = 1.5*in - 0.5*in*in*in;
|
||||
in = input - in;
|
||||
filter->stage_1 += (in - filter->stage_1) * cutoff;
|
||||
filter->stage_2 += (filter->stage_1 - filter->stage_2) * cutoff;
|
||||
filter->stage_3 += (filter->stage_2 - filter->stage_3) * cutoff;
|
||||
filter->stage_4 += (filter->stage_3 - filter->stage_4) * cutoff;
|
||||
output += filter->stage_4;
|
||||
filter->resonance_input = output * resonance;
|
||||
}
|
||||
|
||||
return (outputs[0] + outputs[1]) / 2;
|
||||
return output / OVERSAMPLE;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "sineosc.h"
|
||||
#include "config.h"
|
||||
|
||||
void sine_osc_init(struct SineOsc *osc) {
|
||||
osc->s0 = 1.0;
|
||||
osc->s1 = 0.0;
|
||||
}
|
||||
|
||||
void sine_osc_set_freq(struct SineOsc *osc, float freq) {
|
||||
osc->a = 2.0 * sinf(M_PI * freq / SAMPLE_RATE);
|
||||
}
|
||||
|
||||
float sine_osc_sample(struct SineOsc *osc) {
|
||||
osc->s0 = osc->s0 - osc->a * osc->s1;
|
||||
osc->s1 = osc->s1 + osc->a * osc->s0;
|
||||
return osc->s0;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#ifndef SINEOSC_H_
|
||||
#define SINEOSC_H_
|
||||
|
||||
struct SineOsc {
|
||||
float a, s0, s1;
|
||||
};
|
||||
|
||||
void sine_osc_init(struct SineOsc *osc);
|
||||
void sine_osc_set_freq(struct SineOsc *osc, float freq);
|
||||
float sine_osc_sample(struct SineOsc *osc);
|
||||
|
||||
#endif /* SINEOSC_H_ */
|
Loading…
Reference in new issue