From ed290461e2ea7595bd36f7c097c7c5187cb43c46 Mon Sep 17 00:00:00 2001 From: slack Date: Fri, 12 Jun 2009 16:40:23 +0200 Subject: [PATCH] First filter test. Sounds weird :P --- play.c | 2 +- synth.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++------ synth.h | 17 ++++++++----- thesong.h | 8 +++---- 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/play.c b/play.c index 7f7a9db..d07f207 100644 --- a/play.c +++ b/play.c @@ -70,7 +70,7 @@ void play(void *s, uint8 *stream, int len) uint8 j = last_voice_used; last_voice_used = (last_voice_used + 1) % NUM_VOICES; - voices[j].pitch = 440.0f*detune(note-21,0); + voices[j].pitch = detune(440.0f,note-21,0); voices[j].pos = buf_start; voices[j].ins = &song->instrument_data[cur_trk->instrument]; voices[j].vol = 0.19921875f*vol; diff --git a/synth.c b/synth.c index d7774c7..77cfc82 100644 --- a/synth.c +++ b/synth.c @@ -2,11 +2,10 @@ #include #include -#define PI 3.1415926535897931 -float detune(int coarse, int fine) +float detune(float base, int coarse, int fine) { - return powf(2.0f, (coarse+(fine/100.0f))/12.0f); + return base*powf(2.0f, (coarse+(fine/100.0f))/12.0f); } uint8 synth(Voice *v, int len, float *mix_buf) @@ -21,15 +20,25 @@ uint8 synth(Voice *v, int len, float *mix_buf) int wave=0; while (1) { uint8 op = v->ins[iPC++]; + //printf("wave %d, op=%d\n", wave, op); switch (op) { + /* + case 0: // CONSTANT + { + float value = ((int8) v->ins[iPC++]/127.0); + for (int i=0; iwaves[wave][i] = value; + } + } + */ case 1: // SINE { - uint8 coarse = v->ins[iPC++]; - uint8 fine = v->ins[iPC++]; - float pitch = v->pitch*detune(coarse, fine); + int8 coarse = v->ins[iPC++]; + int8 fine = v->ins[iPC++]; + float pitch = detune(v->pitch, coarse, fine); for (int i=0; iwaves[wave][i] = 0.5f*sinf(pitch*2.0f*PI*(v->pos+i)/SAMPLE_RATE); + v->waves[wave][i] = 0.5f*sinf(pitch*TWOPI_samplerate*(v->pos+i)); } break; } @@ -47,7 +56,56 @@ uint8 synth(Voice *v, int len, float *mix_buf) } break; } + + case 4: // LPF + case 5: // HPF + { + // TODO: cutoff should be a wave + float cutoff = detune(440.0f, v->ins[iPC++], 0); + float r = 1.0f/(v->ins[iPC++]); + + for (int i=0; iwaves[wave-1][i]; + + // Compute filter coefficients + float c, c2,a1,a2,b1,b2; + + // Extraemos algunos calculos que son redundantes en HP y LP + float param_tan = PI_samplerate * cutoff; + if (op==4) { // Low-pass + c=1.0f / tanf(param_tan); + c2 = c*c; + + a1 = 1.0f / ( 1.0f + r * c + c2); + a2 = 2.0f * a1; + b1 = 2.0f * ( 1.0f - c2) * a1; + } else { // High-pass + c = tanf(-param_tan); + c2 = c*c; + + a1 = 1.0f / ( 1.0f + r * c + c2); + a2 = -2*a1; + b1 = 2.0f * ( c2 - 1.0f) * a1; + } + + b2 = ( 1.0f - r*c + c2) * a1; + + // data [0,1,2] = y(0), y(-1), y(-2) + // data [3,4] = x(-1), x(-2) + float *data = (float*)v->data[wave]; + data[0] = a1*sample + a2*data[3] + a1*data[4] - + b1*data[1] - b2*data[2]; + + data[4]=data[3]; + data[3]=sample; + data[2]=data[1]; + data[1]=data[0]; + + v->waves[wave][i] = data[0]; + } + break; + } default: goto end; } diff --git a/synth.h b/synth.h index 17660d7..32611be 100644 --- a/synth.h +++ b/synth.h @@ -6,6 +6,9 @@ #define BUFFER_SIZE 1024 #define SAMPLE_RATE 44100.0f #define MAX_OPS 30 +#define PI 3.1415926535897931f +#define PI_samplerate 7.10487365723e-05f +#define TWOPI_samplerate 0.000142097473145f /* An instrument is defined a FORTH-like stack of several operations between @@ -30,10 +33,10 @@ typedef struct int pos; // position in samples since the start uint8 active; // { 0 ==> inactive, (not 0) ==> active } - // data buffer to store, for example, previous inputs/outputs for filtering. - // 50 bytes should be enough for everyone. Anyway, voices will be created - // at bss, so they don't count for the file size :) - uint8 status[50]; + // data buffer to store, for example, previous inputs/outputs for + // filtering. It is as big as the wave buffer. Anyway, voices will be + // created at bss, so they don't count for the file size :) + uint8 data[MAX_OPS][BUFFER_SIZE*sizeof(float)]; // buffers generated by wave operations float waves[MAX_OPS][BUFFER_SIZE]; @@ -41,10 +44,12 @@ typedef struct #define SINE(detune_coarse, detune_fine) 1,detune_coarse,detune_fine #define SUM(a,b) 2,a,b -#define RING(a,b) 3,a,b +#define MUL(a,b) 3,a,b +#define LPF(cutoff, resonance) 4, cutoff,resonance +#define HPF(cutoff, resonance) 5, cutoff,resonance extern uint8 synth(Voice *v, int len, float *mix_buf); -extern float detune(int coarse, int fine); +extern float detune(float base, int coarse, int fine); diff --git a/thesong.h b/thesong.h index 77abaee..93bf344 100644 --- a/thesong.h +++ b/thesong.h @@ -8,11 +8,9 @@ Song thesong={ {{45,0,0,0,43,0,0,0,41,0,0,0,40,0,0,0}, 0}, }, // end tracks { // begin instrument data - SINE(0,0), - SINE(1,10), - //SINE(3,1), - RING(0,1), - RING(1,2), + SINE(0,0), + SINE(-70,0), // LFO + MUL(0,1), 255, }, // end instrument data { // begin playlist -- 2.34.1