1 /*
2 ugens3.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" /* UGENS3.C */
25 #include "ugens3.h"
26 #include <math.h>
27
foscset(CSOUND * csound,FOSC * p)28 int32_t foscset(CSOUND *csound, FOSC *p)
29 {
30 FUNC *ftp;
31
32 if (LIKELY((ftp = csound->FTFind(csound, p->ifn)) != NULL)) {
33 p->ftp = ftp;
34 if (*p->iphs >= 0)
35 p->cphs = p->mphs = (int32_t)(*p->iphs * FMAXLEN);
36 p->ampcod = IS_ASIG_ARG(p->xamp) ? 1 : 0;
37 p->carcod = IS_ASIG_ARG(p->xcar) ? 1 : 0;
38 p->modcod = IS_ASIG_ARG(p->xmod) ? 1 : 0;
39 return OK;
40 }
41 return NOTOK;
42 }
43
foscil(CSOUND * csound,FOSC * p)44 int32_t foscil(CSOUND *csound, FOSC *p)
45 {
46 FUNC *ftp;
47 MYFLT *ar, *ampp, *modp, cps, amp;
48 MYFLT xcar, xmod, *carp, car, fmod, cfreq, mod, ndx, *ftab;
49 int32_t mphs, cphs, minc, cinc, lobits;
50 uint32_t offset = p->h.insdshead->ksmps_offset;
51 uint32_t early = p->h.insdshead->ksmps_no_end;
52 uint32_t n, nsmps = CS_KSMPS;
53 MYFLT sicvt = csound->sicvt;
54
55 ar = p->rslt;
56 ftp = p->ftp;
57 if (UNLIKELY(ftp == NULL)) goto err1;
58 ftab = ftp->ftable;
59 lobits = ftp->lobits;
60 mphs = p->mphs;
61 cphs = p->cphs;
62 ampp = p->xamp;
63 cps = *p->kcps;
64 carp = p->xcar;
65 modp = p->xmod;
66 amp = *ampp;
67 xcar = *carp;
68 xmod = *modp;
69 if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
70 if (UNLIKELY(early)) {
71 nsmps -= early;
72 memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
73 }
74
75 if (p->ampcod || p->carcod || p->modcod) {
76 for (n=offset;n<nsmps;n++) {
77 if (p->ampcod) amp = ampp[n];
78 if (p->carcod) xcar = carp[n];
79 if (p->modcod) xmod = modp[n];
80 car = cps * xcar;
81 mod = cps * xmod;
82 ndx = *p->kndx * mod;
83 minc = (int32_t)(mod * sicvt);
84 mphs &= PHMASK;
85 fmod = *(ftab + (mphs >>lobits)) * ndx;
86 mphs += minc;
87 cfreq = car + fmod;
88 cinc = (int32_t)(cfreq * sicvt);
89 cphs &= PHMASK;
90 ar[n] = *(ftab + (cphs >>lobits)) * amp;
91 cphs += cinc;
92 }
93 }
94 else {
95 MYFLT amp = *ampp;
96 cps = *p->kcps;
97 car = cps * *carp;
98 mod = cps * *modp;
99 ndx = *p->kndx * mod;
100 minc = (int32_t)(mod * sicvt);
101 for (n=offset;n<nsmps;n++) {
102 mphs &= PHMASK;
103 fmod = *(ftab + (mphs >>lobits)) * ndx;
104 mphs += minc;
105 cfreq = car + fmod;
106 cinc = (int32_t)(cfreq * sicvt);
107 cphs &= PHMASK;
108 ar[n] = *(ftab + (cphs >>lobits)) * amp;
109 cphs += cinc;
110 }
111 }
112 p->mphs = mphs;
113 p->cphs = cphs;
114
115 return OK;
116 err1:
117 return csound->PerfError(csound, &(p->h),
118 Str("foscil: not initialised"));
119 }
120
foscili(CSOUND * csound,FOSC * p)121 int32_t foscili(CSOUND *csound, FOSC *p)
122 {
123 FUNC *ftp;
124 MYFLT *ar, *ampp, amp, cps, fract, v1, car, fmod, cfreq, mod;
125 MYFLT *carp, *modp, xcar, xmod, ndx, *ftab;
126 int32_t mphs, cphs, minc, cinc, lobits;
127 uint32_t offset = p->h.insdshead->ksmps_offset;
128 uint32_t early = p->h.insdshead->ksmps_no_end;
129 uint32_t n, nsmps = CS_KSMPS;
130 MYFLT sicvt = csound->sicvt;
131 MYFLT *ft;
132
133 ar = p->rslt;
134 ftp = p->ftp;
135 if (UNLIKELY(ftp == NULL)) goto err1; /* RWD fix */
136 ft = ftp->ftable;
137 lobits = ftp->lobits;
138 mphs = p->mphs;
139 cphs = p->cphs;
140 ampp = p->xamp;
141 cps = *p->kcps;
142 carp = p->xcar;
143 modp = p->xmod;
144 amp = *ampp;
145 xcar = *carp;
146 xmod = *modp;
147 if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
148 if (UNLIKELY(early)) {
149 nsmps -= early;
150 memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
151 }
152 if (p->ampcod || p->carcod || p->modcod) {
153 for (n=offset;n<nsmps;n++) {
154 if (p->ampcod) amp = ampp[n];
155 if (p->carcod) xcar = carp[n];
156 if (p->modcod) xmod = modp[n];
157 car = cps * xcar;
158 mod = cps * xmod;
159 ndx = *p->kndx * mod;
160 minc = (int32_t)(mod * sicvt);
161 mphs &= PHMASK;
162 fract = PFRAC(mphs);
163 ftab = ft + (mphs >>lobits);
164 v1 = *ftab++;
165 fmod = (v1 + (*ftab - v1) * fract) * ndx;
166 mphs += minc;
167 cfreq = car + fmod;
168 cinc = (int32_t)(cfreq * sicvt);
169 cphs &= PHMASK;
170 fract = PFRAC(cphs);
171 ftab = ft + (cphs >>lobits);
172 v1 = *ftab++;
173 ar[n] = (v1 + (*ftab - v1) * fract) * amp;
174 cphs += cinc;
175 }
176 }
177 else {
178 cps = *p->kcps;
179 car = cps * *carp;
180 mod = cps * *modp;
181 ndx = *p->kndx * mod;
182 minc = (int32_t)(mod * sicvt);
183 for (n=offset;n<nsmps;n++) {
184 mphs &= PHMASK;
185 fract = PFRAC(mphs);
186 ftab = ft + (mphs >>lobits);
187 v1 = *ftab++;
188 fmod = (v1 + (*ftab - v1) * fract) * ndx;
189 mphs += minc;
190 cfreq = car + fmod;
191 cinc = (int32_t)(cfreq * sicvt);
192 cphs &= PHMASK;
193 fract = PFRAC(cphs);
194 ftab = ft + (cphs >>lobits);
195 v1 = *ftab++;
196 ar[n] = (v1 + (*ftab - v1) * fract) * amp;
197 cphs += cinc;
198 }
199 }
200 p->mphs = mphs;
201 p->cphs = cphs;
202
203 return OK;
204 err1:
205 return csound->PerfError(csound, &(p->h),
206 Str("foscili: not initialised"));
207 }
208
209
losset(CSOUND * csound,LOSC * p)210 int32_t losset(CSOUND *csound, LOSC *p)
211 {
212 FUNC *ftp;
213 if ((ftp = csound->FTnp2Finde(csound,p->ifn)) != NULL) {
214 uint32 maxphs = ftp->flenfrms;
215 //printf("****maxphs = %d (%x)\n", maxphs, maxphs);
216 //printf("****ftp cvtbas = %g ibas = %g\n", ftp->cvtbas, *p->ibas);
217 p->ftp = ftp;
218 if (*p->ibas != FL(0.0))
219 p->cpscvt = (ftp->cvtbas / *p->ibas)/LOFACT;
220 else if (UNLIKELY((p->cpscvt = ftp->cpscvt) == FL(0.0))) {
221 p->cpscvt = FL(1.0) /FL(261.62556530059862592); /* Middle C */
222 csound->Warning(csound, Str("no legal base frequency"));
223 }
224 else p->cpscvt /= LOFACT;
225 //printf("****cpscvt = %g\n", p->cpscvt);
226 if ((p->mod1 = (int16) *p->imod1) < 0) {
227 if (UNLIKELY((p->mod1 = ftp->loopmode1) == 0)) {
228 csound->Warning(csound, Str("loscil: sustain defers to "
229 "non-looping source"));
230 }
231 p->beg1 = ftp->begin1;
232 p->end1 = ftp->end1;
233 }
234 else if (UNLIKELY(p->mod1 < 0 || p->mod1 > 3))
235 goto lerr2;
236 else {
237 p->beg1 = *p->ibeg1;
238 p->end1 = *p->iend1;
239 if (!p->beg1 && !p->end1)
240 /* default to looping the whole sample */
241 p->end1 = /* These are the same!! */
242 (p->mod1 ? (MYFLT)maxphs : (MYFLT)ftp->flenfrms);
243 else if (UNLIKELY(p->beg1 < 0 ||
244 p->end1 > maxphs ||
245 p->beg1 >= p->end1)) {
246 csound->Message(csound, "beg: %g, end = %g, maxphs = %d\n",
247 p->beg1, p->end1, maxphs);
248 goto lerr2;
249 }
250 }
251 if ((p->mod2 = (int16) *p->imod2) < 0) {
252 p->mod2 = ftp->loopmode2;
253 p->beg2 = ftp->begin2;
254 p->end2 = ftp->end2;
255 }
256 else {
257 p->beg2 = *p->ibeg2;
258 p->end2 = *p->iend2;
259 if (UNLIKELY(p->mod2 < 0 || p->mod2 > 3 ||
260 p->beg2 < 0 || p->end2 > (int32_t)maxphs ||
261 p->beg2 >= p->end2)) {
262 goto lerr3;
263 }
264 }
265 p->beg1 = (p->beg1 >= 0L ? p->beg1 : 0L);
266 p->end1 = (p->end1 < (int32_t)maxphs ? p->end1 : (int32_t)maxphs);
267 if (UNLIKELY(p->beg1 >= p->end1)) {
268 p->mod1 = 0;
269 p->beg1 = 0L;
270 p->end1 = maxphs;
271 }
272 p->beg2 = (p->beg2 >= 0L ? p->beg2 : 0L);
273 p->end2 = (p->end2 < (int32_t)maxphs ? p->end2 : (int32_t)maxphs);
274 if (UNLIKELY(p->beg2 >= p->end2)) {
275 p->mod2 = 0;
276 p->beg2 = 0L;
277 }
278 if (!p->mod2 && !p->end2) /* if no release looping */
279 p->end2 = maxphs; /* set a reading limit */
280 p->lphs = 0;
281 p->seg1 = 1;
282 if ((p->curmod = p->mod1))
283 p->looping = 1;
284 else p->looping = 0;
285 if (p->OUTOCOUNT == 1) {
286 p->stereo = 0;
287 if (UNLIKELY(ftp->nchanls != 1))
288 return csound->InitError(csound, Str(
289 "mono loscil cannot read from stereo ftable"));
290 }
291 else {
292 p->stereo = 1;
293 if (UNLIKELY(ftp->nchanls != 2))
294 return csound->InitError(csound, Str(
295 "stereo loscil cannot read from mono ftable"));
296 }
297 return OK;
298 }
299 return NOTOK;
300
301 lerr2:
302 return csound->InitError(csound, Str("illegal sustain loop data"));
303 lerr3:
304 return csound->InitError(csound, Str("illegal release loop data"));
305 }
306
losset_phs(CSOUND * csound,LOSCPHS * p)307 int32_t losset_phs(CSOUND *csound, LOSCPHS *p)
308 {
309 FUNC *ftp;
310 if ((ftp = csound->FTnp2Finde(csound,p->ifn)) != NULL) {
311 uint32 maxphs = ftp->flenfrms;
312 //printf("****maxphs = %d (%x)\n", maxphs, maxphs);
313 p->ftp = ftp;
314 if (*p->ibas != FL(0.0))
315 p->cpscvt = (ftp->cvtbas / *p->ibas)/LOFACT;
316 else if (UNLIKELY((p->cpscvt = ftp->cpscvt) == FL(0.0))) {
317 p->cpscvt = FL(1.0) /FL(261.62556530059862592); /* Middle C */
318 csound->Warning(csound, Str("no legal base frequency"));
319 }
320 else p->cpscvt /= LOFACT;
321 //printf("****cpscvt = %g\n", p->cpscvt);
322 if ((p->mod1 = (int16) *p->imod1) < 0) {
323 if (UNLIKELY((p->mod1 = ftp->loopmode1) == 0)) {
324 csound->Warning(csound, Str("loscil: sustain defers to "
325 "non-looping source"));
326 }
327 p->beg1 = ftp->begin1;
328 p->end1 = ftp->end1;
329 }
330 else if (UNLIKELY(p->mod1 < 0 || p->mod1 > 3))
331 goto lerr2;
332 else {
333 p->beg1 = *p->ibeg1;
334 p->end1 = *p->iend1;
335 if (!p->beg1 && !p->end1)
336 /* default to looping the whole sample */
337 p->end1 = /* These are the same!! */
338 (p->mod1 ? (MYFLT)maxphs : (MYFLT)ftp->flenfrms);
339 else if (UNLIKELY(p->beg1 < 0 ||
340 p->end1 > maxphs ||
341 p->beg1 >= p->end1)) {
342 csound->Message(csound, "beg: %g, end = %g, maxphs = %d\n",
343 p->beg1, p->end1, maxphs);
344 goto lerr2;
345 }
346 }
347 if ((p->mod2 = (int16) *p->imod2) < 0) {
348 p->mod2 = ftp->loopmode2;
349 p->beg2 = ftp->begin2;
350 p->end2 = ftp->end2;
351 }
352 else {
353 p->beg2 = *p->ibeg2;
354 p->end2 = *p->iend2;
355 if (UNLIKELY(p->mod2 < 0 || p->mod2 > 3 ||
356 p->beg2 < 0 || p->end2 > (int32_t)maxphs ||
357 p->beg2 >= p->end2)) {
358 goto lerr3;
359 }
360 }
361 p->beg1 = (p->beg1 >= 0L ? p->beg1 : 0L);
362 p->end1 = (p->end1 < (int32_t)maxphs ? p->end1 : (int32_t)maxphs);
363 if (UNLIKELY(p->beg1 >= p->end1)) {
364 p->mod1 = 0;
365 p->beg1 = 0L;
366 p->end1 = maxphs;
367 }
368 p->beg2 = (p->beg2 >= 0L ? p->beg2 : 0L);
369 p->end2 = (p->end2 < (int32_t)maxphs ? p->end2 : (int32_t)maxphs);
370 if (UNLIKELY(p->beg2 >= p->end2)) {
371 p->mod2 = 0;
372 p->beg2 = 0L;
373 }
374 if (!p->mod2 && !p->end2) /* if no release looping */
375 p->end2 = maxphs; /* set a reading limit */
376 p->lphs = 0;
377 p->seg1 = 1;
378 if ((p->curmod = p->mod1))
379 p->looping = 1;
380 else p->looping = 0;
381 if (p->OUTOCOUNT == 2) {
382 p->stereo = 0;
383 if (UNLIKELY(ftp->nchanls != 1))
384 return csound->InitError(csound, Str(
385 "mono loscilphs cannot read from stereo ftable"));
386 }
387 else if (p->OUTOCOUNT == 3)
388 {
389 p->stereo = 1;
390 if (UNLIKELY(ftp->nchanls != 2))
391 return csound->InitError(csound, Str(
392 "stereo loscilphs cannot read from mono ftable"));
393 }
394 else {
395 return csound->InitError(csound, Str(
396 "loscilphs: insufficient outputs"));
397 }
398 return OK;
399 }
400 return NOTOK;
401
402 lerr2:
403 return csound->InitError(csound, Str("illegal sustain loop data"));
404 lerr3:
405 return csound->InitError(csound, Str("illegal release loop data"));
406 }
407
loscil_linear_interp_mono(MYFLT * ar,MYFLT * ftbl,MYFLT phs,int32_t flen)408 static inline void loscil_linear_interp_mono(MYFLT *ar,
409 MYFLT *ftbl, MYFLT phs, int32_t flen)
410 {
411 MYFLT fract, tmp;
412 int32_t x;
413
414 fract = MODF(phs, &tmp);
415 x = (int32_t) tmp;
416 //printf("phs=%d+%f\n",x, fract);
417 tmp = ftbl[x];
418 x = (x < flen ? (x + 1) : flen);
419 *ar = tmp + ((ftbl[x] - tmp) * fract);
420 }
421
loscil_linear_interp_stereo(MYFLT * arL,MYFLT * arR,MYFLT * ftbl,MYFLT phs,int32_t flen)422 static inline void loscil_linear_interp_stereo(MYFLT *arL, MYFLT *arR,
423 MYFLT *ftbl, MYFLT phs, int32_t flen)
424 {
425 MYFLT fract, tmpL, tmpR;
426 int x;
427
428 fract = MODF(phs, &tmpL);
429 x = (int32_t) 2*tmpL;
430 //printf("phs=%d+%f\n",x, fract);
431 tmpL = ftbl[x];
432 tmpR = ftbl[x + 1];
433 x = (x < ((int32_t) flen - 1) ? (x + 2) : ((int32_t) flen - 1));
434 *arL = tmpL + ((ftbl[x] - tmpL) * fract);
435 *arR = tmpR + ((ftbl[x + 1] - tmpR) * fract);
436 }
437
loscil_cubic_interp_mono(MYFLT * ar,MYFLT * ftbl,MYFLT phs,int32_t flen)438 static inline void loscil_cubic_interp_mono(MYFLT *ar,
439 MYFLT *ftbl, MYFLT phs, int32_t flen)
440 {
441 MYFLT fract, tmp, a0, a1, a2, a3;
442 int32_t x;
443
444 fract = MODF(phs, &tmp);
445 x = (int32_t) tmp;
446 //printf("phs=%d+%f\n",x, fract);
447 a3 = fract * fract; a3 -= FL(1.0); a3 *= (FL(1.0) / FL(6.0));
448 a2 = fract; a2 += FL(1.0); a0 = (a2 *= FL(0.5)); a0 -= FL(1.0);
449 a1 = FL(3.0) * a3; a2 -= a1; a0 -= a3; a1 -= fract;
450 a0 *= fract; a1 *= fract; a2 *= fract; a3 *= fract; a1 += FL(1.0);
451 tmp = ftbl[(x >= 0 ? x : 0)] * a0;
452 tmp += ftbl[++x] * a1;
453 x++;
454 tmp += ftbl[(x < (int32_t) flen ? x : (int32_t) flen)] * a2;
455 x++;
456 tmp += ftbl[(x < (int32_t) flen ? x : (int32_t) flen)] * a3;
457 *ar = tmp;
458 }
459
460 static CS_NOINLINE void
loscil_cubic_interp_stereo(MYFLT * arL,MYFLT * arR,MYFLT * ftbl,MYFLT phs,int32_t flen)461 loscil_cubic_interp_stereo(MYFLT *arL, MYFLT *arR,
462 MYFLT *ftbl, MYFLT phs, int32_t flen)
463 {
464 MYFLT fract, tmpL, tmpR, a0, a1, a2, a3;
465 int32_t x;
466
467 fract = MODF(phs, &tmpL);
468 x = (int32_t) 2*tmpL;
469 //printf("phs=%d+%f\n",x, fract);
470 a3 = fract * fract; a3 -= FL(1.0); a3 *= (FL(1.0) / FL(6.0));
471 a2 = fract; a2 += FL(1.0); a0 = (a2 *= FL(0.5)); a0 -= FL(1.0);
472 a1 = FL(3.0) * a3; a2 -= a1; a0 -= a3; a1 -= fract;
473 a0 *= fract; a1 *= fract; a2 *= fract; a3 *= fract; a1 += FL(1.0);
474 tmpL = ftbl[(x >= 0 ? x : 0)] * a0;
475 tmpR = ftbl[(x >= 0 ? (x + 1) : 1)] * a0;
476 x += 2;
477 tmpL += ftbl[x] * a1;
478 tmpR += ftbl[x + 1] * a1;
479 x = (x < ((int32_t) flen - 1) ? (x + 2) : ((int32_t) flen - 1));
480 tmpL += ftbl[x] * a2;
481 tmpR += ftbl[x + 1] * a2;
482 x = (x < ((int32_t) flen - 1) ? (x + 2) : ((int32_t) flen - 1));
483 tmpL += ftbl[x] * a3;
484 tmpR += ftbl[x + 1] * a3;
485 *arL = tmpL;
486 *arR = tmpR;
487 }
488
489 /* *********************** needs total rewrite **************** */
loscil(CSOUND * csound,LOSC * p)490 int32_t loscil(CSOUND *csound, LOSC *p)
491 {
492 IGN(csound);
493 FUNC *ftp;
494 MYFLT *ar1, *ar2, *ftbl, *xamp;
495 MYFLT phs;
496 MYFLT inc, beg, end;
497 uint32_t n = p->h.insdshead->ksmps_offset;
498 uint32_t early = p->h.insdshead->ksmps_no_end;
499 uint32_t nsmps = CS_KSMPS;
500 int32_t aamp;
501 MYFLT xx;
502
503 ftp = p->ftp;
504 ftbl = ftp->ftable;
505 if ((inc = (*p->kcps * p->cpscvt)) < 0)
506 inc = -inc;
507 //printf("inc: %lf * %lf = %lf\n", *p->kcps, p->cpscvt, inc);
508 xamp = p->xamp;
509 xx = *xamp;
510 aamp = IS_ASIG_ARG(p->xamp) ? 1 : 0;
511 if (p->seg1) { /* if still segment 1 */
512 beg = p->beg1;
513 end = p->end1;
514 if (UNLIKELY(p->h.insdshead->relesing)) /* sense note_off */
515 p->looping = 0;
516 }
517 else {
518 beg = p->beg2;
519 end = p->end2;
520 }
521 phs = p->lphs;
522 ar1 = p->ar1;
523 if (UNLIKELY(n)) memset(ar1, '\0', n*sizeof(MYFLT));
524 if (UNLIKELY(early)) {
525 nsmps -= early;
526 memset(&ar1[nsmps], '\0', early*sizeof(MYFLT));
527 }
528 if (p->stereo) {
529 ar2 = p->ar2;
530 if (UNLIKELY(n)) memset(ar2, '\0', n*sizeof(MYFLT));
531 if (UNLIKELY(early)) memset(&ar2[nsmps], '\0', early*sizeof(MYFLT));
532 goto phsck2;
533 }
534 phschk:
535 if (phs >= end && p->curmod != 3) {
536 //printf("****phs = %f end = %f\n", phs,end);
537 goto put0;
538 }
539 switch (p->curmod) {
540 case 0:
541 for (; n<nsmps; n++) { /* NO LOOPING */
542 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
543 if (aamp) xx = xamp[n];
544 ar1[n] *= xx;
545 if ((phs += inc) >= end) {
546 //printf("****phs, end = %f, %f\n", phs, end);
547 goto nxtseg;
548 }
549 }
550 break;
551 case 1:
552 for (; n<nsmps; n++) { /* NORMAL LOOPING */
553 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
554 if (aamp) xx = xamp[n];
555 ar1[n] *= xx;
556 if (UNLIKELY((phs += inc) >= end)) {
557 if (!(p->looping)) goto nxtseg;
558 phs -= end - beg;
559 }
560 }
561 break;
562 case 2:
563 case2:
564 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
565 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
566 if (aamp) xx = xamp[n];
567 ar1[n] *= xx;
568 if ((phs += inc) >= end) {
569 if (!(p->looping)) goto nxtseg;
570 phs -= (phs - end) * 2;
571 p->curmod = 3;
572 if (++n<nsmps) goto case3;
573 else break;
574 }
575 }
576 break;
577 case 3:
578 case3:
579 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
580 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
581 if (aamp) xx = xamp[n];
582 ar1[n] *= xx;
583 if (UNLIKELY((phs -= inc) < beg)) {
584 phs += (beg - phs) * 2;
585 p->curmod = 2;
586 if (++n<nsmps) goto case2;
587 else break;
588 }
589 }
590 break;
591
592 nxtseg:
593 if (p->seg1) {
594 p->seg1 = 0;
595 if ((p->curmod = p->mod2) != 0)
596 p->looping = 1;
597 if (++n>nsmps) {
598 beg = p->beg2;
599 end = p->end2;
600 p->lphs = phs;
601 goto phschk;
602 }
603 break;
604 }
605 if (LIKELY(++n<nsmps)) goto phsout;
606 break;
607 }
608 p->lphs = phs;
609 return OK;
610
611 phsout:
612 p->lphs = phs;
613 put0:
614 //printf("****put0\n");
615 memset(&ar1[n], '\0', sizeof(MYFLT)*(nsmps-n));
616 return OK;
617
618 phsck2:
619 /*VL increment for stereo */
620 if (phs >= end && p->curmod != 3)
621 goto put0s; /* for STEREO: */
622 switch (p->curmod) {
623 case 0:
624 for (; n<nsmps; n++) { /* NO LOOPING */
625 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
626 if (aamp) xx = xamp[n];
627 ar1[n] *= xx;
628 ar2[n] *= xx;
629 if (UNLIKELY((phs += inc) >= end))
630 goto nxtseg2;
631 }
632 break;
633 case 1:
634 for (; n<nsmps; n++) { /* NORMAL LOOPING */
635 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
636 if (aamp) xx = xamp[n];
637 ar1[n] *= xx;
638 ar2[n] *= xx;
639 if (UNLIKELY((phs += inc) >= end)) {
640 if (!(p->looping)) goto nxtseg2;
641 phs -= end - beg;
642 }
643 }
644 break;
645 case 2:
646 case2s:
647 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
648 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
649 if (aamp) xx = xamp[n];
650 ar1[n] *= xx;
651 ar2[n] *= xx;
652 if (UNLIKELY((phs += inc) >= end)) {
653 if (!(p->looping)) goto nxtseg2;
654 phs -= (phs - end) * 2;
655 p->curmod = 3;
656 if (++n<nsmps) goto case3s;
657 else break;
658 }
659 }
660 break;
661 case 3:
662 case3s:
663 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
664 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
665 if (aamp) xx = xamp[n];
666 ar1[n] *= xx;
667 ar2[n] *= xx;
668 if (UNLIKELY((phs -= inc) < beg)) {
669 phs += (beg - phs) * 2;
670 p->curmod = 2;
671 if (++n<nsmps) goto case2s;
672 else break;
673 }
674 }
675 break;
676
677 nxtseg2:
678 if (p->seg1) {
679 p->seg1 = 0;
680 if ((p->curmod = p->mod2) != 0)
681 p->looping = 1;
682 if (++n<nsmps) {
683 beg = p->beg2;
684 end = p->end2;
685 p->lphs = phs;
686 goto phsck2;
687 }
688 break;
689 }
690 if (LIKELY(++n<nsmps)) goto phsout2;
691 break;
692 }
693 p->lphs = phs;
694 return OK;
695
696 phsout2:
697 p->lphs = phs;
698 put0s:
699 memset(&ar1[n], '\0', sizeof(MYFLT)*(nsmps-n));
700 memset(&ar2[n], '\0', sizeof(MYFLT)*(nsmps-n));
701 return OK;
702 }
703
704
loscil_phs(CSOUND * csound,LOSCPHS * p)705 int32_t loscil_phs(CSOUND *csound, LOSCPHS *p)
706 {
707 IGN(csound);
708 FUNC *ftp;
709 MYFLT *ar1, *ar2, *ftbl, *xamp, *sphs;
710 MYFLT phs;
711 MYFLT inc, beg, end;
712 uint32_t n = p->h.insdshead->ksmps_offset;
713 uint32_t early = p->h.insdshead->ksmps_no_end;
714 uint32_t nsmps = CS_KSMPS;
715 int32_t aamp;
716 MYFLT xx;
717
718 ftp = p->ftp;
719 ftbl = ftp->ftable;
720 if ((inc = (*p->kcps * p->cpscvt)) < 0)
721 inc = -inc;
722 xamp = p->xamp;
723 xx = *xamp;
724 aamp = IS_ASIG_ARG(p->xamp) ? 1 : 0;
725 if (p->seg1) { /* if still segment 1 */
726 beg = p->beg1;
727 end = p->end1;
728 if (UNLIKELY(p->h.insdshead->relesing)) /* sense note_off */
729 p->looping = 0;
730 }
731 else {
732 beg = p->beg2;
733 end = p->end2;
734 }
735 phs = p->lphs;
736 ar1 = p->ar1;
737 sphs = p->sphs;
738 if (UNLIKELY(n)) memset(ar1, '\0', n*sizeof(MYFLT));
739 if (UNLIKELY(early)) {
740 nsmps -= early;
741 memset(&ar1[nsmps], '\0', early*sizeof(MYFLT));
742 memset(&sphs[nsmps], '\0', early*sizeof(MYFLT));
743 }
744 if (p->stereo) {
745 ar2 = p->ar2;
746 if (UNLIKELY(n)) memset(ar2, '\0', n*sizeof(MYFLT));
747 if (UNLIKELY(early)) memset(&ar2[nsmps], '\0', early*sizeof(MYFLT));
748 goto phsck2;
749 }
750 phschk:
751 if (phs >= end && p->curmod != 3) {
752 //printf("****phs = %f end = %d\n", phs,end);
753 goto put0;
754 }
755 switch (p->curmod) {
756 case 0:
757 for (; n<nsmps; n++) { /* NO LOOPING */
758 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
759 if (aamp) xx = xamp[n];
760 ar1[n] *= xx;
761 sphs[n] = phs/ftp->flen;
762 if ((phs += inc) >= end) {
763 //printf("****phs, end = %f, %d\n", phs, end);
764 goto nxtseg;
765 }
766 }
767 break;
768 case 1:
769 for (; n<nsmps; n++) { /* NORMAL LOOPING */
770 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
771 if (aamp) xx = xamp[n];
772 ar1[n] *= xx;
773 sphs[n] = phs/ftp->flen;
774 if (UNLIKELY((phs += inc) >= end)) {
775 if (!(p->looping)) goto nxtseg;
776 phs -= end - beg;
777 }
778 }
779 break;
780 case 2:
781 case2:
782 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
783 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
784 if (aamp) xx = xamp[n];
785 ar1[n] *= xx;
786 sphs[n] = phs/ftp->flen;
787 if ((phs += inc) >= end) {
788 if (!(p->looping)) goto nxtseg;
789 phs -= (phs - end) * 2;
790 p->curmod = 3;
791 if (++n<nsmps) goto case3;
792 else break;
793 }
794 }
795 break;
796 case 3:
797 case3:
798 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
799 loscil_linear_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
800 if (aamp) xx = xamp[n];
801 ar1[n] *= xx;
802 sphs[n] = phs/ftp->flen;
803 if (UNLIKELY((phs -= inc) < beg)) {
804 phs += (beg - phs) * 2;
805 p->curmod = 2;
806 if (++n<nsmps) goto case2;
807 else break;
808 }
809 }
810 break;
811
812 nxtseg:
813 if (p->seg1) {
814 p->seg1 = 0;
815 if ((p->curmod = p->mod2) != 0)
816 p->looping = 1;
817 if (++n>nsmps) {
818 beg = p->beg2;
819 end = p->end2;
820 p->lphs = phs;
821 goto phschk;
822 }
823 break;
824 }
825 if (LIKELY(++n<nsmps)) goto phsout;
826 break;
827 }
828 p->lphs = phs;
829 return OK;
830
831 phsout:
832 p->lphs = phs;
833 put0:
834 //printf("****put0\n");
835 memset(&ar1[n], '\0', sizeof(MYFLT)*(nsmps-n));
836 return OK;
837
838 phsck2:
839 if (phs >= end && p->curmod != 3)
840 goto put0s; /* for STEREO: */
841 switch (p->curmod) {
842 case 0:
843 for (; n<nsmps; n++) { /* NO LOOPING */
844 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
845 if (aamp) xx = xamp[n];
846 ar1[n] *= xx;
847 ar2[n] *= xx;
848 sphs[n] = phs/ftp->flen;
849 if (UNLIKELY((phs += inc) >= end))
850 goto nxtseg2;
851 }
852 break;
853 case 1:
854 for (; n<nsmps; n++) { /* NORMAL LOOPING */
855 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
856 if (aamp) xx = xamp[n];
857 ar1[n] *= xx;
858 ar2[n] *= xx;
859 sphs[n] = phs/ftp->flen;
860 if (UNLIKELY((phs += inc) >= end)) {
861 if (!(p->looping)) goto nxtseg2;
862 phs -= end - beg;
863 }
864 }
865 break;
866 case 2:
867 case2s:
868 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
869 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
870 if (aamp) xx = xamp[n];
871 ar1[n] *= xx;
872 ar2[n] *= xx;
873 sphs[n] = phs/ftp->flen;
874 if (UNLIKELY((phs += inc) >= end)) {
875 if (!(p->looping)) goto nxtseg2;
876 phs -= (phs - end) * 2;
877 p->curmod = 3;
878 if (++n<nsmps) goto case3s;
879 else break;
880 }
881 }
882 break;
883 case 3:
884 case3s:
885 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
886 loscil_linear_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
887 if (aamp) xx = xamp[n];
888 ar1[n] *= xx;
889 ar2[n] *= xx;
890 sphs[n] = phs/ftp->flen;
891 if (UNLIKELY((phs -= inc) < beg)) {
892 phs += (beg - phs) * 2;
893 p->curmod = 2;
894 if (++n<nsmps) goto case2s;
895 else break;
896 }
897 }
898 break;
899
900 nxtseg2:
901 if (p->seg1) {
902 p->seg1 = 0;
903 if ((p->curmod = p->mod2) != 0)
904 p->looping = 1;
905 if (++n<nsmps) {
906 beg = p->beg2;
907 end = p->end2;
908 p->lphs = phs;
909 goto phsck2;
910 }
911 break;
912 }
913 if (LIKELY(++n<nsmps)) goto phsout2;
914 break;
915 }
916 p->lphs = phs;
917 return OK;
918
919 phsout2:
920 p->lphs = phs;
921 put0s:
922 memset(&ar1[n], '\0', sizeof(MYFLT)*(nsmps-n));
923 memset(&ar2[n], '\0', sizeof(MYFLT)*(nsmps-n));
924 return OK;
925 }
926
927
928
loscil3_phs(CSOUND * csound,LOSCPHS * p)929 int32_t loscil3_phs(CSOUND *csound, LOSCPHS *p)
930 {
931 IGN(csound);
932 FUNC *ftp;
933 MYFLT *ar1, *ar2, *ftbl, *xamp, *sphs;
934 MYFLT phs;
935 MYFLT inc, beg, end;
936 uint32_t n = p->h.insdshead->ksmps_offset;
937 uint32_t early = p->h.insdshead->ksmps_no_end;
938 uint32_t nsmps = CS_KSMPS;
939 int32_t aamp;
940 MYFLT xx;
941
942 ftp = p->ftp;
943 ftbl = ftp->ftable;
944 if ((inc = (*p->kcps * p->cpscvt)) < 0)
945 inc = -inc;
946 xamp = p->xamp;
947 xx = *xamp;
948 aamp = IS_ASIG_ARG(p->xamp) ? 1 : 0;
949 if (p->seg1) { /* if still segment 1 */
950 beg = p->beg1;
951 end = p->end1;
952 if (p->h.insdshead->relesing) /* sense note_off */
953 p->looping = 0;
954 }
955 else {
956 beg = p->beg2;
957 end = p->end2;
958 }
959 phs = p->lphs;
960 ar1 = p->ar1;
961 sphs = p->sphs;
962 if (UNLIKELY(n)) memset(ar1, '\0', n*sizeof(MYFLT));
963 if (UNLIKELY(early)) {
964 nsmps -= early;
965 memset(&ar1[nsmps], '\0', early*sizeof(MYFLT));
966 memset(&sphs[nsmps], '\0', early*sizeof(MYFLT));
967 }
968 if (p->stereo) {
969 ar2 = p->ar2;
970 if (UNLIKELY(n)) memset(ar1, '\0', n*sizeof(MYFLT));
971 if (UNLIKELY(early)) memset(&ar2[nsmps], '\0', early*sizeof(MYFLT));
972 goto phsck2;
973 }
974 phschk:
975 if (UNLIKELY(phs >= end && p->curmod != 3))
976 goto put0;
977 switch (p->curmod) {
978 case 0:
979 for (; n<nsmps; n++) { /* NO LOOPING */
980 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
981 if (aamp) xx = xamp[n];
982 ar1[n] *= xx;
983 sphs[n] = phs/ftp->flen;
984 if (UNLIKELY((phs += inc) >= end))
985 goto nxtseg;
986 }
987 break;
988 case 1:
989 for (; n<nsmps; n++) { /* NORMAL LOOPING */
990 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
991 if (aamp) xx = xamp[n];
992 ar1[n] *= xx;
993 sphs[n] = phs/ftp->flen;
994 if (UNLIKELY((phs += inc) >= end)) {
995 if (!(p->looping)) goto nxtseg;
996 phs -= end - beg;
997 }
998 }
999 break;
1000 case 2:
1001 case2:
1002 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
1003 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
1004 if (aamp) xx = xamp[n];
1005 ar1[n] *= xx;
1006 sphs[n] = phs/ftp->flen;
1007 if (UNLIKELY((phs += inc) >= end)) {
1008 if (!(p->looping)) goto nxtseg;
1009 phs -= (phs - end) * 2;
1010 p->curmod = 3;
1011 if (++n<nsmps) goto case3;
1012 else break;
1013 }
1014 }
1015 break;
1016 case 3:
1017 case3:
1018 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
1019 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);;
1020 if (aamp) xx = xamp[n];
1021 ar1[n] *= xx;
1022 sphs[n] = phs/ftp->flen;
1023 if (UNLIKELY((phs -= inc) < beg)) {
1024 phs += (beg - phs) * 2;
1025 p->curmod = 2;
1026 if (++n<nsmps) goto case2;
1027 else break;
1028 }
1029 }
1030 break;
1031
1032 nxtseg:
1033 if (p->seg1) {
1034 p->seg1 = 0;
1035 if ((p->curmod = p->mod2) != 0)
1036 p->looping = 1;
1037 if (--nsmps) {
1038 beg = p->beg2;
1039 end = p->end2;
1040 p->lphs = phs;
1041 goto phschk;
1042 }
1043 break;
1044 }
1045 if (LIKELY(++n<nsmps)) goto phsout;
1046 break;
1047 }
1048 p->lphs = phs;
1049 return OK;
1050
1051 phsout:
1052 p->lphs = phs;
1053 put0:
1054 memset(&ar1[n], 0, sizeof(MYFLT)*(nsmps-n));
1055 /* do { */
1056 /* *ar1++ = FL(0.0); */
1057 /* } while (--nsmps); */
1058 return OK;
1059
1060 phsck2:
1061 if (UNLIKELY(phs >= end && p->curmod != 3))
1062 goto put0s; /* for STEREO: */
1063 switch (p->curmod) {
1064 case 0:
1065 for (; n<nsmps; n++) { /* NO LOOPING */
1066 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1067 if (aamp) xx = xamp[n];
1068 ar1[n] *= xx;
1069 ar2[n] *= xx;
1070 sphs[n] = phs/ftp->flen;
1071 if (UNLIKELY((phs += inc) >= end))
1072 goto nxtseg2;
1073 }
1074 break;
1075 case 1:
1076 for (; n<nsmps; n++) { /* NORMAL LOOPING */
1077 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1078 if (aamp) xx = xamp[n];
1079 ar1[n] *= xx;
1080 ar2[n] *= xx;
1081 sphs[n] = phs/ftp->flen;
1082 if (UNLIKELY((phs += inc) >= end)) {
1083 if (!(p->looping)) goto nxtseg2;
1084 phs -= end - beg;
1085 }
1086 }
1087 break;
1088 case 2:
1089 case2s:
1090 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
1091 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1092 if (aamp) xx = xamp[n];
1093 ar1[n] *= xx;
1094 ar2[n] *= xx;
1095 if (UNLIKELY((phs += inc) >= end)) {
1096 if (!(p->looping)) goto nxtseg2;
1097 phs -= (phs - end) * 2;
1098 p->curmod = 3;
1099 if (++n<nsmps) goto case3s;
1100 else break;
1101 }
1102 }
1103 break;
1104 case 3:
1105 case3s:
1106 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
1107 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1108 if (aamp) xx = xamp[n];
1109 ar1[n] *= xx;
1110 ar2[n] *= xx;
1111 sphs[n] = phs/ftp->flen;
1112 if (UNLIKELY((phs -= inc) < beg)) {
1113 phs += (beg - phs) * 2;
1114 p->curmod = 2;
1115 if (++n<nsmps) goto case2s;
1116 else break;
1117 }
1118 }
1119 break;
1120
1121 nxtseg2:
1122 if (p->seg1) {
1123 p->seg1 = 0;
1124 if ((p->curmod = p->mod2) != 0)
1125 p->looping = 1;
1126 if (++n<nsmps) {
1127 beg = p->beg2;
1128 end = p->end2;
1129 p->lphs = phs;
1130 goto phsck2;
1131 }
1132 break;
1133 }
1134 if (LIKELY(++n<nsmps)) goto phsout2;
1135 break;
1136 }
1137 p->lphs = phs;
1138 return OK;
1139
1140 phsout2:
1141 p->lphs = phs;
1142 put0s:
1143 memset(&ar1[n], '\0', sizeof(MYFLT)*(nsmps-n));
1144 memset(&ar2[n], '\0', sizeof(MYFLT)*(nsmps-n));
1145 return OK;
1146 }
1147
1148
loscil3(CSOUND * csound,LOSC * p)1149 int32_t loscil3(CSOUND *csound, LOSC *p)
1150 {
1151 IGN(csound);
1152 FUNC *ftp;
1153 MYFLT *ar1, *ar2, *ftbl, *xamp;
1154 MYFLT phs;
1155 MYFLT inc, beg, end;
1156 uint32_t n = p->h.insdshead->ksmps_offset;
1157 uint32_t early = p->h.insdshead->ksmps_no_end;
1158 uint32_t nsmps = CS_KSMPS;
1159 int32_t aamp;
1160 MYFLT xx;
1161
1162 ftp = p->ftp;
1163 ftbl = ftp->ftable;
1164 if ((inc = (*p->kcps * p->cpscvt)) < 0)
1165 inc = -inc;
1166 xamp = p->xamp;
1167 xx = *xamp;
1168 aamp = IS_ASIG_ARG(p->xamp) ? 1 : 0;
1169 if (p->seg1) { /* if still segment 1 */
1170 beg = p->beg1;
1171 end = p->end1;
1172 if (p->h.insdshead->relesing) /* sense note_off */
1173 p->looping = 0;
1174 }
1175 else {
1176 beg = p->beg2;
1177 end = p->end2;
1178 }
1179 phs = p->lphs;
1180 ar1 = p->ar1;
1181 if (UNLIKELY(n)) memset(ar1, '\0', n*sizeof(MYFLT));
1182 if (UNLIKELY(early)) {
1183 nsmps -= early;
1184 memset(&ar1[nsmps], '\0', early*sizeof(MYFLT));
1185 }
1186 if (p->stereo) {
1187 ar2 = p->ar2;
1188 if (UNLIKELY(n)) memset(ar1, '\0', n*sizeof(MYFLT));
1189 if (UNLIKELY(early)) memset(&ar2[nsmps], '\0', early*sizeof(MYFLT));
1190 goto phsck2;
1191 }
1192 phschk:
1193 if (UNLIKELY(phs >= end && p->curmod != 3))
1194 goto put0;
1195 switch (p->curmod) {
1196 case 0:
1197 for (; n<nsmps; n++) { /* NO LOOPING */
1198 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
1199 if (aamp) xx = xamp[n];
1200 ar1[n] *= xx;
1201 if (UNLIKELY((phs += inc) >= end))
1202 goto nxtseg;
1203 }
1204 break;
1205 case 1:
1206 for (; n<nsmps; n++) { /* NORMAL LOOPING */
1207 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
1208 if (aamp) xx = xamp[n];
1209 ar1[n] *= xx;
1210 if (UNLIKELY((phs += inc) >= end)) {
1211 if (!(p->looping)) goto nxtseg;
1212 phs -= end - beg;
1213 }
1214 }
1215 break;
1216 case 2:
1217 case2:
1218 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
1219 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);
1220 if (aamp) xx = xamp[n];
1221 ar1[n] *= xx;
1222 if (UNLIKELY((phs += inc) >= end)) {
1223 if (!(p->looping)) goto nxtseg;
1224 phs -= (phs - end) * 2;
1225 p->curmod = 3;
1226 if (++n<nsmps) goto case3;
1227 else break;
1228 }
1229 }
1230 break;
1231 case 3:
1232 case3:
1233 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
1234 loscil_cubic_interp_mono(&ar1[n], ftbl, phs, ftp->flen);;
1235 if (aamp) xx = xamp[n];
1236 ar1[n] *= xx;
1237 if (UNLIKELY((phs -= inc) < beg)) {
1238 phs += (beg - phs) * 2;
1239 p->curmod = 2;
1240 if (++n<nsmps) goto case2;
1241 else break;
1242 }
1243 }
1244 break;
1245
1246 nxtseg:
1247 if (p->seg1) {
1248 p->seg1 = 0;
1249 if ((p->curmod = p->mod2) != 0)
1250 p->looping = 1;
1251 if (--nsmps) {
1252 beg = p->beg2;
1253 end = p->end2;
1254 p->lphs = phs;
1255 goto phschk;
1256 }
1257 break;
1258 }
1259 if (LIKELY(++n<nsmps)) goto phsout;
1260 break;
1261 }
1262 p->lphs = phs;
1263 return OK;
1264
1265 phsout:
1266 p->lphs = phs;
1267 put0:
1268 memset(&ar1[n], 0, sizeof(MYFLT)*(nsmps-n));
1269 /* do { */
1270 /* *ar1++ = FL(0.0); */
1271 /* } while (--nsmps); */
1272 return OK;
1273
1274 phsck2:
1275 if (UNLIKELY(phs >= end && p->curmod != 3))
1276 goto put0s; /* for STEREO: */
1277 switch (p->curmod) {
1278 case 0:
1279 for (; n<nsmps; n++) { /* NO LOOPING */
1280 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1281 if (aamp) xx = xamp[n];
1282 ar1[n] *= xx;
1283 ar2[n] *= xx;
1284 if (UNLIKELY((phs += inc) >= end))
1285 goto nxtseg2;
1286 }
1287 break;
1288 case 1:
1289 for (; n<nsmps; n++) { /* NORMAL LOOPING */
1290 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1291 if (aamp) xx = xamp[n];
1292 ar1[n] *= xx;
1293 ar2[n] *= xx;
1294 if (UNLIKELY((phs += inc) >= end)) {
1295 if (!(p->looping)) goto nxtseg2;
1296 phs -= end - beg;
1297 }
1298 }
1299 break;
1300 case 2:
1301 case2s:
1302 for (; n<nsmps; n++) { /* BIDIR FORW, EVEN */
1303 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1304 if (aamp) xx = xamp[n];
1305 ar1[n] *= xx;
1306 ar2[n] *= xx;
1307 if (UNLIKELY((phs += inc) >= end)) {
1308 if (!(p->looping)) goto nxtseg2;
1309 phs -= (phs - end) * 2;
1310 p->curmod = 3;
1311 if (++n<nsmps) goto case3s;
1312 else break;
1313 }
1314 }
1315 break;
1316 case 3:
1317 case3s:
1318 for (; n<nsmps; n++) { /* BIDIR BACK, EVEN */
1319 loscil_cubic_interp_stereo(&ar1[n], &ar2[n], ftbl, phs, ftp->flen);
1320 if (aamp) xx = xamp[n];
1321 ar1[n] *= xx;
1322 ar2[n] *= xx;
1323 if (UNLIKELY((phs -= inc) < beg)) {
1324 phs += (beg - phs) * 2;
1325 p->curmod = 2;
1326 if (++n<nsmps) goto case2s;
1327 else break;
1328 }
1329 }
1330 break;
1331
1332 nxtseg2:
1333 if (p->seg1) {
1334 p->seg1 = 0;
1335 if ((p->curmod = p->mod2) != 0)
1336 p->looping = 1;
1337 if (++n<nsmps) {
1338 beg = p->beg2;
1339 end = p->end2;
1340 p->lphs = phs;
1341 goto phsck2;
1342 }
1343 break;
1344 }
1345 if (LIKELY(++n<nsmps)) goto phsout2;
1346 break;
1347 }
1348 p->lphs = phs;
1349 return OK;
1350
1351 phsout2:
1352 p->lphs = phs;
1353 put0s:
1354 memset(&ar1[n], '\0', sizeof(MYFLT)*(nsmps-n));
1355 memset(&ar2[n], '\0', sizeof(MYFLT)*(nsmps-n));
1356 return OK;
1357 }
1358
1359
1360
1361 #define ISINSIZ 32768L
1362 #define ADMASK 32767L
1363
adset_(CSOUND * csound,ADSYN * p,int32_t stringname)1364 static int32_t adset_(CSOUND *csound, ADSYN *p, int32_t stringname)
1365 {
1366 int32_t n;
1367 char filnam[MAXNAME];
1368 MEMFIL *mfp;
1369 int16 *adp, *endata, val;
1370 PTLPTR *ptlap, *ptlfp, *ptlim;
1371 int32_t size;
1372
1373 if (csound->isintab == NULL) { /* if no sin table yet, make one */
1374 int16 *ip;
1375 csound->isintab = ip =
1376 (int16*) csound->Malloc(csound, ISINSIZ * sizeof(int16));
1377 for (n = 0; n < ISINSIZ; n++)
1378 *ip++ = (int16) (sin(TWOPI * n / ISINSIZ) * 32767.0);
1379 }
1380 if (stringname) strNcpy(filnam, ((STRINGDAT*)p->ifilcod)->data, MAXNAME-1);
1381 else if (csound->ISSTRCOD(*p->ifilcod))
1382 strNcpy(filnam, get_arg_string(csound, *p->ifilcod), MAXNAME-1);
1383 else csound->strarg2name(csound, filnam, p->ifilcod, "adsyn.", 0);
1384
1385
1386 if ((mfp = p->mfp) == NULL || strcmp(mfp->filename,filnam) != 0) {
1387 /* readfile if reqd */
1388 if (UNLIKELY((mfp = ldmemfile2withCB(csound, filnam,
1389 CSFTYPE_HETRO, NULL)) == NULL)) {
1390 return csound->InitError(csound, Str("ADSYN cannot load %s"), filnam);
1391 }
1392 p->mfp = mfp; /* & record */
1393 }
1394
1395 adp = (int16 *) mfp->beginp; /* align on file data */
1396 endata = (int16 *) mfp->endp;
1397 size = 1+(*adp == -1 ? MAXPTLS : *adp++); /* Old no header -> MAXPIL */
1398 if (p->aux.auxp==NULL || p->aux.size < (uint32_t)sizeof(PTLPTR)*size)
1399 csound->AuxAlloc(csound, sizeof(PTLPTR)*size, &p->aux);
1400
1401 ptlap = ptlfp = (PTLPTR*)p->aux.auxp; /* find base ptl blk */
1402 ptlim = ptlap + size;
1403 do {
1404 if ((val = *adp++) < 0) { /* then for each brkpt set, */
1405 switch (val) {
1406 case -1:
1407 ptlap->nxtp = ptlap + 1; /* chain the ptl blks */
1408 if (UNLIKELY((ptlap = ptlap->nxtp) >= ptlim)) goto adsful;
1409 ptlap->ap = (DUPLE *) adp; /* record start amp */
1410 ptlap->amp = ptlap->ap->val;
1411 break;
1412 case -2:
1413 if (UNLIKELY((ptlfp += 1) >= ptlim)) goto adsful;
1414 ptlfp->fp = (DUPLE *) adp; /* record start frq */
1415 ptlfp->frq = ptlfp->fp->val;
1416 ptlfp->phs = 0; /* and clr the phase */
1417 break;
1418 default:
1419 return csound->InitError(csound, Str("illegal code %d encountered"), val);
1420 }
1421 }
1422 } while (adp < endata);
1423 if (UNLIKELY(ptlap != ptlfp)) {
1424 return csound->InitError(csound, Str("%d amp tracks, %d freq tracks"),
1425 (int32_t) (ptlap - (PTLPTR*)p->aux.auxp) - 1,
1426 (int32_t) (ptlfp - (PTLPTR*)p->aux.auxp) - 1);
1427 }
1428 ptlap->nxtp = NULL; /* terminate the chain */
1429 p->mksecs = 0;
1430
1431 return OK;
1432
1433 adsful:
1434 return csound->InitError(csound, Str("partial count exceeds MAXPTLS"));
1435 }
1436
adset(CSOUND * csound,ADSYN * p)1437 int32_t adset(CSOUND *csound, ADSYN *p){
1438 return adset_(csound,p,0);
1439 }
1440
adset_S(CSOUND * csound,ADSYN * p)1441 int32_t adset_S(CSOUND *csound, ADSYN *p){
1442 return adset_(csound,p,1);
1443 }
1444
1445 #define ADSYN_MAXLONG FL(2147483647.0)
1446
adsyn(CSOUND * csound,ADSYN * p)1447 int32_t adsyn(CSOUND *csound, ADSYN *p)
1448 {
1449 PTLPTR *curp, *prvp;
1450 DUPLE *ap, *fp;
1451 int16 curtim, diff, ktogo;
1452 int32_t phs, sinc, amp;
1453 uint32_t offset = p->h.insdshead->ksmps_offset;
1454 uint32_t early = p->h.insdshead->ksmps_no_end;
1455 uint32_t n, nsmps = CS_KSMPS;
1456 MYFLT *ar = p->rslt;
1457 MYFLT ampscale, frqscale;
1458 int32_t timkincr, nxtim;
1459
1460 if (UNLIKELY(csound->isintab == NULL)) { /* RWD fix */
1461 return csound->PerfError(csound, &(p->h),
1462 Str("adsyn: not initialised"));
1463 }
1464 /* IV - Jul 11 2002 */
1465 ampscale = *p->kamod * csound->e0dbfs; /* since 15-bit sine table */
1466 frqscale = *p->kfmod * ISINSIZ * csound->onedsr;
1467 /* 1024 * msecs of analysis */
1468 memset(p->rslt,0,sizeof(MYFLT)*nsmps);
1469 if (UNLIKELY(early)) nsmps -= early;
1470 timkincr = (int32)(*p->ksmod*FL(1024000.0)*CS_ONEDKR);
1471 curtim = (int16)(p->mksecs >> 10); /* cvt mksecs to msecs */
1472 curp = (PTLPTR*)p->aux.auxp; /* now for each partial: */
1473 while ((prvp = curp) && (curp = curp->nxtp) != NULL ) {
1474 ap = curp->ap;
1475 fp = curp->fp;
1476 while (curtim >= (ap+1)->tim) /* timealign ap, fp */
1477 curp->ap = ap += 1;
1478 while (curtim >= (fp+1)->tim)
1479 curp->fp = fp += 1;
1480 if ((amp = curp->amp)) { /* for non-zero amp */
1481 sinc = (int32)(curp->frq * frqscale);
1482 phs = curp->phs;
1483 /* addin a sinusoid */
1484 for (n=offset; n<nsmps; n++) {
1485 ar[n] += (ampscale*(MYFLT)csound->isintab[phs]*(MYFLT)amp)/ADSYN_MAXLONG;
1486 phs += sinc;
1487 phs &= ADMASK;
1488 }
1489 curp->phs = phs;
1490 }
1491 if ((nxtim = (ap+1)->tim) == 32767) { /* if last amp this partial */
1492 prvp->nxtp = curp->nxtp; /* remov from activ chain */
1493 curp = prvp;
1494 }
1495 else { /* else interp towds nxt amp */
1496 if ((diff = (int16)((ap+1)->val - amp))) {
1497 ktogo = (int16)(((nxtim<<10) - p->mksecs + timkincr - 1) / timkincr);
1498 if (ktogo == 0) curp->amp += diff;
1499 else curp->amp += diff / ktogo;
1500 }
1501 if ((nxtim = (fp+1)->tim) != 32767 /* & nxt frq */
1502 && (diff = (fp+1)->val - curp->frq)) {
1503 ktogo = (int16)(((nxtim<<10) - p->mksecs + timkincr - 1) / timkincr);
1504 if (ktogo == 0) curp->frq += diff;
1505 else curp->frq += diff / ktogo;
1506 }
1507 }
1508 }
1509 p->mksecs += timkincr; /* advance the time */
1510 return OK;
1511 }
1512