AtlatestRepositorysigil-dsp
1
/*2
* ks.h - Karplus-Strong plucked string primitive3
*4
* Feedback delay-line physical model. Delay length N = round(sr/freq).5
* Each sample: averaging 2-tap lowpass in the feedback loop; per-trip6
* gain set from the requested -60 dB decay time.7
*8
* Self-contained (no SoundPipe dependency beyond SPFLOAT and sp_data)9
* so motif can duplicate the struct in its render loop.10
*/12
#ifndef SIGIL_DSP_KS_H13
#define SIGIL_DSP_KS_H15
#include "soundpipe.h"17
typedef struct sp_ks {18
SPFLOAT freq; /* fundamental frequency (Hz) */19
SPFLOAT decay; /* -60 dB decay time (seconds) */20
SPFLOAT excite_gain; /* excitation amplitude (0..1) */21
SPFLOAT feedback; /* per-trip feedback coefficient (derived) */22
SPFLOAT *buf; /* delay line */23
int bufsize; /* current active length (samples) */24
int bufcap; /* allocated capacity */25
int bufpos; /* read/write cursor */26
SPFLOAT last; /* last output, for 2-tap averaging LP */27
int gate_prev; /* previous gate sample for edge detection */28
uint32_t rng; /* xorshift state for excitation noise */29
} sp_ks;31
int sp_ks_create(sp_ks **p);32
int sp_ks_destroy(sp_ks **p);33
int sp_ks_init(sp_data *sp, sp_ks *p, SPFLOAT freq, SPFLOAT decay,34
SPFLOAT excite_gain);35
/* Recompute feedback coefficient + active bufsize from freq/decay. */36
int sp_ks_retune(sp_data *sp, sp_ks *p);37
/* Fill the delay line with noise * excite_gain. */38
int sp_ks_trigger(sp_data *sp, sp_ks *p);39
/* Per-sample step. `gate` used for rising-edge retrigger; pass 1.0 to40
* disable retriggering (and call sp_ks_trigger manually). */41
int sp_ks_compute(sp_data *sp, sp_ks *p, SPFLOAT *gate, SPFLOAT *out);43
#endif