AtlatestRepositorysigil-dsp

sigil-dsp / tree / src / cks.h

1/*
2 * ks.h - Karplus-Strong plucked string primitive
3 *
4 * Feedback delay-line physical model. Delay length N = round(sr/freq).
5 * Each sample: averaging 2-tap lowpass in the feedback loop; per-trip
6 * 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_H
13#define SIGIL_DSP_KS_H
15#include "soundpipe.h"
17typedef 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;
31int sp_ks_create(sp_ks **p);
32int sp_ks_destroy(sp_ks **p);
33int 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. */
36int sp_ks_retune(sp_data *sp, sp_ks *p);
37/* Fill the delay line with noise * excite_gain. */
38int sp_ks_trigger(sp_data *sp, sp_ks *p);
39/* Per-sample step. `gate` used for rising-edge retrigger; pass 1.0 to
40 * disable retriggering (and call sp_ks_trigger manually). */
41int sp_ks_compute(sp_data *sp, sp_ks *p, SPFLOAT *gate, SPFLOAT *out);
43#endif