Commitd71f7cd5Recorded22 Sep 2026Repositorysigil-dsp

sp_zitarev_compute_block: n samples of the reverb with the coefficients computed once (0.3.4)

Message

sp_zitarev_compute hands Faust's computezitarev a count of 1, so its control-rate coefficients (a dozen powf/expf/cosf) run per sample: 16 % of a motif render on 2026-09-22, silence or not. The block call computes them once per block; the samples are the same while the parameters hold, a parameter set mid-block lands at the next block. Declared in zitarev.h and soundpipe.h; no generated code touched.

Changed
 RELEASES.md                        |  9 +++++++++
 package.sgl                        |  2 +-
 vendor/soundpipe/h/soundpipe.h     |  1 +
 vendor/soundpipe/h/zitarev.h       |  1 +
 vendor/soundpipe/modules/zitarev.c | 16 ++++++++++++++++
 5 files changed, 28 insertions(+), 1 deletion(-)
Diff
RELEASES.mdmodified
@@ -1,5 +1,14 @@
1
# sigil-dsp Releases
2
+3
## v0.3.4 — 2026-09-22
+4
+5
One addition: `sp_zitarev_compute_block(sp, p, in1, in2, out1, out2, n)` renders n samples of the zitarev reverb in one call. `sp_zitarev_compute` hands the Faust-generated `computezitarev` a count of 1, so its ~40 control-rate coefficients — a dozen `powf`/`expf`/`cosf` among them — are recomputed for every sample; a profile of motif's render on 2026-09-22 put 16 % of the whole render in them, silence or not. The block call computes them once per block. The samples are the ones n single calls give while the parameters hold; a parameter set mid-block takes effect at the next block. No generated code is touched; the header declares the new entry beside `sp_zitarev_compute`. No Scheme binding yet: motif calls it from C.
+6
+7
## Upgrade notes
+8
+9
Nothing changes for existing callers.
+10
+11
12
## v0.3.3 — 2026-09-21
13
14
One fix: `(dsp-init sr)` sets the shared context's sample rate on every call that gives one, not only the first. The nodes cache the rate when they are built (soundpipe's oscillators and filters at init, the fm4 voice, the chorus, the comp), so a program that renders at more than one rate in its life — motif's player opened at 48000 and then at 24000 when a slow phone asks for a cheaper render (Crash The Stack's live soundtrack) — built every later graph with the first rate's increments and played it at the new rate: a 24000 render sounded an octave down. Now a `(dsp-init sr)` before a graph is built gives that graph `sr`; graphs already built keep theirs. A call without a rate still changes nothing once the context exists. The test entry checks a 440 Hz fm4 voice built after `(dsp-init 24000)` and one after `(dsp-init 48000)` both cross zero 880 times in a second.
package.sglmodified
@@ -5,7 +5,7 @@
5
6
(package
7
name: "sigil-dsp"
−8
version: "0.3.3"
+8
version: "0.3.4"
9
sigil: "0.20"
10
description: "DSP primitives for Sigil (SoundPipe bindings)"
11
url: "https://codeberg.org/sigil/sigil-dsp"
vendor/soundpipe/h/soundpipe.hmodified
@@ -614,4 +614,5 @@ int sp_zitarev_create(sp_zitarev **p);
614
int sp_zitarev_destroy(sp_zitarev **p);
615
int sp_zitarev_init(sp_data *sp, sp_zitarev *p);
616
int sp_zitarev_compute(sp_data *sp, sp_zitarev *p, SPFLOAT *in1, SPFLOAT *in2, SPFLOAT *out1, SPFLOAT *out2);
+617
int sp_zitarev_compute_block(sp_data *sp, sp_zitarev *p, SPFLOAT *in1, SPFLOAT *in2, SPFLOAT *out1, SPFLOAT *out2, int n);
618
#endif
vendor/soundpipe/h/zitarev.hmodified
@@ -19,3 +19,4 @@ int sp_zitarev_create(sp_zitarev **p);
19
int sp_zitarev_destroy(sp_zitarev **p);
20
int sp_zitarev_init(sp_data *sp, sp_zitarev *p);
21
int sp_zitarev_compute(sp_data *sp, sp_zitarev *p, SPFLOAT *in1, SPFLOAT *in2, SPFLOAT *out1, SPFLOAT *out2);
+22
int sp_zitarev_compute_block(sp_data *sp, sp_zitarev *p, SPFLOAT *in1, SPFLOAT *in2, SPFLOAT *out1, SPFLOAT *out2, int n);
vendor/soundpipe/modules/zitarev.cmodified
@@ -1060,3 +1060,19 @@ int sp_zitarev_compute(sp_data *sp, sp_zitarev *p, SPFLOAT *in1, SPFLOAT *in2, S
1060
computezitarev(dsp, 1, faust_in, faust_out);
1061
return SP_OK;
1062
}
+1063
+1064
/* n samples at once: the Faust compute with count = n runs its ~40
+1065
* coefficient computations (a dozen powf/expf/cosf) once for the block
+1066
* instead of once per sample (sp_zitarev_compute's count = 1 spent 16 %
+1067
* of a motif render in them, 2026-09-22). The output is the same
+1068
* samples as n calls of sp_zitarev_compute while the parameters hold;
+1069
* a parameter set mid-block takes effect at the next block. */
+1070
int sp_zitarev_compute_block(sp_data *sp, sp_zitarev *p, SPFLOAT *in1, SPFLOAT *in2, SPFLOAT *out1, SPFLOAT *out2, int n)
+1071
{
+1072
(void)sp;
+1073
zitarev *dsp = p->faust;
+1074
SPFLOAT *faust_out[] = {out1, out2};
+1075
SPFLOAT *faust_in[] = {in1, in2};
+1076
if (n > 0) computezitarev(dsp, n, faust_in, faust_out);
+1077
return SP_OK;
+1078
}