[Csnd] linseg

Is this not a trivial fencepost issue? The target for the result is
the value at the end of the k-cycle, but the printing is from the
start of the cycle. Just a thought.

==John ffitch

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        Issues · csound/csound · GitHub
Discussions of bugs and features can be posted here

That is what it is.

linsegr gets to (nearly) zero at the next kcycle, as the increment is applied after the envelope has been output. This is the relevant incr code

p->curinc = (segp->nxtpt - p->curval) / segp->cnt;

If segp->cnt is reduced by 1, then it gets very close to 0.

If the release time is longer, then the result will also be closer to 0.

As far as I can see that’s how it always worked.

I have tried the change below which seems to work as desired. I am not sure if it is the best way to do it, so appreciate any feedback - it took me a while to work out the flow, and it seems the return by the comment 'seg Z now done all' is/was never actually reached.
Basically if releasing, segp->cnt is reduced by 1, then if in last segment and curcnt == 1 it sets rslt and segsrem to 0 to ensure the final value is as desired.

@@ -414,13 +414,19 @@ int32_t klnsegr(CSOUND *csound, LINSEG *p)
      *p->rslt = p->curval; /* put the cur value */
      if (p->segsrem) { /* done if no more segs */
        SEG *segp;
- if (p->h.insdshead->relesing && p->segsrem > 1) {
- while (p->segsrem > 1) { /* reles flag new: */
- segp = ++p->cursegp; /* go to last segment */
- p->segsrem--;
- } /* get univ relestim */
- segp->cnt = p->xtra>= 0 ? p->xtra : p->h.insdshead->xtratim;
- goto newi; /* and set new curinc */
+ if (p->h.insdshead->relesing) {
+ if (p->segsrem > 1) {
+ while (p->segsrem > 1) { /* reles flag new: */
+ segp = ++p->cursegp; /* go to last segment */
+ p->segsrem--;
+ } /* get univ relestim */
+ segp->cnt = (p->xtra>= 0 ? p->xtra : p->h.insdshead->xtratim) - 1;
+ goto newi; /* and set new curinc */
+ } else if (p->segsrem == 1 && p->curcnt == 1) { /* set final value */
+ *p->rslt = p->cursegp->nxtpt;
+ p->segsrem = 0;
+ return OK;
+ }

Thanks, I have been working on a fix and have committed it to csound6, but there is a few things I have to check before I finish. The main issue appears to be a discrepancy by 1 kcycle between normal performance and xtratim. I am checking the origin of this before I complete the job and mainline it to develop.

Prof. Victor Lazzarini
Maynooth University
Ireland