1 /*
2 gens1.c:
3
4 Copyright (C) 1991 Barry Vercoe, John ffitch
5
6 This file is part of Csound.
7
8 The Csound Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 Csound is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with Csound; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301 USA
22 */
23
24 #include "csoundCore.h" /* UGENS1.C */
25 #include "ugens1.h"
26 #include <math.h>
27
28 #define FHUND (FL(100.0))
29
30
linset(CSOUND * csound,LINE * p)31 int32_t linset(CSOUND *csound, LINE *p)
32 {
33 double dur;
34 if (LIKELY((dur = *p->idur) > FL(0.0))) {
35 p->incr = (*p->ib - *p->ia) / dur * csound->onedsr;
36 p->kincr = p->incr*CS_KSMPS;
37 p->val = *p->ia;
38 }
39 return OK;
40 }
41
kline(CSOUND * csound,LINE * p)42 int32_t kline(CSOUND *csound, LINE *p)
43 {
44 IGN(csound);
45 *p->xr = p->val; /* rslt = val */
46 p->val += p->kincr; /* val += incr */
47 return OK;
48 }
49
aline(CSOUND * csound,LINE * p)50 int32_t aline(CSOUND *csound, LINE *p)
51 {
52 IGN(csound);
53 double val, inc;
54 MYFLT *ar;
55 uint32_t offset = p->h.insdshead->ksmps_offset;
56 uint32_t early = p->h.insdshead->ksmps_no_end;
57 uint32_t n, nsmps = CS_KSMPS;
58 ar = p->xr;
59 val = p->val;
60 inc = p->incr;
61
62 if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
63 if (UNLIKELY(early)) {
64 nsmps -= early;
65 memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
66 }
67
68 //p->val += inc;/* nxtval = val + inc */
69 //inc /= (nsmps - offset);
70 for (n=offset; n<nsmps; n++) {
71 ar[n] = (MYFLT)val;
72 val += inc; /* interp val for ksmps */
73 }
74 p->val = val;
75 return OK;
76 }
77
expset(CSOUND * csound,EXPON * p)78 int32_t expset(CSOUND *csound, EXPON *p)
79 {
80 double dur, a, b;
81 //printf("kr = %f , 1/kr = %f \n",CS_EKR, CS_ONEDKR);
82 if (LIKELY((dur = *p->idur) > FL(0.0) )) {
83 a = *p->ia;
84 b = *p->ib;
85 if (LIKELY((a * b) > FL(0.0))) {
86 p->mlt = POWER(b/a, csound->onedsr/dur);
87 p->kmlt = POWER(b/a, CS_ONEDKR/dur);
88 p->val = a;
89 }
90 else if (a == FL(0.0))
91 return csound->InitError(csound, Str("arg1 is zero"));
92 else if (b == FL(0.0))
93 return csound->InitError(csound, Str("arg2 is zero"));
94 else return csound->InitError(csound, Str("unlike signs"));
95 }
96 return OK;
97 }
98
kexpon(CSOUND * csound,EXPON * p)99 int32_t kexpon(CSOUND *csound, EXPON *p)
100 {
101 IGN(csound);
102 *p->xr = p->val; /* rslt = val */
103 p->val *= p->kmlt; /* val *= mlt */
104 return OK;
105 }
106
expon(CSOUND * csound,EXPON * p)107 int32_t expon(CSOUND *csound, EXPON *p)
108 {
109 IGN(csound);
110 double val, mlt;//, inc;//, nxtval;
111 MYFLT *ar;
112 uint32_t offset = p->h.insdshead->ksmps_offset;
113 uint32_t early = p->h.insdshead->ksmps_no_end;
114 uint32_t n, nsmps = CS_KSMPS;
115
116 val = p->val;
117 mlt = p->mlt;
118 // nxtval = val * mlt;
119 ar = p->xr;
120 if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
121 if (UNLIKELY(early)) {
122 nsmps -= early;
123 memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
124 }
125 //inc = nxtval - val;
126 //inc /= (nsmps - offset); /* increment per sample */
127 for (n=offset; n<nsmps; n++) {
128 ar[n] = (MYFLT)val;
129 val *= mlt; /* interp val for ksmps */
130 }
131 // p->val = nxtval; /* store next value */
132 p->val = val;
133 return OK;
134 }
135
lsgset(CSOUND * csound,LINSEG * p)136 int32_t lsgset(CSOUND *csound, LINSEG *p)
137 {
138 SEG *segp;
139 int32_t nsegs;
140 MYFLT **argp;
141 double val;
142
143 if (UNLIKELY(!(p->INCOUNT & 1))) {
144 return csound->InitError(csound, Str("incomplete number of input arguments"));
145 }
146
147 /* count segs & alloc if nec */
148 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
149 /* VL: 29.05.17 allocating one extra empty segment
150 so that the breakpoint version of this opcode
151 can work properly without a fencepost bug */
152 if (UNLIKELY((p->cursegp = (SEG *) p->auxch.auxp) == NULL ||
153 (nsegs+1)*sizeof(SEG) < (uint32_t)p->auxch.size)) {
154 csound->AuxAlloc(csound, (int32_t)(nsegs+1)*sizeof(SEG), &p->auxch);
155 p->cursegp = (SEG *) p->auxch.auxp;
156 segp = p->cursegp + 1; /* point to first seg */
157 p->cursegp->cnt = 0; /* zero duration of segment 0 */
158 segp[nsegs-1].cnt = MAXPOS; /* set endcount for safety */
159 } else segp = p->cursegp + 1; /* point to first seg */
160 argp = p->argums;
161 val = (double)**argp++;
162 if (UNLIKELY(**argp <= FL(0.0))) return OK; /* if idur1 <= 0, skip init */
163 p->curval = val;
164 p->curcnt = 0;
165 /* VL: 29.05.17 this was causing a fencepost error in
166 the breakpoint version (linsegb) */
167 //p->cursegp = segp - 1; /* else setup null seg0 */
168 p->segsrem = nsegs + 1;
169 do { /* init each seg .. */
170 double dur = (double)**argp++;
171 segp->nxtpt = (double)**argp++;
172 if (UNLIKELY((segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5))) < 0))
173 segp->cnt = 0;
174 if (UNLIKELY((segp->acnt = (int32_t)(dur * csound->esr + FL(0.5))) < 0))
175 segp->acnt = 0;
176 segp++;
177 } while (--nsegs);
178 p->xtra = -1;
179
180 return OK;
181
182 }
183
lsgset_bkpt(CSOUND * csound,LINSEG * p)184 int32_t lsgset_bkpt(CSOUND *csound, LINSEG *p)
185 {
186 int32_t cnt = 0, bkpt = 0;
187 int32_t nsegs;
188 int32_t n;
189 SEG *segp;
190 n = lsgset(csound, p);
191 if (UNLIKELY(n!=0)) return n;
192 nsegs = p->segsrem;
193 segp = p->cursegp;
194 do {
195 if (UNLIKELY(cnt > segp->cnt))
196 return csound->InitError(csound, Str("Breakpoint %d not valid"), bkpt);
197 segp->cnt -= cnt;
198 cnt += segp->cnt;
199 segp++;
200 bkpt++;
201 } while (--nsegs);
202 return OK;
203 }
204
205
klnseg(CSOUND * csound,LINSEG * p)206 int32_t klnseg(CSOUND *csound, LINSEG *p)
207 {
208 IGN(csound);
209 *p->rslt = p->curval; /* put the cur value */
210 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1; /* RWD fix */
211 if (UNLIKELY(p->segsrem)) { /* done if no more segs */
212 if (--p->curcnt <= 0) { /* if done cur segment */
213 SEG *segp = p->cursegp;
214 if (UNLIKELY(!(--p->segsrem))) {
215 p->curval = segp->nxtpt; /* advance the cur val */
216 return OK;
217 }
218 p->cursegp = ++segp; /* find the next */
219 if (UNLIKELY(!(p->curcnt = segp->cnt))) { /* nonlen = discontin */
220 p->curval = segp->nxtpt; /* poslen = new slope */
221 /* p->curval += p->curinc; ??????? */
222 return OK;
223 }
224 else {
225 p->curinc = (segp->nxtpt - p->curval) / segp->cnt;
226 p->curval += p->curinc;
227 return OK;
228 }
229 }
230 if (p->curcnt<10) /* This is a fiddle to get rounding right! */
231 p->curinc = (p->cursegp->nxtpt - p->curval) / p->curcnt; /* recalc */
232 p->curval += p->curinc; /* advance the cur val */
233 }
234 return OK;
235 err1:
236 return csound->InitError(csound, Str("linseg not initialised (krate)\n"));
237 }
238
linseg(CSOUND * csound,LINSEG * p)239 int32_t linseg(CSOUND *csound, LINSEG *p)
240 {
241 double val, ainc;
242 MYFLT *rs = p->rslt;
243 uint32_t offset = p->h.insdshead->ksmps_offset;
244 uint32_t early = p->h.insdshead->ksmps_no_end;
245 uint32_t n, nsmps = CS_KSMPS;
246
247 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1; /* RWD fix */
248
249 val = p->curval; /* sav the cur value */
250 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
251 if (UNLIKELY(early)) {
252 nsmps -= early;
253 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
254 }
255
256 for (n=offset; n<nsmps; n++) {
257 if (LIKELY(p->segsrem)) { /* if no more segs putk */
258 if (--p->curcnt <= 0) { /* if done cur segment */
259 SEG *segp = p->cursegp;
260 chk1:
261 if (UNLIKELY(!--p->segsrem)) { /* if none left */
262 val = p->curval = segp->nxtpt;
263 goto putk; /* put endval */
264 }
265 p->cursegp = ++segp; /* else find the next */
266 //printf("newseg: nxtpt=%f acnt=%d\n", segp->nxtpt, segp->acnt);
267 if (UNLIKELY(!(p->curcnt = segp->acnt))) {
268 val = p->curval = segp->nxtpt; /* nonlen = discontin */
269 goto chk1;
270 } /* poslen = new slope */
271 p->curainc = (segp->nxtpt - val) / segp->acnt;
272 // p->curainc = p->curinc * CS_ONEDKSMPS;
273 }
274 // p->curval = val + p->curinc; /* advance the cur val */
275 if (UNLIKELY((ainc = p->curainc) == FL(0.0)))
276 goto putk;
277 rs[n] = (MYFLT)val;
278 val += ainc;
279 }
280 else { /* no more segments */
281 putk:
282 rs[n] = (MYFLT)val;
283 }
284 }
285 p->curval = val;
286 return OK;
287 err1:
288
289 return csound->PerfError(csound, &(p->h),
290 Str("linseg: not initialised (arate)\n"));
291 }
292
293 /* **** ADSR is just a construction and use of linseg */
294
295 #define MAXSEGDUR (INT_MAX/CS_ESR)
296
adsrset1(CSOUND * csound,LINSEG * p,int32_t midip)297 static int32_t adsrset1(CSOUND *csound, LINSEG *p, int32_t midip)
298 {
299 SEG *segp;
300 int32_t nsegs;
301 MYFLT **argp = p->argums;
302 double dur;
303 MYFLT len = csound->curip->p3.value;
304 MYFLT release = *argp[3];
305 int32_t relestim;
306
307 //printf("len = %f\n", len);
308 if (UNLIKELY(len<=FL(0.0)))
309 len = (int32_t) MAXSEGDUR;// FL(10000.0); /* MIDI case set int32_t */
310 nsegs = 6; /* DADSR */
311 if ((segp = (SEG *) p->auxch.auxp) == NULL ||
312 nsegs*sizeof(SEG) < (uint32_t)p->auxch.size) {
313 csoundAuxAlloc(csound, (size_t) nsegs * sizeof(SEG), &p->auxch);
314 p->cursegp = segp = (SEG *) p->auxch.auxp;
315 segp[nsegs-1].cnt = MAXPOS; /* set endcount for safety */
316 }
317 else if (**argp > FL(0.0))
318 memset(p->auxch.auxp, 0, (size_t)nsegs*sizeof(SEG));
319 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
320 p->curval = 0.0;
321 p->curcnt = 0;
322 p->cursegp = segp - 1; /* else setup null seg0 */
323 p->segsrem = nsegs;
324 //printf("args: %f %f %f %f %f\n",
325 // *argp[0], *argp[1], *argp[2], *argp[3],* argp[4]);
326 /* Delay */
327 dur = (double)*argp[4];
328 segp->nxtpt = FL(0.0);
329 segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5));
330 //printf("delay: dur=%f cnt=%d\n", dur, segp->cnt);
331 segp++;
332 /* Attack */
333 dur = (double)*argp[0];
334 segp->nxtpt = FL(1.0);
335 segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5));
336 if (UNLIKELY((segp->acnt = (int32_t)(dur * csound->esr + FL(0.5))) < 0))
337 segp->acnt = 0;
338 //printf("attack: dur=%f cnt=%d acnt=%d nxt=%f\n",
339 // dur, segp->cnt, segp->acnt, segp->nxtpt);
340 segp++;
341 /* Decay */
342 dur = *argp[1];
343 segp->nxtpt = *argp[2];
344 segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5));
345 if (UNLIKELY((segp->acnt = (int32_t)(dur * csound->esr + FL(0.5))) < 0))
346 segp->acnt = 0;
347 //printf("decay: dur=%f cnt=%d acnt=%d nxt=%f\n",
348 // dur, segp->cnt, segp->acnt, segp->nxtpt);
349 segp++;
350 /* Sustain */
351 /* Should use p3 from score, but how.... */
352 dur = len - *argp[4] - *argp[0] - *argp[1] - *argp[3];
353 if (!midip && dur <0.0)
354 csound->Warning(csound, Str("length of ADSR note too short"));
355 segp->nxtpt = *argp[2];
356 segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5));
357 if (UNLIKELY((segp->acnt = (int32_t)(dur * csound->esr + FL(0.5))) < 0))
358 segp->acnt = 0;
359 //printf("sustain: dur=%f cnt=%d acnt=%d nxt=%f\n",
360 // dur, segp->cnt, segp->acnt, segp->nxtpt);
361 segp++;
362 /* Release */
363 dur = *argp[3];
364 segp->nxtpt = FL(0.0);
365 segp->cnt = (int32_t)(release * CS_EKR + FL(0.5));
366 if (UNLIKELY((segp->acnt = (int32_t)(release * csound->esr + FL(0.5))) < 0))
367 segp->acnt = 0;
368 //printf("release: dur=%f cnt=%d acnt=%d nxt=%f\n",
369 // dur, segp->cnt, segp->acnt, segp->nxtpt);
370 if (midip) {
371 relestim = (p->cursegp + p->segsrem - 1)->cnt;
372 p->xtra = relestim;
373 /* VL 4-1-2011 was (int32_t)(*argp[5] * CS_EKR + FL(0.5));
374 this seems to fix it */
375 if (relestim > p->h.insdshead->xtratim)
376 p->h.insdshead->xtratim = (int32_t)relestim;
377 }
378 else
379 p->xtra = 0L;
380 return OK;
381 }
382
adsrset(CSOUND * csound,LINSEG * p)383 int32_t adsrset(CSOUND *csound, LINSEG *p)
384 {
385 return adsrset1(csound, p, 0);
386 }
387
madsrset(CSOUND * csound,LINSEG * p)388 int32_t madsrset(CSOUND *csound, LINSEG *p)
389 {
390 return adsrset1(csound, p, 1);
391 }
392
393 /* End of ADSR */
394
lsgrset(CSOUND * csound,LINSEG * p)395 int32_t lsgrset(CSOUND *csound, LINSEG *p)
396 {
397 int32_t relestim;
398 if (lsgset(csound,p) == OK){
399 relestim = (p->cursegp + p->segsrem - 1)->cnt;
400 p->xtra = relestim;
401 /* VL 4-1-2011 was -1, making all linsegr
402 releases in an instr => xtratim
403 set to relestim seems to fix this */
404 if (relestim > p->h.insdshead->xtratim)
405 p->h.insdshead->xtratim = (int32_t)relestim;
406 return OK;
407 }
408 else return NOTOK;
409 }
410
klnsegr(CSOUND * csound,LINSEG * p)411 int32_t klnsegr(CSOUND *csound, LINSEG *p)
412 {
413 IGN(csound);
414 *p->rslt = p->curval; /* put the cur value */
415 if (p->segsrem) { /* done if no more segs */
416 SEG *segp;
417 if (p->h.insdshead->relesing && p->segsrem > 1) {
418 while (p->segsrem > 1) { /* reles flag new: */
419 segp = ++p->cursegp; /* go to last segment */
420 p->segsrem--;
421 } /* get univ relestim */
422 segp->cnt = p->xtra>= 0 ? p->xtra : p->h.insdshead->xtratim;
423 goto newi; /* and set new curinc */
424 }
425 if (--p->curcnt <= 0) { /* if done cur seg */
426 chk2:
427 if (p->segsrem == 2) return OK; /* seg Y rpts lastval */
428 if (!(--p->segsrem)) return OK; /* seg Z now done all */
429 segp = ++p->cursegp; /* else find nextseg */
430 newi:
431 if (!(p->curcnt = segp->cnt)) { /* nonlen = discontin */
432 p->curval = segp->nxtpt; /* reload & rechk */
433 goto chk2;
434 } /* else get new slope */
435 p->curinc = (segp->nxtpt - p->curval) / segp->cnt;
436 }
437 p->curval += p->curinc; /* advance the cur val */
438 }
439 return OK;
440 }
441
linsegr(CSOUND * csound,LINSEG * p)442 int32_t linsegr(CSOUND *csound, LINSEG *p)
443 {
444 IGN(csound);
445 MYFLT val, ainc, *rs = p->rslt;
446 uint32_t offset = p->h.insdshead->ksmps_offset;
447 uint32_t early = p->h.insdshead->ksmps_no_end;
448 uint32_t n, nsmps = CS_KSMPS;
449
450 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
451 if (UNLIKELY(early)) {
452 nsmps -= early;
453 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
454 }
455 val = p->curval; /* sav the cur value */
456 for (n=offset; n<nsmps; n++) {
457 if (LIKELY(p->segsrem)) { /* if no more segs putk */
458 SEG *segp;
459 if (p->h.insdshead->relesing && p->segsrem > 1) {
460 while (p->segsrem > 1) { /* release flag new: */
461 segp = ++p->cursegp; /* go to last segment */
462 p->segsrem--;
463 } /* get univ relestim */
464 segp->acnt = (p->xtra >=0 ? p->xtra : p->h.insdshead->xtratim)*CS_KSMPS;
465 goto newi; /* and set new curinc */
466 }
467 if (--p->curcnt <= 0) { /* if done cur seg */
468 chk2:
469 if (p->segsrem == 2) goto putk; /* seg Y rpts lastval */
470 if (!(--p->segsrem)) goto putk; /* seg Z now done all */
471 segp = ++p->cursegp; /* else find nextseg */
472 newi:
473 if (!(p->curcnt = segp->acnt)) { /* nonlen = discontin */
474 val = p->curval = segp->nxtpt; /* reload & rechk */
475 goto chk2;
476 } /* else get new slope */
477 p->curainc = (segp->nxtpt - val) / segp->acnt;
478 // p->curainc = p->curinc * CS_ONEDKSMPS;
479 }
480 //p->curval = val + p->curainc*CS_KSMPS; /* advance the cur val */
481 if ((ainc = p->curainc) == FL(0.0))
482 goto putk;
483
484 rs[n] = val;
485 val += ainc;
486 }
487 else {
488 putk:
489 rs[n] = val;
490 }
491 }
492 p->curval = val;
493 return OK;
494 }
495
xsgset(CSOUND * csound,EXXPSEG * p)496 int32_t xsgset(CSOUND *csound, EXXPSEG *p)
497 {
498 XSEG *segp;
499 int32_t nsegs;
500 MYFLT d, **argp, val, dur, nxtval;
501 int32_t n=0;
502
503 if (!(p->INCOUNT & 1)) {
504 return csound->InitError(csound, Str("incomplete number of input arguments"));
505 }
506
507 /* count segs & alloc if nec */
508 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
509 if ((segp = (XSEG *) p->auxch.auxp) == NULL ||
510 nsegs*sizeof(XSEG) < (uint32_t)p->auxch.size) {
511 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(XSEG), &p->auxch);
512 p->cursegp = segp = (XSEG *) p->auxch.auxp;
513 (segp+nsegs-1)->cnt = MAXPOS; /* set endcount for safety */
514 }
515 argp = p->argums;
516 nxtval = **argp++;
517 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
518 p->cursegp = segp; /* else proceed from 1st seg */
519 segp--;
520 p->segsrem = nsegs;
521 do {
522 segp++; /* init each seg .. */
523 val = nxtval;
524 dur = **argp++;
525 nxtval = **argp++;
526 if (UNLIKELY(val * nxtval <= FL(0.0)))
527 goto experr;
528 d = dur * CS_EKR;
529 segp->val = val;
530 segp->mlt = (MYFLT) pow((double)(nxtval / val), (1.0/(double)d));
531 segp->cnt = (int32_t) (d + FL(0.5));
532 d = dur * csound->esr;
533 segp->amlt = (MYFLT) pow((double)(nxtval / val), (1.0/(double)d));
534 segp->acnt = (int32_t) (d + FL(0.5));
535 } while (--nsegs);
536 segp->cnt = MAXPOS; /* set last cntr to infin */
537 segp->acnt = MAXPOS; /* set last cntr to infin */
538 return OK;
539
540 experr:
541 n = segp - p->cursegp + 1;
542 if (val == FL(0.0))
543 return csound->InitError(csound, Str("ival%d is zero"), n);
544 else if (nxtval == FL(0.0))
545 return csound->InitError(csound, Str("ival%d is zero"), n+1);
546 return csound->InitError(csound, Str("ival%d sign conflict"), n+1);
547 }
548
xsgset_bkpt(CSOUND * csound,EXXPSEG * p)549 int32_t xsgset_bkpt(CSOUND *csound, EXXPSEG *p)
550 {
551 XSEG *segp;
552 int32_t nsegs;
553 MYFLT d, **argp, val, dur, dursum = FL(0.0), bkpt, nxtval;
554 int32_t n=0;
555
556
557 if (!(p->INCOUNT & 1)){
558 return csound->InitError(csound, Str("incomplete number of input arguments"));
559 }
560
561 /* count segs & alloc if nec */
562 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
563 if ((segp = (XSEG *) p->auxch.auxp) == NULL ||
564 nsegs*sizeof(XSEG) < (uint32_t)p->auxch.size) {
565 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(XSEG), &p->auxch);
566 p->cursegp = segp = (XSEG *) p->auxch.auxp;
567 (segp+nsegs-1)->cnt = MAXPOS; /* set endcount for safety */
568 }
569 argp = p->argums;
570 nxtval = **argp++;
571 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
572 p->cursegp = segp; /* else proceed from 1st seg */
573 segp--;
574 p->segsrem = nsegs;
575 do {
576 segp++; /* init each seg .. */
577 val = nxtval;
578 bkpt = **argp++;
579 if (UNLIKELY(bkpt < dursum))
580 return csound->InitError(csound,
581 Str("Breakpoint time %f not valid"), bkpt);
582 dur = bkpt - dursum;
583 dursum += dur;
584 nxtval = **argp++;
585 if (UNLIKELY(val * nxtval <= FL(0.0)))
586 goto experr;
587 d = dur * CS_EKR;
588 segp->val = val;
589 segp->mlt = (MYFLT) pow((double)(nxtval / val), (1.0/(double)d));
590 segp->cnt = (int32_t) (d + FL(0.5));
591 d = dur * csound->esr;
592 segp->amlt = (MYFLT) pow((double)(nxtval / val), (1.0/(double)d));
593 segp->acnt = (int32_t) (d + FL(0.5));
594 } while (--nsegs);
595 segp->cnt = MAXPOS; /* set last cntr to infin */
596 segp->acnt = MAXPOS;
597 return OK;
598
599 experr:
600 n = segp - p->cursegp + 1;
601 if (val == FL(0.0))
602 return csound->InitError(csound, Str("ival%d is zero"), n);
603 else if (nxtval == FL(0.0))
604 return csound->InitError(csound, Str("ival%d is zero"), n+1);
605 return csound->InitError(csound, Str("ival%d sign conflict"), n+1);
606 }
607
608
xsgset2b(CSOUND * csound,EXPSEG2 * p)609 int32_t xsgset2b(CSOUND *csound, EXPSEG2 *p)
610 {
611 XSEG *segp;
612 int32_t nsegs;
613 MYFLT d, **argp, val, dur, dursum = FL(0.0), bkpt, nxtval;
614 int32_t n;
615
616
617 if (!(p->INCOUNT & 1)){
618 return csound->InitError(csound, Str("incomplete number of input arguments"));
619 }
620
621 /* count segs & alloc if nec */
622 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
623 if ((segp = (XSEG*) p->auxch.auxp) == NULL ||
624 (uint32_t)nsegs*sizeof(XSEG) > (uint32_t)p->auxch.size) {
625 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(XSEG), &p->auxch);
626 p->cursegp = segp = (XSEG *) p->auxch.auxp;
627 (segp+nsegs-1)->cnt = MAXPOS; /* set endcount for safety */
628 }
629 argp = p->argums;
630 nxtval = **argp++;
631 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
632 p->cursegp = segp; /* else proceed from 1st seg */
633 segp--;
634 do {
635 segp++; /* init each seg .. */
636 val = nxtval;
637 bkpt = **argp++;
638 if (UNLIKELY(bkpt < dursum))
639 return csound->InitError(csound,
640 Str("Breakpoint time %f not valid"), bkpt);
641 dur = bkpt - dursum;
642 dursum += dur;
643 nxtval = **argp++;
644 /* if (dur > FL(0.0)) { */
645 if (UNLIKELY(val * nxtval <= FL(0.0)))
646 goto experr;
647 d = dur * csound->esr;
648 segp->val = val;
649 segp->mlt = POWER((nxtval / val), FL(1.0)/d);
650 segp->cnt = (int32_t) (d + FL(0.5));
651 d = dur * csound->esr;
652 segp->amlt = (MYFLT) pow((double)(nxtval / val), (1.0/(double)d));
653 segp->acnt = (int32_t) (d + FL(0.5));
654 /* } */
655 /* else break; /\* .. til 0 dur or done *\/ */
656 } while (--nsegs);
657 segp->cnt = MAXPOS; /* set last cntr to infin */
658 segp->acnt = MAXPOS;
659 return OK;
660
661 experr:
662 n = segp - p->cursegp + 1;
663 if (val == FL(0.0))
664 return csound->InitError(csound, Str("ival%d is zero"), n);
665 else if (nxtval == FL(0.0))
666 return csound->InitError(csound, Str("ival%d is zero"), n+1);
667 return csound->InitError(csound, Str("ival%d sign conflict"), n+1);
668 }
669
xsgset2(CSOUND * csound,EXPSEG2 * p)670 int32_t xsgset2(CSOUND *csound, EXPSEG2 *p) /*gab-A1 (G.Maldonado) */
671 {
672 XSEG *segp;
673 int32_t nsegs;
674 MYFLT d, **argp, val, dur, nxtval;
675 int32_t n;
676
677
678 if (!(p->INCOUNT & 1)){
679 return csound->InitError(csound, Str("incomplete number of input arguments"));
680 }
681
682 /* count segs & alloc if nec */
683 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
684 if ((segp = (XSEG*) p->auxch.auxp) == NULL ||
685 (uint32_t)nsegs*sizeof(XSEG) > (uint32_t)p->auxch.size) {
686 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(XSEG), &p->auxch);
687 p->cursegp = segp = (XSEG *) p->auxch.auxp;
688 (segp+nsegs-1)->cnt = MAXPOS; /* set endcount for safety */
689 }
690 argp = p->argums;
691 nxtval = **argp++;
692 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
693 p->cursegp = segp; /* else proceed from 1st seg */
694 segp--;
695 do {
696 segp++; /* init each seg .. */
697 val = nxtval;
698 dur = **argp++;
699 nxtval = **argp++;
700 /* if (dur > FL(0.0)) { */
701 if (UNLIKELY(val * nxtval <= FL(0.0)))
702 goto experr;
703 d = dur * csound->esr;
704 segp->val = val;
705 segp->mlt = POWER((nxtval / val), FL(1.0)/d);
706 segp->cnt = (int32_t) (d + FL(0.5));
707 d = dur * csound->esr;
708 segp->amlt = (MYFLT) pow((double)(nxtval / val), (1.0/(double)d));
709 segp->acnt = (int32_t) (d + FL(0.5));
710 /* } */
711 /* else break; /\* .. til 0 dur or done *\/ */
712 } while (--nsegs);
713 segp->cnt = MAXPOS; /* set last cntr to infin */
714 segp->acnt = MAXPOS;
715 return OK;
716
717 experr:
718 n = segp - p->cursegp + 1;
719 if (val == FL(0.0))
720 return csound->InitError(csound, Str("ival%d is zero"), n);
721 else if (nxtval == FL(0.0))
722 return csound->InitError(csound, Str("ival%d is zero"), n+1);
723 return csound->InitError(csound, Str("ival%d sign conflict"), n+1);
724 }
725
726 /***************************************/
727
expseg2(CSOUND * csound,EXPSEG2 * p)728 int32_t expseg2(CSOUND *csound, EXPSEG2 *p) /* gab-A1 (G.Maldonado) */
729 {
730 IGN(csound);
731 XSEG *segp;
732 uint32_t offset = p->h.insdshead->ksmps_offset;
733 uint32_t early = p->h.insdshead->ksmps_no_end;
734 uint32_t n, nsmps = CS_KSMPS;
735 MYFLT val, *rs;
736 segp = p->cursegp;
737 val = segp->val;
738 rs = p->rslt;
739 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
740 if (UNLIKELY(early)) {
741 nsmps -= early;
742 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
743 }
744 for (n=offset; n<nsmps; n++) {
745 while (--segp->cnt < 0) {
746 p->cursegp = ++segp;
747 val = segp->val;
748 }
749 rs[n] = val;
750 val *= segp->mlt;
751 }
752 segp->val = val;
753 return OK;
754 }
755
756 /* **** XDSR is just a construction and use of expseg */
757
xdsrset(CSOUND * csound,EXXPSEG * p)758 int32_t xdsrset(CSOUND *csound, EXXPSEG *p)
759 {
760 XSEG *segp;
761 int32_t nsegs;
762 MYFLT **argp = p->argums;
763 MYFLT len = csound->curip->p3.value;
764 MYFLT delay = *argp[4], attack = *argp[0], decay = *argp[1];
765 MYFLT sus, dur;
766 MYFLT release = *argp[3];
767
768 if (UNLIKELY(len<FL(0.0))) len = FL(100000.0); /* MIDI case set long */
769 if (csound->curip->p3.value-delay-attack-decay<FL(0.0))
770 csound->Warning(csound, Str("length of XADSR note too short"));
771 len -= release; /* len is time remaining */
772 if (UNLIKELY(len<FL(0.0))) { /* Odd case of release time greater than dur */
773 release = csound->curip->p3.value; len = FL(0.0);
774 }
775 nsegs = 5; /* DXDSR */
776 if ((segp = (XSEG *) p->auxch.auxp) == NULL ||
777 nsegs*sizeof(XSEG) < (uint32_t)p->auxch.size) {
778 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(XSEG), &p->auxch);
779 segp = (XSEG *) p->auxch.auxp;
780 }
781 segp[nsegs-1].cnt = MAXPOS; /* set endcount for safety */
782 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
783 p->cursegp = segp; /* else setup null seg0 */
784 p->segsrem = nsegs;
785 delay += FL(0.001);
786 if (delay > len) {delay = len; len -= delay;}
787 attack -= FL(0.001);
788 if (attack > len) {attack = len; len -= attack;}
789 if (decay > len) {decay = len; len -= decay;}
790 sus = len;
791 segp[0].val = FL(0.0001); /* Like zero start, but exponential */
792 segp[0].mlt = FL(1.0);
793 segp[0].cnt = (int32_t) (delay*CS_EKR + FL(0.5));
794 segp[0].amlt = FL(1.0);
795 segp[0].acnt = (int32_t) (delay*CS_ESR + FL(0.5));
796 dur = attack*CS_EKR;
797 segp[1].val = FL(0.0001);
798 segp[1].mlt = POWER(FL(1000.0), FL(1.0)/dur);
799 segp[1].cnt = (int32_t) (dur + FL(0.5));
800 dur = attack*CS_ESR;
801 segp[1].amlt = POWER(FL(1000.0), FL(1.0)/dur);
802 segp[1].acnt = (int32_t) (dur + FL(0.5));
803 //printf("attack: %f %f %d / %f %d\n",
804 // segp[1].val,segp[1].mlt,segp[1].cnt,segp[1].amlt, segp[1].acnt);
805 dur = decay*CS_EKR;
806 segp[2].val = FL(1.0);
807 segp[2].mlt = POWER(*argp[2], FL(1.0)/dur);
808 segp[2].cnt = (int32_t) (dur + FL(0.5));
809 dur = decay*CS_ESR;
810 segp[2].amlt = POWER(*argp[2], FL(1.0)/dur);
811 segp[2].acnt = (int32_t) (dur + FL(0.5));
812 //printf("decay: %f %f %d %f %d\n",
813 // segp[2].val,segp[2].mlt,segp[2].cnt,segp[2].amlt, segp[2].acnt);
814 segp[3].val = *argp[2];
815 segp[3].mlt = FL(1.0);
816 segp[3].cnt = (int32_t) (sus*CS_EKR + FL(0.5));
817
818 segp[3].amlt = FL(1.0);
819 segp[3].acnt = (int32_t) (sus*CS_ESR + FL(0.5));
820 //printf("sustain: %f %f %d %f %d\n",
821 // segp[3].val,segp[3].mlt,segp[3].cnt,segp[3].amlt, segp[3].acnt);
822 dur = release*CS_EKR;
823 segp[4].val = *argp[2];
824 segp[4].mlt = POWER(FL(0.001)/(*argp[2]), FL(1.0)/dur);
825 segp[4].cnt = MAXPOS; /*(int32_t) (dur + FL(0.5)); */
826
827 dur = release*CS_ESR;
828 segp[4].amlt = POWER(FL(0.001)/(*argp[2]), FL(1.0)/dur);
829 segp[4].acnt = MAXPOS; /*(int32_t) (dur + FL(0.5)); */
830 //printf("releaase: %f %f %d %f %d\n",
831 // segp[4].val,segp[4].mlt,segp[4].cnt,segp[4].amlt, segp[4].acnt);
832 return OK;
833 }
834
835 /* end of XDSR */
836
kxpseg(CSOUND * csound,EXXPSEG * p)837 int32_t kxpseg(CSOUND *csound, EXXPSEG *p)
838 {
839 XSEG *segp;
840
841
842 segp = p->cursegp;
843 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1; /* RWD fix */
844 while (--segp->cnt < 0)
845 p->cursegp = ++segp;
846 *p->rslt = segp->val;
847 segp->val *= segp->mlt;
848 return OK;
849 err1:
850 return csound->PerfError(csound, &(p->h),
851 Str("expseg (krate): not initialised"));
852 }
853
854
expseg(CSOUND * csound,EXXPSEG * p)855 int32_t expseg(CSOUND *csound, EXXPSEG *p)
856 {
857 XSEG *segp;
858 uint32_t offset = p->h.insdshead->ksmps_offset;
859 uint32_t early = p->h.insdshead->ksmps_no_end;
860 uint32_t n, nsmps = CS_KSMPS;
861 MYFLT *rs = p->rslt;
862
863
864
865 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
866 if (UNLIKELY(early)) {
867 nsmps -= early;
868 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
869 }
870 for (n=offset; n<nsmps; n++) {
871 segp = p->cursegp;
872 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1;
873 while (--segp->acnt < 0) {
874 //printf("seg: val=%f amlt=%f\n", segp->val,segp->amlt );
875 p->cursegp = ++segp;
876 //printf("nxtseg: val=%f amlt=%f acnt=%d\n",
877 // segp->val,segp->amlt,segp->acnt);
878 }
879 rs[n] = segp->val;
880 segp->val *= segp->amlt;
881 }
882 return OK;
883 err1:
884 return csound->PerfError(csound, &(p->h),
885 Str("expseg (arate): not initialised"));
886 }
887
xsgrset(CSOUND * csound,EXPSEG * p)888 int32_t xsgrset(CSOUND *csound, EXPSEG *p)
889 {
890 int32_t relestim;
891 SEG *segp;
892 int32_t nsegs, n = 0;
893 MYFLT **argp, prvpt;
894
895
896 if (!(p->INCOUNT & 1)){
897 return csound->InitError(csound, Str("incomplete number of input arguments"));
898 }
899
900 //p->xtra = -1;
901 /* count segs & alloc if nec */
902 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
903 if ((segp = (SEG *) p->auxch.auxp) == NULL ||
904 (uint32_t)nsegs*sizeof(SEG) > (uint32_t)p->auxch.size) {
905 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(SEG), &p->auxch);
906 p->cursegp = segp = (SEG *) p->auxch.auxp;
907 }
908 argp = p->argums;
909 prvpt = **argp++;
910 if (**argp < FL(0.0)) return OK; /* if idur1 < 0, skip init */
911 p->curval = prvpt;
912 p->curcnt = 0; /* else setup null seg0 */
913 p->cursegp = segp - 1;
914 p->segsrem = nsegs + 1;
915 do { /* init & chk each real seg .. */
916 MYFLT dur = **argp++;
917 segp->nxtpt = **argp++;
918 if ((segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5))) <= 0)
919 segp->cnt = 0;
920 else if (segp->nxtpt * prvpt <= FL(0.0))
921 goto experr;
922 if ((segp->acnt = (int32_t)(dur * CS_ESR )) <= 0)
923 segp->acnt = 0;
924 prvpt = segp->nxtpt;
925 segp++;
926 } while (--nsegs);
927 relestim = (int32_t)(p->cursegp + p->segsrem - 1)->cnt;
928 p->xtra = relestim;
929 if (relestim > p->h.insdshead->xtratim)
930 p->h.insdshead->xtratim = relestim;
931 return OK;
932
933 experr:
934 n = segp - p->cursegp;// + 2;
935 if (prvpt == FL(0.0))
936 return csound->InitError(csound, Str("ival%d is zero"), n);
937 else if (segp->nxtpt == FL(0.0))
938 return csound->InitError(csound, Str("ival%d is zero"), n+1);
939 return csound->InitError(csound, Str("ival%d sign conflict"), n+1);
940 }
941
942 /* **** MXDSR is just a construction and use of expseg */
943
mxdsrset(CSOUND * csound,EXPSEG * p)944 int32_t mxdsrset(CSOUND *csound, EXPSEG *p)
945 {
946 int32_t relestim;
947 SEG *segp;
948 int32_t nsegs;
949 MYFLT **argp = p->argums;
950 MYFLT delay = *argp[4], attack = *argp[0], decay = *argp[1];
951 MYFLT rel = *argp[3];
952
953 nsegs = 4; /* DXDSR */
954 if ((segp = (SEG *) p->auxch.auxp) == NULL ||
955 nsegs*sizeof(SEG) < (uint32_t)p->auxch.size) {
956 csound->AuxAlloc(csound, (int32_t)nsegs*sizeof(SEG), &p->auxch);
957 segp = (SEG *) p->auxch.auxp;
958 }
959 if (**argp <= FL(0.0)) return OK; /* if idur1 <= 0, skip init */
960 p->cursegp = segp-1; /* else setup null seg0 */
961 p->segsrem = nsegs+1;
962 p->curval = FL(0.001);
963 p->curcnt = 0; /* else setup null seg0 */
964 delay += FL(0.001);
965 attack -= FL(0.001);
966 segp[0].nxtpt = FL(0.001);
967 segp[0].cnt = (int32_t) (delay*CS_EKR + FL(0.5));
968 segp[0].acnt = (int32_t) (delay*CS_ESR + FL(0.5));
969 segp[1].nxtpt = FL(1.0);
970 segp[1].cnt = (int32_t) (attack*CS_EKR + FL(0.5));
971 segp[1].acnt = (int32_t) (attack*CS_ESR + FL(0.5));
972 segp[2].nxtpt = *argp[2];
973 segp[2].cnt = (int32_t) (decay*CS_EKR + FL(0.5));
974 segp[2].acnt = (int32_t) (decay*CS_ESR + FL(0.5));
975 segp[3].nxtpt = FL(0.001);
976 segp[3].cnt = (int32_t) (rel*CS_EKR + FL(0.5));
977 segp[3].acnt = (int32_t) (rel*CS_ESR + FL(0.5));
978 relestim = (int32_t)(p->cursegp + p->segsrem - 1)->cnt;
979 p->xtra = relestim;//(int32_t)(*argp[5] * CS_EKR + FL(0.5)); /* Release time?? */
980 if (relestim > p->h.insdshead->xtratim)
981 p->h.insdshead->xtratim = relestim;
982 return OK;
983 }
984
985 /* end of MXDSR */
986
kxpsegr(CSOUND * csound,EXPSEG * p)987 int32_t kxpsegr(CSOUND *csound, EXPSEG *p)
988 {
989 IGN(csound);
990 *p->rslt = p->curval; /* put the cur value */
991 if (p->segsrem) { /* done if no more segs */
992 SEG *segp;
993 if (p->h.insdshead->relesing && p->segsrem > 1) {
994 while (p->segsrem > 1) { /* reles flag new: */
995 segp = ++p->cursegp; /* go to last segment */
996 p->segsrem--;
997 } /* get univ relestim */
998 segp->cnt = p->xtra>=0 ? p->xtra : p->h.insdshead->xtratim;
999 goto newm; /* and set new curmlt */
1000 }
1001 if (--p->curcnt <= 0) { /* if done cur seg */
1002 chk2:
1003 if (p->segsrem == 2) return OK; /* seg Y rpts lastval */
1004 if (!(--p->segsrem)) return OK; /* seg Z now done all */
1005 segp = ++p->cursegp; /* else find nextseg */
1006 newm:
1007 if (!(p->curcnt = segp->cnt)) { /* nonlen = discontin */
1008 p->curval = segp->nxtpt; /* reload & rechk */
1009 goto chk2;
1010 }
1011 if (segp->nxtpt == p->curval) /* else get new mlt */
1012 p->curmlt = FL(1.0);
1013 else p->curmlt = (MYFLT) pow(segp->nxtpt/p->curval, 1.0/segp->cnt);
1014 }
1015 p->curval *= p->curmlt; /* advance the cur val */
1016 }
1017 return OK;
1018 }
1019
expsegr(CSOUND * csound,EXPSEG * p)1020 int32_t expsegr(CSOUND *csound, EXPSEG *p)
1021 {
1022 IGN(csound);
1023 MYFLT val, amlt, *rs = p->rslt;
1024 uint32_t offset = p->h.insdshead->ksmps_offset;
1025 uint32_t early = p->h.insdshead->ksmps_no_end;
1026 uint32_t n, nsmps = CS_KSMPS;
1027
1028
1029 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
1030 if (UNLIKELY(early)) {
1031 nsmps -= early;
1032 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
1033 }
1034 /* sav the cur value */
1035 val = p->curval;
1036 for (n=offset; n<nsmps; n++) {
1037
1038 if (p->segsrem) { /* if no more segs putk */
1039 SEG *segp;
1040 if (p->h.insdshead->relesing && p->segsrem > 1) {
1041 while (p->segsrem > 1) { /* if reles flag new */
1042 segp = ++p->cursegp; /* go to last segment */
1043 p->segsrem--;
1044 } /* get univ relestim */
1045 segp->acnt = (p->xtra>=0 ? p->xtra : p->h.insdshead->xtratim)*CS_KSMPS;
1046 goto newm; /* and set new curmlt */
1047 }
1048 if (--p->curcnt <= 0) { /* if done cur seg */
1049 chk2:
1050 if (p->segsrem == 2) goto putk; /* seg Y rpts lastval */
1051 if (!(--p->segsrem)) goto putk; /* seg Z now done all */
1052 segp = ++p->cursegp; /* else find nextseg */
1053 newm:
1054 if (!(p->curcnt = segp->acnt)) { /* nonlen = discontin */
1055 val = p->curval = segp->nxtpt; /* reload & rechk */
1056 goto chk2;
1057 } /* else get new mlts */
1058 if (segp->nxtpt == val) {
1059 p->curmlt = p->curamlt = FL(1.0);
1060 p->curval = val;
1061 goto putk;
1062 }
1063 else {
1064 p->curmlt = POWER((segp->nxtpt/val), FL(1.0)/segp->cnt);
1065 // VL: this line introduces a bug
1066 //p->curamlt = POWER(p->curmlt, FL(1.0)/(MYFLT)(nsmps-offset));
1067 // VL: this line fixes it but does not take account of offset
1068 p->curamlt = POWER((segp->nxtpt/val), FL(1.0)/segp->acnt);
1069 }
1070 }
1071 if ((amlt = p->curamlt) == FL(1.0)) goto putk;
1072 rs[n] = val;
1073 val *= amlt;
1074 }
1075 else {
1076 putk:
1077 rs[n] = val;
1078 }
1079 }
1080 p->curval = val;
1081 return OK;
1082 }
1083
lnnset(CSOUND * csound,LINEN * p)1084 int32_t lnnset(CSOUND *csound, LINEN *p)
1085 {
1086 MYFLT a,b,dur;
1087 MYFLT len = csound->curip->p3.value;
1088
1089 if ((dur = *p->idur) > FL(0.0)) {
1090 MYFLT iris = *p->iris, idec = *p->idec;
1091 if (len<(iris<idec?idec:iris))
1092 csound->Warning(csound, Str("p3 too short in linen"));
1093
1094 p->cnt1 = (int32_t)(iris * CS_EKR + FL(0.5));
1095 if (p->cnt1 > (int32_t)0) {
1096 p->inc1 = FL(1.0) / (MYFLT) p->cnt1;
1097 }
1098 else p->inc1 = FL(1.0);
1099 a = dur * CS_EKR + FL(0.5);
1100 b = idec * CS_EKR + FL(0.5);
1101 if ((int32_t) b > 0) {
1102 p->cnt2 = (int32_t) (a - b);
1103 p->inc2 = FL(1.0) / b;
1104 }
1105 else {
1106 p->inc2 = FL(1.0);
1107 p->cnt2 = (int32_t) a;
1108 }
1109 p->lin1 = FL(0.0);
1110 p->lin2 = FL(1.0);
1111 }
1112 return OK;
1113 }
1114
alnnset(CSOUND * csound,LINEN * p)1115 int32_t alnnset(CSOUND *csound, LINEN *p)
1116 {
1117 MYFLT a,b,dur;
1118 MYFLT len = csound->curip->p3.value;
1119
1120 if ((dur = *p->idur) > FL(0.0)) {
1121 MYFLT iris = *p->iris, idec = *p->idec;
1122 if (len<(iris<idec?idec:iris))
1123 csound->Warning(csound, Str("p3 too short in linen"));
1124 p->cnt1 = (int64_t)(*p->iris * CS_ESR + FL(0.5));
1125 if (p->cnt1 > 0) {
1126 p->inc1 = FL(1.0) / (MYFLT) p->cnt1;
1127 }
1128 else p->inc1 = FL(1.0);
1129 a = dur * CS_ESR + FL(0.5);
1130 b = *p->idec * CS_ESR + FL(0.5);
1131 if ((int64_t) b > 0) {
1132 p->cnt2 = (int64_t) (a - b);
1133 p->inc2 = FL(1.0) / b;
1134 }
1135 else {
1136 p->inc2 = FL(1.0);
1137 p->cnt2 = (int64_t) a;
1138 }
1139 p->lin1 = FL(0.0);
1140 p->lin2 = FL(1.0);
1141 }
1142 return OK;
1143 }
1144
klinen(CSOUND * csound,LINEN * p)1145 int32_t klinen(CSOUND *csound, LINEN *p)
1146 {
1147 IGN(csound);
1148 MYFLT fact = FL(1.0);
1149
1150 if (p->cnt1 > 0) {
1151 fact = p->lin1;
1152 p->lin1 += p->inc1;
1153 p->cnt1--;
1154 }
1155 if (p->cnt2 > 0)
1156 p->cnt2--;
1157 else {
1158 fact *= p->lin2;
1159 p->lin2 -= p->inc2;
1160 }
1161 *p->rslt = *p->sig * fact;
1162 return OK;
1163 }
1164
linen(CSOUND * csound,LINEN * p)1165 int32_t linen(CSOUND *csound, LINEN *p)
1166 {
1167 IGN(csound);
1168 uint32_t offset = p->h.insdshead->ksmps_offset;
1169 uint32_t early = p->h.insdshead->ksmps_no_end;
1170 uint32_t flag=0, n, nsmps = CS_KSMPS;
1171 MYFLT *rs,*sg,val;
1172 int32_t asgsg = IS_ASIG_ARG(p->sig);
1173 int64_t cnt2 = p->cnt2;
1174 int64_t cnt1 = p->cnt1;
1175 MYFLT lin1 = p->lin1;
1176 MYFLT lin2 = p->lin2;
1177
1178 rs = p->rslt;
1179 sg = p->sig;
1180
1181 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
1182 if (UNLIKELY(early)) {
1183 nsmps -= early;
1184 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
1185 }
1186
1187 for (n=offset; n<nsmps; n++) {
1188 val = FL(1.0);
1189 if (cnt1 > 0) {
1190 flag = 1;
1191 val = lin1;
1192 lin1 += p->inc1;
1193 cnt1--;
1194 }
1195
1196 if (cnt2 > 0){
1197 cnt2--;
1198 }
1199 else {
1200 val *= lin2;
1201 lin2 -= p->inc2;
1202 flag = 1;
1203 }
1204
1205 if (flag) {
1206 if (asgsg)
1207 rs[n] = sg[n] * val;
1208 else
1209 rs[n] = *sg * val;
1210 }
1211 else {
1212 if (asgsg)
1213 rs[n] = sg[n];
1214 else rs[n] = *sg;
1215 }
1216 flag = 0;
1217 }
1218 p->cnt2 = cnt2;
1219 p->cnt1 = cnt1;
1220 p->lin1 = lin1;
1221 p->lin2 = lin2;
1222 return OK;
1223 }
1224
1225
1226
lnrset(CSOUND * csound,LINENR * p)1227 int32_t lnrset(CSOUND *csound, LINENR *p)
1228 {
1229 p->cnt1 = (int32_t)(*p->iris * CS_EKR + FL(0.5));
1230 if (p->cnt1 > 0L) {
1231 p->inc1 = FL(1.0) / (MYFLT)p->cnt1;
1232 p->val = FL(0.0);
1233 }
1234 else p->inc1 = p->val = FL(1.0);
1235 if (*p->idec > FL(0.0)) {
1236 int32_t relestim = (int32_t)(*p->idec * CS_EKR + FL(0.5));
1237
1238 if (relestim > p->h.insdshead->xtratim)
1239 p->h.insdshead->xtratim = relestim;
1240 if (UNLIKELY(*p->iatdec <= FL(0.0))) {
1241 return csound->InitError(csound, Str("non-positive iatdec"));
1242 }
1243 else p->mlt2 = POWER(*p->iatdec, CS_ONEDKR / *p->idec);
1244 }
1245 else p->mlt2 = FL(1.0);
1246 p->lin1 = FL(0.0);
1247 p->val2 = FL(1.0);
1248 return OK;
1249 }
1250
alnrset(CSOUND * csound,LINENR * p)1251 int32_t alnrset(CSOUND *csound, LINENR *p)
1252 {
1253 p->cnt1 = (int32_t)(*p->iris * CS_ESR);
1254 if (p->cnt1 > 0L) {
1255 p->inc1 = FL(1.0) / (MYFLT)p->cnt1;
1256 p->val = FL(0.0);
1257 }
1258 else p->inc1 = p->val = FL(1.0);
1259 if (*p->idec > FL(0.0)) {
1260 int32_t relestim = (int32_t)(*p->idec * CS_EKR + FL(0.5));
1261 if (relestim > p->h.insdshead->xtratim)
1262 p->h.insdshead->xtratim = relestim;
1263 if (UNLIKELY(*p->iatdec <= FL(0.0))) {
1264 return csound->InitError(csound, Str("non-positive iatdec"));
1265 }
1266 else p->mlt2 = POWER(*p->iatdec, csound->onedsr / *p->idec);
1267 }
1268 else p->mlt2 = FL(1.0);
1269 p->lin1 = FL(0.0);
1270 p->val2 = FL(1.0);
1271 return OK;
1272 }
1273
1274
klinenr(CSOUND * csound,LINENR * p)1275 int32_t klinenr(CSOUND *csound, LINENR *p)
1276 {
1277 IGN(csound);
1278 MYFLT fact = FL(1.0);
1279
1280 if (p->cnt1 > 0L) {
1281 fact = p->lin1;
1282 p->lin1 += p->inc1;
1283 p->cnt1--;
1284 }
1285 if (p->h.insdshead->relesing) {
1286 fact *= p->val2;
1287 p->val2 *= p->mlt2;
1288 }
1289 *p->rslt = *p->sig * fact;
1290 return OK;
1291 }
1292
linenr(CSOUND * csound,LINENR * p)1293 int32_t linenr(CSOUND *csound, LINENR *p)
1294 {
1295 IGN(csound);
1296 uint32_t offset = p->h.insdshead->ksmps_offset;
1297 uint32_t early = p->h.insdshead->ksmps_no_end;
1298 uint32_t flag=0, n, nsmps = CS_KSMPS;
1299 MYFLT *rs,*sg,val,val2 = p->val2;
1300 int32_t asgsg = IS_ASIG_ARG(p->sig);
1301 val = p->val;
1302 rs = p->rslt;
1303 sg = p->sig;
1304 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
1305 if (UNLIKELY(early)) {
1306 nsmps -= early;
1307 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
1308 }
1309 for (n=offset; n<nsmps; n++) {
1310 if (p->cnt1 > 0L) {
1311 flag = 1;
1312 val = p->lin1;
1313 p->lin1 += p->inc1;
1314 p->cnt1--;
1315 }
1316 if (p->h.insdshead->relesing) {
1317 flag = 1;
1318 val = p->cnt1==0L ? val2 :val*val2;
1319 //val *= val2; /* If val = val2 jumps */
1320 val2 *= p->mlt2;
1321 }
1322 if (flag) {
1323 if (asgsg)
1324 rs[n] = sg[n] * val;
1325 else
1326 rs[n] = *sg * val;
1327 }
1328 else {
1329 if (asgsg) rs[n] = sg[n];
1330 else rs[n] = *sg;
1331 }
1332 }
1333 p->val = val;
1334 p->val2 = val2;
1335 return OK;
1336 }
1337
evxset(CSOUND * csound,ENVLPX * p)1338 int32_t evxset(CSOUND *csound, ENVLPX *p)
1339 {
1340 FUNC *ftp;
1341 MYFLT ixmod, iatss, idur, prod, diff, asym, nk, denom, irise;
1342 int32_t cnt1;
1343 MYFLT len = csound->curip->p3.value;
1344
1345 if ((ftp = csound->FTFind(csound, p->ifn)) == NULL)
1346 return NOTOK;
1347 p->ftp = ftp;
1348 if ((idur = *p->idur) > FL(0.0)) {
1349 if (UNLIKELY((iatss = FABS(*p->iatss)) == FL(0.0))) {
1350 return csound->InitError(csound, "iatss = 0");
1351 }
1352 if (iatss != FL(1.0) && (ixmod = *p->ixmod) != FL(0.0)) {
1353 if (UNLIKELY(FABS(ixmod) > FL(0.95))) {
1354 return csound->InitError(csound, Str("ixmod out of range."));
1355 }
1356 ixmod = -SIN(SIN(ixmod));
1357 prod = ixmod * iatss;
1358 diff = ixmod - iatss;
1359 denom = diff + prod + FL(1.0);
1360 if (denom == FL(0.0))
1361 asym = FHUND;
1362 else {
1363 asym = FL(2.0) * prod / denom;
1364 if (FABS(asym) > FHUND)
1365 asym = FHUND;
1366 }
1367 iatss = (iatss - asym) / (FL(1.0) - asym);
1368 asym = asym* *(ftp->ftable + ftp->flen); /* +1 */
1369 }
1370 else asym = FL(0.0);
1371 if ((irise = *p->irise) > FL(0.0)) {
1372 if (irise + *p->idec > len)
1373 csound->Warning(csound, Str("p3 too short in envlpx"));
1374 p->phs = 0;
1375 p->ki = (int32_t) (CS_KICVT / irise);
1376 p->val = *ftp->ftable;
1377 }
1378 else {
1379 p->phs = -1;
1380 p->val = *(ftp->ftable + ftp->flen)-asym;
1381 irise = FL(0.0); /* in case irise < 0 */
1382 }
1383 if (UNLIKELY(!(*(ftp->ftable + ftp->flen)))) {
1384 return csound->InitError(csound, Str("rise func ends with zero"));
1385 }
1386 cnt1 = (int32_t) ((idur - irise - *p->idec) * CS_EKR + FL(0.5));
1387 if (cnt1 < 0L) {
1388 cnt1 = 0;
1389 nk = CS_EKR;
1390 }
1391 else {
1392 if (*p->iatss < FL(0.0) || cnt1 <= 4L)
1393 nk = CS_EKR;
1394 else nk = (MYFLT) cnt1;
1395 }
1396 p->mlt1 = POWER(iatss, (FL(1.0)/nk));
1397 if (*p->idec > FL(0.0)) {
1398 if (UNLIKELY(*p->iatdec <= FL(0.0))) {
1399 return csound->InitError(csound, Str("non-positive iatdec"));
1400 }
1401 p->mlt2 = POWER(*p->iatdec, (CS_ONEDKR / *p->idec));
1402 }
1403 p->cnt1 = cnt1;
1404 p->asym = asym;
1405 }
1406 return OK;
1407 }
1408
knvlpx(CSOUND * csound,ENVLPX * p)1409 int32_t knvlpx(CSOUND *csound, ENVLPX *p)
1410 {
1411 FUNC *ftp;
1412 int32_t phs;
1413 MYFLT fact, v1, fract, *ftab;
1414
1415 ftp = p->ftp;
1416 if (UNLIKELY(ftp==NULL)) goto err1; /* RWD fix */
1417
1418 if ((phs = p->phs) >= 0) {
1419 fract = (MYFLT) PFRAC(phs);
1420 ftab = ftp->ftable + (phs >> ftp->lobits);
1421 v1 = *ftab++;
1422 fact = (v1 + (*ftab - v1) * fract);
1423 phs += p->ki;
1424 if (phs >= MAXLEN) { /* check that 2**N+1th pnt is good */
1425 p->val = *(ftp->ftable + ftp->flen );
1426 if (UNLIKELY(!p->val)) {
1427 return csound->PerfError(csound, &(p->h),
1428 Str("envlpx rise func ends with zero"));
1429 }
1430 p->val -= p->asym;
1431 phs = -1L;
1432 }
1433 p->phs = phs;
1434 }
1435 else {
1436 fact = p->val;
1437 if (p->cnt1 > 0L) {
1438 p->val *= p->mlt1;
1439 fact += p->asym;
1440 p->cnt1--;
1441 if (p->cnt1 == 0L)
1442 p->val += p->asym;
1443 }
1444 else p->val *= p->mlt2;
1445 }
1446 *p->rslt = *p->xamp * fact;
1447 return OK;
1448 err1:
1449 return csound->PerfError(csound, &(p->h),
1450 Str("envlpx(krate): not initialised"));
1451 }
1452
aevxset(CSOUND * csound,ENVLPX * p)1453 int32_t aevxset(CSOUND *csound, ENVLPX *p)
1454 {
1455 FUNC *ftp;
1456 MYFLT ixmod, iatss, idur, prod, diff, asym, nk, denom, irise;
1457 int32_t cnt1;
1458 MYFLT len = csound->curip->p3.value;
1459
1460 if ((ftp = csound->FTFind(csound, p->ifn)) == NULL)
1461 return NOTOK;
1462 p->ftp = ftp;
1463 if ((idur = *p->idur) > FL(0.0)) {
1464 if (UNLIKELY((iatss = FABS(*p->iatss)) == FL(0.0))) {
1465 return csound->InitError(csound, "iatss = 0");
1466 }
1467 if (iatss != FL(1.0) && (ixmod = *p->ixmod) != FL(0.0)) {
1468 if (UNLIKELY(FABS(ixmod) > FL(0.95))) {
1469 return csound->InitError(csound, Str("ixmod out of range."));
1470 }
1471 ixmod = -SIN(SIN(ixmod));
1472 prod = ixmod * iatss;
1473 diff = ixmod - iatss;
1474 denom = diff + prod + FL(1.0);
1475 if (denom == FL(0.0))
1476 asym = FHUND;
1477 else {
1478 asym = FL(2.0) * prod / denom;
1479 if (FABS(asym) > FHUND)
1480 asym = FHUND;
1481 }
1482 iatss = (iatss - asym) / (FL(1.0) - asym);
1483 asym = asym* *(ftp->ftable + ftp->flen); /* +1 */
1484 }
1485 else asym = FL(0.0);
1486
1487 if ((irise = *p->irise) > FL(0.0)) {
1488 if (irise + *p->idec > len)
1489 csound->Warning(csound, Str("p3 too short in envlpx"));
1490 p->phs = 0;
1491 p->ki = (int32_t) ((FMAXLEN / CS_ESR )/ irise);
1492 p->val = *ftp->ftable;
1493 }
1494 else {
1495 p->phs = -1;
1496 p->val = *(ftp->ftable + ftp->flen)-asym;
1497 irise = FL(0.0); /* in case irise < 0 */
1498 }
1499 if (UNLIKELY(!(*(ftp->ftable + ftp->flen)))) {
1500 return csound->InitError(csound, Str("rise func ends with zero"));
1501 }
1502 cnt1 = (int32_t) ((idur - irise - *p->idec) * CS_ESR);
1503 if (cnt1 < 0L) {
1504 cnt1 = 0;
1505 nk = CS_ESR;
1506 }
1507 else {
1508 if (*p->iatss < FL(0.0) || cnt1 <= 4L)
1509 nk = CS_ESR;
1510 else nk = (MYFLT) cnt1;
1511 }
1512 p->mlt1 = POWER(iatss, (FL(1.0)/nk));
1513 if (*p->idec > FL(0.0)) {
1514 if (UNLIKELY(*p->iatdec <= FL(0.0))) {
1515 return csound->InitError(csound, Str("non-positive iatdec"));
1516 }
1517 p->mlt2 = POWER(*p->iatdec, (csound->onedsr / *p->idec));
1518 }
1519 p->cnt1 = cnt1;
1520 p->asym = asym;
1521 }
1522 return OK;
1523 }
1524
1525
envlpx(CSOUND * csound,ENVLPX * p)1526 int32_t envlpx(CSOUND *csound, ENVLPX *p)
1527 {
1528 int32_t phs;
1529 uint32_t offset = p->h.insdshead->ksmps_offset;
1530 uint32_t early = p->h.insdshead->ksmps_no_end;
1531 uint32_t n, nsmps = CS_KSMPS;
1532 int64_t pos, lobits, lomask;
1533 MYFLT fact, *xamp, *rslt, val, asym, mlt, mlt2, v1, fract, *ftab, lodiv;
1534 int32_t asgsg = IS_ASIG_ARG(p->xamp);
1535 xamp = p->xamp;
1536 rslt = p->rslt;
1537 val = p->val;
1538 mlt = p->mlt1;
1539 mlt2 = p->mlt2;
1540 asym = p->asym;
1541
1542 if (UNLIKELY(p->ftp==NULL))
1543 return csound->PerfError(csound, &(p->h),
1544 Str("envlpx(krate): not initialised"));
1545 ftab = p->ftp->ftable;
1546 lobits = p->ftp->lobits;
1547 lomask = p->ftp->lomask;
1548 lodiv = p->ftp->lodiv;
1549 if (UNLIKELY(ftab[p->ftp->flen] == 0.0))
1550 return csound->PerfError(csound, &(p->h),
1551 Str("envlpx rise func ends with zero"));
1552
1553 if (UNLIKELY(offset)) memset(rslt, '\0', offset*sizeof(MYFLT));
1554 if (UNLIKELY(early)) {
1555 nsmps -= early;
1556 memset(&rslt[nsmps], '\0', early*sizeof(MYFLT));
1557 }
1558
1559
1560 for (n=offset; n<nsmps;n++) {
1561
1562 if ((phs = p->phs) >= 0L) {
1563 fract = ((phs) & lomask) * lodiv;
1564 pos = (int64_t) (phs >> lobits);
1565 v1 = ftab[pos+1];
1566 fact = (v1 + (ftab[pos] - v1) * fract);
1567 phs += p->ki;
1568 if (phs >= MAXLEN) {
1569 val = ftab[p->ftp->flen];
1570 val -= p->asym;
1571 phs = -1;
1572 }
1573 p->phs = phs;
1574 }
1575 else {
1576 fact = val;
1577 if (p->cnt1 > 0L) {
1578 val *= mlt;
1579 fact += asym;
1580 p->cnt1--;
1581 if (p->cnt1 == 0L)
1582 val += asym;
1583 }
1584 else val *= mlt2;
1585 }
1586 if (asgsg)
1587 rslt[n] = xamp[n] * fact;
1588 else
1589 rslt[n] = *xamp * fact;
1590 }
1591 p->val = val;
1592 return OK;
1593 }
1594
evrset(CSOUND * csound,ENVLPR * p)1595 int32_t evrset(CSOUND *csound, ENVLPR *p)
1596 {
1597 FUNC *ftp;
1598 MYFLT ixmod, iatss, prod, diff, asym, denom, irise;
1599
1600 if ((ftp = csound->FTFind(csound, p->ifn)) == NULL)
1601 return NOTOK;
1602 p->ftp = ftp;
1603 if (UNLIKELY((iatss = FABS(*p->iatss)) == FL(0.0))) {
1604 return csound->InitError(csound, "iatss = 0");
1605 }
1606 if (iatss != FL(1.0) && (ixmod = *p->ixmod) != FL(0.0)) {
1607 if (UNLIKELY(FABS(ixmod) > FL(0.95))) {
1608 return csound->InitError(csound, Str("ixmod out of range."));
1609 }
1610 ixmod = -SIN(SIN(ixmod));
1611 prod = ixmod * iatss;
1612 diff = ixmod - iatss;
1613 denom = diff + prod + FL(1.0);
1614 if (denom == FL(0.0))
1615 asym = FHUND;
1616 else {
1617 asym = FL(2.0) * prod / denom;
1618 if (FABS(asym) > FHUND)
1619 asym = FHUND;
1620 }
1621 iatss = (iatss - asym) / (FL(1.0) - asym);
1622 asym = asym * *(ftp->ftable + ftp->flen); /* +1 */
1623 }
1624 else asym = FL(0.0);
1625 if ((irise = *p->irise) > FL(0.0)) {
1626 p->phs = 0;
1627 p->ki = (int32_t) (CS_KICVT / irise);
1628 p->val = *ftp->ftable;
1629 }
1630 else {
1631 p->phs = -1;
1632 p->val = *(ftp->ftable + ftp->flen)-asym;
1633 /* irise = FL(0.0); */ /* in case irise < 0 */
1634 }
1635 if (UNLIKELY(!(*(ftp->ftable + ftp->flen)))) {
1636 return csound->InitError(csound, Str("rise func ends with zero"));
1637 }
1638 p->mlt1 = POWER(iatss, CS_ONEDKR);
1639 if (*p->idec > FL(0.0)) {
1640 int32_t rlscnt = (int32_t)(*p->idec * CS_EKR + FL(0.5));
1641 if ((p->rindep = (int32_t)*p->irind))
1642 p->rlscnt = rlscnt;
1643 else if (rlscnt > p->h.insdshead->xtratim)
1644 p->h.insdshead->xtratim = (int32_t)rlscnt;
1645 if (UNLIKELY((p->atdec = *p->iatdec) <= FL(0.0) )) {
1646 return csound->InitError(csound, Str("non-positive iatdec"));
1647 }
1648 }
1649 p->asym = asym;
1650 p->rlsing = 0;
1651 return OK;
1652 }
1653
aevrset(CSOUND * csound,ENVLPR * p)1654 int32_t aevrset(CSOUND *csound, ENVLPR *p)
1655 {
1656 FUNC *ftp;
1657 MYFLT ixmod, iatss, prod, diff, asym, denom, irise;
1658
1659 if ((ftp = csound->FTFind(csound, p->ifn)) == NULL)
1660 return NOTOK;
1661 p->ftp = ftp;
1662 if (UNLIKELY((iatss = FABS(*p->iatss)) == FL(0.0))) {
1663 return csound->InitError(csound, "iatss = 0");
1664 }
1665 if (iatss != FL(1.0) && (ixmod = *p->ixmod) != FL(0.0)) {
1666 if (UNLIKELY(FABS(ixmod) > FL(0.95))) {
1667 return csound->InitError(csound, Str("ixmod out of range."));
1668 }
1669 ixmod = -SIN(SIN(ixmod));
1670 prod = ixmod * iatss;
1671 diff = ixmod - iatss;
1672 denom = diff + prod + FL(1.0);
1673 if (denom == FL(0.0))
1674 asym = FHUND;
1675 else {
1676 asym = FL(2.0) * prod / denom;
1677 if (FABS(asym) > FHUND)
1678 asym = FHUND;
1679 }
1680 iatss = (iatss - asym) / (FL(1.0) - asym);
1681 asym = asym * *(ftp->ftable + ftp->flen); /* +1 */
1682 }
1683 else asym = FL(0.0);
1684 if ((irise = *p->irise) > FL(0.0)) {
1685 p->phs = 0;
1686 p->ki = (int32_t) ((FMAXLEN / CS_ESR)/ irise);
1687 p->val = *ftp->ftable;
1688 }
1689 else {
1690 p->phs = -1;
1691 p->val = *(ftp->ftable + ftp->flen)-asym;
1692 /* irise = FL(0.0); */ /* in case irise < 0 */
1693 }
1694 if (UNLIKELY(!(*(ftp->ftable + ftp->flen)))) {
1695 return csound->InitError(csound, Str("rise func ends with zero"));
1696 }
1697 p->mlt1 = POWER(iatss, csound->onedsr);
1698 if (*p->idec > FL(0.0)) {
1699 int32_t rlscnt = (int32_t)(*p->idec * CS_EKR + FL(0.5));
1700 if ((p->rindep = (int32_t)*p->irind))
1701 p->rlscnt = rlscnt;
1702 else if (rlscnt > p->h.insdshead->xtratim)
1703 p->h.insdshead->xtratim = (int32_t)rlscnt;
1704 if (UNLIKELY((p->atdec = *p->iatdec) <= FL(0.0) )) {
1705 return csound->InitError(csound, Str("non-positive iatdec"));
1706 }
1707 }
1708 p->asym = asym;
1709 p->rlsing = 0;
1710 return OK;
1711 }
1712
1713
knvlpxr(CSOUND * csound,ENVLPR * p)1714 int32_t knvlpxr(CSOUND *csound, ENVLPR *p)
1715 {
1716 IGN(csound);
1717 MYFLT fact;
1718 int32_t rlscnt;
1719
1720 if (!p->rlsing) { /* if not in reles seg */
1721 if (p->h.insdshead->relesing) {
1722 p->rlsing = 1; /* if new flag, set mlt2 */
1723 rlscnt = (p->rindep) ? p->rlscnt : p->h.insdshead->xtratim;
1724 if (rlscnt)
1725 p->mlt2 = POWER(p->atdec, FL(1.0)/rlscnt);
1726 else p->mlt2 = FL(1.0);
1727 }
1728 if (p->phs >= 0) { /* do fn rise for seg 1 */
1729 FUNC *ftp = p->ftp;
1730 int32_t phs = p->phs;
1731 MYFLT fract = PFRAC(phs);
1732 MYFLT *ftab = ftp->ftable + (phs >> ftp->lobits);
1733 MYFLT v1 = *ftab++;
1734 fact = (v1 + (*ftab - v1) * fract);
1735 phs += p->ki;
1736 if (phs < MAXLEN || p->rlsing) /* if more fn or beg rls */
1737 p->val = fact; /* save cur val */
1738 else { /* else prep for seg 2 */
1739 p->val = *(ftp->ftable + ftp->flen) - p->asym;
1740 phs = -1L;
1741 }
1742 p->phs = phs;
1743 }
1744 else {
1745 fact = p->val + p->asym; /* do seg 2 with asym */
1746 p->val *= p->mlt1;
1747 if (p->rlsing) /* if ending, rm asym */
1748 p->val += p->asym;
1749 }
1750 }
1751 else fact = p->val *= p->mlt2; /* else do seg 3 decay */
1752 *p->rslt = *p->xamp * fact;
1753 return OK;
1754 }
1755
envlpxr(CSOUND * csound,ENVLPR * p)1756 int32_t envlpxr(CSOUND *csound, ENVLPR *p)
1757 {
1758 uint32_t offset = p->h.insdshead->ksmps_offset;
1759 uint32_t early = p->h.insdshead->ksmps_no_end;
1760 uint32_t n, nsmps = CS_KSMPS;
1761 int32_t rlscnt;
1762 int64_t lobits, lomask, pos, phs = p->phs;
1763 MYFLT fact, *xamp, *rslt, val, asym, mlt, v1, fract, *ftab, lodiv;
1764 int32_t asgsg = IS_ASIG_ARG(p->xamp);
1765
1766 xamp = p->xamp;
1767 rslt = p->rslt;
1768 val = p->val;
1769 mlt = p->mlt1;
1770 //mlt2 = p->mlt2;
1771 asym = p->asym;
1772
1773 if (UNLIKELY(p->ftp==NULL))
1774 return csound->PerfError(csound, &(p->h),
1775 Str("envlpx(krate): not initialised"));
1776 ftab = p->ftp->ftable;
1777 lobits = p->ftp->lobits;
1778 lomask = p->ftp->lomask;
1779 lodiv = p->ftp->lodiv;
1780 if (UNLIKELY(ftab[p->ftp->flen] == 0.0))
1781 return csound->PerfError(csound, &(p->h),
1782 Str("envlpx rise func ends with zero"));
1783
1784 if (UNLIKELY(offset)) memset(rslt, '\0', offset*sizeof(MYFLT));
1785 if (UNLIKELY(early)) {
1786 nsmps -= early;
1787 memset(&rslt[nsmps], '\0', early*sizeof(MYFLT));
1788 }
1789
1790 for (n=offset; n<nsmps; n++) {
1791
1792 if (!p->rlsing) { /* if not in reles seg */
1793 if (p->h.insdshead->relesing) {
1794 p->rlsing = 1; /* if new flag, set mlt2 */
1795 rlscnt = (p->rindep) ? p->rlscnt : p->h.insdshead->xtratim;
1796 rlscnt *= CS_KSMPS;
1797 if (rlscnt)
1798 p->mlt2 = POWER(p->atdec, FL(1.0)/rlscnt);
1799 else p->mlt2 = FL(1.0);
1800 }
1801 if (p->phs >= 0) { /* do fn rise for seg 1 */
1802 fract = ((phs) & lomask) * lodiv;
1803 pos = (int64_t) (phs >> lobits);
1804 v1 = ftab[pos+1];
1805 fact = (v1 + (ftab[pos] - v1) * fract);
1806 phs += p->ki;
1807 if (phs >= MAXLEN) {
1808 val = ftab[p->ftp->flen];
1809 val -= p->asym;
1810 phs = -1;
1811 }
1812 else val = fact; /* JPff: in case very early release */
1813 p->phs = phs;
1814 }
1815 else {
1816 fact = val + asym;
1817 val *= mlt;
1818 if (p->rlsing)
1819 val += asym;
1820 }
1821 }
1822 else
1823 fact = val *= p->mlt2; /* else do seg 3 decay */
1824
1825 if (asgsg)
1826 rslt[n] = xamp[n] * fact;
1827 else
1828 rslt[n] = *xamp * fact;
1829 }
1830 p->val = val;
1831 return OK;
1832 }
1833
csgset(CSOUND * csound,COSSEG * p)1834 int32_t csgset(CSOUND *csound, COSSEG *p)
1835 {
1836 SEG *segp, *sp;
1837 int32_t nsegs;
1838 MYFLT **argp;
1839 double val, y1, y2;
1840
1841
1842 if (!(p->INCOUNT & 1)) {
1843 return csound->InitError(csound, Str("incomplete number of input arguments"));
1844 }
1845
1846 /* count segs & alloc if nec */
1847 nsegs = (p->INOCOUNT - (!(p->INOCOUNT & 1))) >> 1;
1848 //printf("****nsegs = %d\n", nsegs);
1849 if ((segp = (SEG *) p->auxch.auxp) == NULL ||
1850 nsegs*sizeof(SEG) < (uint32_t)p->auxch.size) {
1851 csound->AuxAlloc(csound, (int32_t)(1+nsegs)*sizeof(SEG), &p->auxch);
1852 p->cursegp = 1+(segp = (SEG *) p->auxch.auxp);
1853 segp[nsegs-1].cnt = MAXPOS; /* set endcount for safety */
1854 segp[nsegs-1].acnt = MAXPOS;
1855 }
1856 sp = segp;
1857 argp = p->argums;
1858 y1 = val = (double)**argp++;
1859 if (UNLIKELY(**argp <= FL(0.0))) return OK; /* if idur1 <= 0, skip init */
1860 p->curcnt = 0;
1861 p->cursegp = segp+1; /* else setup first seg */
1862 p->segsrem = nsegs;
1863 //printf("****current seg = %p segp = %p\n", p->cursegp, segp);
1864 do { /* init each seg .. */
1865 double dur = (double)**argp++;
1866 segp->nxtpt = (double)**argp++;
1867 if (UNLIKELY((segp->cnt = (int32_t)(dur * CS_EKR + FL(0.5))) < 0))
1868 segp->cnt = 0;
1869 if (UNLIKELY((segp->acnt = (int32_t)(dur * CS_ESR)) < 0))
1870 segp->acnt = 0;
1871
1872 //printf("****i: %d(%p): cnt=%d nxtpt=%f\n",
1873 // p->segsrem-nsegs, segp, segp->cnt, segp->nxtpt);
1874 segp++;
1875 } while (--nsegs);
1876 p->y1 = y1;
1877 p->y2 = y2 = sp->nxtpt;
1878 p->x = 0.0;
1879 if (IS_ASIG_ARG(p->rslt)) {
1880 p->inc = (y2!=y1 ? 1.0/(sp->acnt) : 0.0);
1881 p->curcnt = sp->acnt;
1882 }
1883 else {
1884 p->inc = (y2!=y1 ? 1.0/(sp->cnt) : 0.0);
1885 p->curcnt = sp->cnt;
1886 }
1887 //printf("****incx, y1,y2 = %g, %f, %f\n", p->inc, p->y1, p->y2);
1888 p->val = p->y1;
1889 return OK;
1890 }
1891
csgset_bkpt(CSOUND * csound,COSSEG * p)1892 int32_t csgset_bkpt(CSOUND *csound, COSSEG *p)
1893 {
1894 int32_t cnt, bkpt = 0;
1895 int32_t nsegs;
1896 int32_t n;
1897 SEG *segp;
1898 n = csgset(csound, p);
1899 if (UNLIKELY(n!=0)) return n;
1900 cnt = p->curcnt;
1901 nsegs = p->segsrem-1;
1902 segp = p->cursegp;
1903 if (IS_ASIG_ARG(p->rslt))
1904 do {
1905 if (UNLIKELY(cnt > segp->acnt))
1906 return csound->InitError(csound, Str("Breakpoint %d not valid"), bkpt);
1907 segp->acnt -= cnt;
1908 cnt += segp->acnt;
1909 segp++;
1910 bkpt++;
1911 } while (--nsegs);
1912 else
1913 do {
1914 //csound->Message(csound, "%d/ %d: %d, %d ", nsegs, bkpt, cnt, segp->cnt);
1915 if (UNLIKELY(cnt > segp->cnt))
1916 return csound->InitError(csound, Str("Breakpoint %d not valid"), bkpt);
1917 segp->cnt -= cnt;
1918 cnt += segp->cnt;
1919 //csound->Message(csound, "-> %d, %d %f\n", cnt, segp->cnt, segp->nxtpt);
1920 segp++;
1921 bkpt++;
1922 } while (--nsegs);
1923
1924 return OK;
1925 }
1926
csgrset(CSOUND * csound,COSSEG * p)1927 int32_t csgrset(CSOUND *csound, COSSEG *p)
1928 {
1929 int32_t relestim;
1930 if (csgset(csound,p) != 0) return NOTOK;
1931 relestim = (p->cursegp + p->segsrem-2)->cnt;
1932 p->xtra = relestim;
1933 if (relestim > p->h.insdshead->xtratim)
1934 p->h.insdshead->xtratim = (int32_t)relestim;
1935 return OK;
1936 }
1937
kosseg(CSOUND * csound,COSSEG * p)1938 int32_t kosseg(CSOUND *csound, COSSEG *p)
1939 {
1940 double val1 = p->y1, val2 = p->y2, x = p->x;
1941 double inc = p->inc;
1942
1943 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1; /* RWD fix */
1944
1945 if (LIKELY(p->segsrem)) { /* if no more segs putk */
1946 if (--p->curcnt <= 0) { /* if done cur segment */
1947 SEG *segp = p->cursegp;
1948 chk1:
1949 p->y1 = val1 = val2;
1950 if (UNLIKELY(!--p->segsrem)) { /* if none left */
1951 p->y2 = val2 = segp->nxtpt;
1952 goto putk; /* put endval */
1953 }
1954 //printf("new seg: %d %f\n", segp->cnt, segp->nxtpt);
1955 val2 = p->y2 = segp->nxtpt; /* Base of next segment */
1956 inc = p->inc = (segp->cnt ? 1.0/(segp->cnt) : 0.0);
1957 x = 0.0;
1958 p->cursegp = segp+1; /* else find the next */
1959 if (UNLIKELY(!(p->curcnt = segp->cnt))) {
1960 val2 = p->y2 = segp->nxtpt; /* nonlen = discontin */
1961 inc = p->inc = (segp->cnt ? 1.0/(segp->cnt) : 0.0);
1962 goto chk1;
1963 } /* poslen = new slope */
1964 }
1965 {
1966 double mu2 = (1.0-cos(x*PI))*0.5;
1967 *p->rslt = (MYFLT)(val1*(1.0-mu2)+val2*mu2);
1968 x += inc;
1969 }
1970 }
1971 else {
1972 putk:
1973 *p->rslt = (MYFLT)val1;
1974 }
1975 p->x = x;
1976 return OK;
1977 err1:
1978 return csound->InitError(csound, Str("cosseg not initialised (krate)\n"));
1979 }
1980
cosseg(CSOUND * csound,COSSEG * p)1981 int32_t cosseg(CSOUND *csound, COSSEG *p)
1982 {
1983 double val1 = p->y1, val2 = p->y2, x = p->x;
1984 MYFLT *rs = p->rslt;
1985 uint32_t offset = p->h.insdshead->ksmps_offset;
1986 uint32_t early = p->h.insdshead->ksmps_no_end;
1987 uint32_t n, nsmps = CS_KSMPS;
1988 double inc = p->inc;///(nsmps-offset);
1989
1990 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1;
1991
1992 if (UNLIKELY(offset)) memset(rs, '\0', offset*sizeof(MYFLT));
1993 if (UNLIKELY(early)) {
1994 nsmps -= early;
1995 memset(&rs[nsmps], '\0', early*sizeof(MYFLT));
1996 }
1997
1998 for (n=offset; n<nsmps; n++) {
1999 double mu2;
2000 if (LIKELY(p->segsrem)) { /* if no more segs putk */
2001 if (--p->curcnt <= 0) { /* if done cur segment */
2002 SEG *segp = p->cursegp;
2003 chk1:
2004 p->y1 = val1 = val2;
2005 if (UNLIKELY(!--p->segsrem)) { /* if none left */
2006 p->y2 = val2 = segp->nxtpt;
2007 goto putk; /* put endval */
2008 }
2009 val2 = p->y2 = segp->nxtpt; /* Base of next segment */
2010 inc = (segp->acnt ? 1.0/(segp->acnt) : 0.0);
2011 x = 0.0;
2012 //printf("****new seg val1.val2=%f,%f inc=%f\n", val1,val2, inc);
2013 p->cursegp = segp+1; /* else find the next */
2014 if (UNLIKELY(!(p->curcnt = segp->acnt))) {
2015 val2 = p->y2 = segp->nxtpt; /* nonlen = discontin */
2016 inc = (segp->acnt ? 1.0/(segp->acnt) : 0.0);
2017 //printf("****val1,val2=%f,%f inc=%f\n", val1, val2, inc);
2018 goto chk1;
2019 } /* poslen = new slope */
2020 }
2021 mu2 = (1.0-cos(x*PI))*0.5;
2022 //printf("****x=%f inc=%f mu2=%f\n", x, inc, mu2);
2023 rs[n] = (MYFLT)(val1*(1.0-mu2)+val2*mu2);
2024 x += inc;
2025 }
2026 else {
2027 putk:
2028 rs[n] = (MYFLT)val1;
2029
2030 }
2031 }
2032 p->inc = inc;
2033 p->x = x;
2034 return OK;
2035 err1:
2036 return csound->PerfError(csound, &(p->h),
2037 Str("cosseg: not initialised (arate)\n"));
2038 }
2039
cossegr(CSOUND * csound,COSSEG * p)2040 int32_t cossegr(CSOUND *csound, COSSEG *p)
2041 {
2042 double val1 = p->y1, val2 = p->y2, x = p->x, val = p->val;
2043 MYFLT *rs = p->rslt;
2044 uint32_t offset = p->h.insdshead->ksmps_offset;
2045 uint32_t n, nsmps = CS_KSMPS;
2046 double inc = p->inc;
2047
2048 memset(rs, '\0', offset*sizeof(MYFLT));
2049 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1;
2050
2051 for (n=offset; n<nsmps; n++) {
2052 if (LIKELY(p->segsrem)) { /* if no more segs putk */
2053 SEG *segp = p->cursegp;
2054 if (p->h.insdshead->relesing && p->segsrem > 1) {
2055 while (p->segsrem > 1) { /* release flag new: */
2056 segp = ++p->cursegp; /* go to last segment */
2057 p->segsrem--;
2058 }
2059 segp--; /* get univ relestim */
2060 segp->acnt = (p->xtra >=0 ? p->xtra : p->h.insdshead->xtratim)*CS_KSMPS;
2061 //p->y1 = val1 = val2;
2062 p->y1 = val1 = val;
2063 //printf("%d(%p): cnt=%d strt= %f nxtpt=%f\n",
2064 // p->segsrem, segp, segp->cnt,val1, segp->nxtpt);
2065 goto newi; /* and set new curinc */
2066 }
2067 if (p->segsrem == 1 && !p->h.insdshead->relesing) {
2068 goto putk;
2069 }
2070 if (--p->curcnt <= 0) { /* if done cur segment */
2071 chk1:
2072 p->y1 = val1 = val2;
2073 if (UNLIKELY(!--p->segsrem)) { /* if none left */
2074 p->y2 = val2 = segp->nxtpt;
2075 goto putk; /* put endval */
2076 }
2077 newi:
2078 //printf("new seg: %d %f\n", segp->cnt, segp->nxtpt);
2079 val2 = p->y2 = segp->nxtpt; /* Base of next segment */
2080 inc =p->inc = (segp->acnt ? 1.0/(segp->acnt) : 0.0);
2081 x = 0.0;
2082 p->cursegp = segp+1; /* else find the next */
2083 if (UNLIKELY(!(p->curcnt = segp->acnt))) {
2084 val2 = p->y2 = segp->nxtpt; /* nonlen = discontin */
2085 inc = p->inc = (segp->acnt ? 1.0/(segp->acnt) : 0.0);
2086 goto chk1;
2087 } /* poslen = new slope */
2088 //printf("New segment incx, y1,y2 = %g, %f, %f\n", inc, val1, val2);
2089 }
2090 {
2091 double mu2 = (1.0-cos(x*PI))*0.5;
2092 val = rs[n] = (MYFLT)(val1*(1.0-mu2)+val2*mu2);
2093 x += inc;
2094 //if (x>1 || x<0) printf("x=%f out of range\n", x);
2095 }
2096 }
2097 else {
2098 putk:
2099 rs[n] = (MYFLT)val1;
2100 }
2101 }
2102 p->inc = inc;
2103 p->x = x;
2104 p->val = val;
2105 return OK;
2106 err1:
2107 return csound->PerfError(csound, &(p->h),
2108 Str("cossegr: not initialised (arate)\n"));
2109 }
2110
2111
2112 #if 0
2113 int32_t cossegr(CSOUND *csound, COSSEG *p)
2114 {
2115 double val1 = p->y1, val2 = p->y2, x = p->x;
2116 MYFLT *rs = p->rslt;
2117 uint32_t offset = p->h.insdshead->ksmps_offset;
2118 uint32_t n, nsmps = CS_KSMPS;
2119 double inc = p->inc/(nsmps-offset);
2120
2121 memset(rs, '\0', offset*sizeof(MYFLT));
2122 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1;
2123
2124 if (LIKELY(p->segsrem)) { /* if no more segs putk */
2125 SEG *segp = p->cursegp;
2126 if (p->h.insdshead->relesing && p->segsrem > 1) {
2127 while (p->segsrem > 1) { /* release flag new: */
2128 segp = ++p->cursegp; /* go to last segment */
2129 p->segsrem--;
2130 } /* get univ relestim */
2131 segp->cnt = p->xtra >=0 ? p->xtra : p->h.insdshead->xtratim;
2132 goto newi; /* and set new curinc */
2133 }
2134 if (--p->curcnt <= 0) { /* if done cur segment */
2135 chk1:
2136 p->y1 = val1 = val2;
2137 if (UNLIKELY(!--p->segsrem)) { /* if none left */
2138 p->y2 = val2 = segp->nxtpt;
2139 goto putk; /* put endval */
2140 }
2141 newi:
2142 //printf("new seg: %d %f\n", segp->cnt, segp->nxtpt);
2143 val2 = p->y2 = segp->nxtpt; /* Base of next segment */
2144 p->inc = (segp->cnt ? 1.0/(segp->cnt) : 0.0);
2145 inc /= nsmps;
2146 x = 0.0;
2147 p->cursegp = segp+1; /* else find the next */
2148 if (UNLIKELY(!(p->curcnt = segp->cnt))) {
2149 val2 = p->y2 = segp->nxtpt; /* nonlen = discontin */
2150 p->inc = (segp->cnt ? 1.0/(segp->cnt) : 0.0);
2151 inc /= nsmps;
2152 //printf("zero length: incx, y1,y2 = %f, %f, %f\n", inc, val1, val2);
2153 goto chk1;
2154 } /* poslen = new slope */
2155 //printf("New segment incx, y1,y2 = %g, %f, %f\n", inc, val1, val2);
2156 }
2157 for (n=offset; n<nsmps; n++) {
2158 double mu2 = (1.0-cos(x*PI))*0.5;
2159 rs[n] = (MYFLT)(val1*(1.0-mu2)+val2*mu2);
2160 x += inc;
2161 //if (x>1 || x<0) printf("x=%f out of range\n", x);
2162 }
2163 }
2164 else {
2165 putk:
2166 //printf("ending at %f\n", val1);
2167 for (n=offset; n<nsmps; n++) {
2168 rs[n] = (MYFLT)val1;
2169 }
2170 }
2171 p->x = x;
2172 return OK;
2173 err1:
2174 return csound->PerfError(csound, &(p->h),
2175 Str("cossegr: not initialised (arate)\n"));
2176 }
2177 #endif
2178
kcssegr(CSOUND * csound,COSSEG * p)2179 int32_t kcssegr(CSOUND *csound, COSSEG *p)
2180 {
2181 double val1 = p->y1, val2 = p->y2, x = p->x, val = p->val;
2182 double inc = p->inc;
2183
2184 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1; /* RWD fix */
2185
2186 if (LIKELY(p->segsrem)) { /* if no more segs putk */
2187 SEG *segp = p->cursegp;
2188 if (p->h.insdshead->relesing && p->segsrem > 1) {
2189 while (p->segsrem > 1) { /* reles flag new: */
2190 segp = ++p->cursegp; /* go to last segment */
2191 p->segsrem--;
2192 }
2193 segp--; /* get univ relestim */
2194 segp->cnt = p->xtra>= 0 ? p->xtra : p->h.insdshead->xtratim;
2195 p->y1 = val1 = val;
2196 goto newi; /* and set new curinc */
2197 }
2198 if (p->segsrem == 1 && !p->h.insdshead->relesing) {
2199 goto putk;
2200 }
2201 if (--p->curcnt <= 0) { /* if done cur segment */
2202 chk1:
2203 p->y1 = val1 = val2;
2204 if (UNLIKELY(!--p->segsrem)) { /* if none left */
2205 p->y2 = val2 = segp->nxtpt;
2206 goto putk; /* put endval */
2207 }
2208 newi:
2209 val2 = p->y2 = segp->nxtpt; /* Base of next segment */
2210 inc = p->inc = (segp->cnt ? 1.0/(segp->cnt) : 0.0);
2211 x = 0.0;
2212 p->cursegp = segp+1; /* else find the next */
2213 if (UNLIKELY(!(p->curcnt = segp->cnt))) {
2214 val2 = p->y2 = segp->nxtpt; /* nonlen = discontin */
2215 inc = p->inc = (segp->cnt ? 1.0/(segp->cnt) : 0.0);
2216 goto chk1;
2217 } /* poslen = new slope */
2218 }
2219 {
2220 double mu2 = (1.0-cos(x*PI))*0.5;
2221 val = *p->rslt = (MYFLT)(val1*(1.0-mu2)+val2*mu2);
2222 x += inc;
2223 }
2224 }
2225 else {
2226 putk:
2227 *p->rslt = (MYFLT)val1;
2228 }
2229 p->x = x;
2230 p->val = val;
2231 return OK;
2232 err1:
2233 return csound->InitError(csound, Str("cosseg not initialised (krate)\n"));
2234 }
2235