1 /* Copyright (C) 2002-2004 Gabriel Maldonado */
2 /* 2016 John ffitch (array changed) */
3
4 /* The gab library is free software; you can redistribute it */
5 /* and/or modify it under the terms of the GNU Lesser General Public */
6 /* License as published by the Free Software Foundation; either */
7 /* version 2.1 of the License, or (at your option) any later version. */
8
9 /* The gab library is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU Lesser General Public License for more details. */
13
14 /* You should have received a copy of the GNU Lesser General Public */
15 /* License along with the gab library; if not, write to the Free Software */
16 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA */
17 /* 02110-1301 USA */
18
19 /* Ported to csound5 by: Andres Cabrera */
20 /* This file includes the opcodes from newopcodes.c */
21 /* TODO: Check if the authors (Peter Neubaeker and Jens Groh) are correct */
22
23 /*printi removed? I can't find the corresponding OENTRY- */
24 /*Left them commented out */
25 /*how should exitnow be safely implemented? */
26 /*Check the zak opcodes */
27 /*changed some comments to c-style */
28 /*Check csystem, exitnow */
29 /*Check other opcodes commented out in Oentry */
30
31
32 #include "stdopcod.h"
33 #include "gab.h"
34 #include <math.h>
35 #include "interlocks.h"
36
37 #define FLT_MAX ((MYFLT)0x7fffffff)
38
krsnsetx(CSOUND * csound,KRESONX * p)39 static int32_t krsnsetx(CSOUND *csound, KRESONX *p)
40 /* Gabriel Maldonado, modified for arb order */
41 {
42 int32_t scale;
43 p->scale = scale = (int32_t) *p->iscl;
44 if (UNLIKELY((p->loop = MYFLT2LRND(*p->ord)) < 1))
45 p->loop = 4; /*default value*/
46 if (!*p->istor && (p->aux.auxp == NULL ||
47 (uint32_t)(p->loop*2*sizeof(MYFLT)) > p->aux.size))
48 csound->AuxAlloc(csound, (int64_t)(p->loop*2*sizeof(MYFLT)), &p->aux);
49 p->yt1 = (MYFLT*)p->aux.auxp; p->yt2 = (MYFLT*)p->aux.auxp + p->loop;
50 if (UNLIKELY(scale && scale != 1 && scale != 2)) {
51 return csound->InitError(csound,Str("illegal reson iscl value, %f"),
52 *p->iscl);
53 }
54 if (LIKELY(!(*p->istor))) {
55 memset(p->yt1, 0, p->loop*sizeof(MYFLT));
56 memset(p->yt2, 0, p->loop*sizeof(MYFLT));
57 }
58 p->prvcf = p->prvbw = -FL(100.0);
59 return OK;
60 }
61
kresonx(CSOUND * csound,KRESONX * p)62 static int32_t kresonx(CSOUND *csound, KRESONX *p) /* Gabriel Maldonado, modified */
63 {
64 int32_t flag = 0, j;
65 MYFLT *ar, *asig;
66 MYFLT c3p1, c3t4, omc3, c2sqr;
67 MYFLT *yt1, *yt2, c1,c2,c3;
68
69 if (*p->kcf != p->prvcf) {
70 p->prvcf = *p->kcf;
71 p->cosf = COS(*p->kcf * csound->tpidsr * CS_KSMPS);
72 flag = 1;
73 }
74 if (*p->kbw != p->prvbw) {
75 p->prvbw = *p->kbw;
76 p->c3 = EXP(*p->kbw * csound->mtpdsr * CS_KSMPS);
77 flag = 1;
78 }
79 if (flag) {
80 c3p1 = p->c3 + FL(1.0);
81 c3t4 = p->c3 * FL(4.0);
82 omc3 = FL(1.0)- p->c3;
83 p->c2 = c3t4 * p->cosf / c3p1; /* -B, so + below */
84 c2sqr = p->c2 * p->c2;
85 if (p->scale == 1)
86 p->c1 = omc3 * SQRT(FL(1.0) - (c2sqr / c3t4));
87 else if (p->scale == 2)
88 p->c1 = SQRT((c3p1*c3p1-c2sqr) * omc3/c3p1);
89 else p->c1 = FL(1.0);
90 }
91 c1 = p->c1;
92 c2 = p->c2;
93 c3 = p->c3;
94 yt1 = p->yt1;
95 yt2 = p->yt2;
96 asig = p->asig;
97 ar = p->ar;
98 for (j=0; j< p->loop; j++) {
99 *ar = c1 * *asig + c2 * yt1[j] - c3 * yt2[j];
100 yt2[j] = yt1[j];
101 yt1[j] = *ar;
102 asig= p->ar;
103 }
104 return OK;
105 }
106
107 /* /////////////////////////////////////////// */
108
fastab_set(CSOUND * csound,FASTAB * p)109 static int32_t fastab_set(CSOUND *csound, FASTAB *p)
110 {
111 FUNC *ftp;
112 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->xfn)) == NULL)) {
113 return csound->InitError(csound, Str("fastab: incorrect table number"));
114 }
115 p->table = ftp->ftable;
116 p->tablen = ftp->flen;
117 p->xmode = (int32_t) *p->ixmode;
118 if (p->xmode)
119 p->xbmul = (MYFLT) p->tablen /*- FL(0.001)*/;
120 else
121 p->xbmul = FL(1.0);
122 return OK;
123 }
124
fastabw(CSOUND * csound,FASTAB * p)125 static int32_t fastabw(CSOUND *csound, FASTAB *p)
126 {
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 FUNC *ftp = csound->FTnp2Finde(csound, p->xfn);
131 p->table = ftp->ftable;
132 MYFLT *tab = p->table;
133 MYFLT *rslt = p->rslt, *ndx = p->xndx;
134
135
136 if (UNLIKELY(early)) nsmps -= early;
137 if (p->xmode) {
138 MYFLT xbmul = p->xbmul; /* load once */
139 int32_t len = p->tablen;
140 for (n=offset; n<nsmps; n++) { /* for loops compile better */
141 int32_t i = (int32_t)MYFLT2LRND(ndx[n]*xbmul);
142 if (UNLIKELY(i > len || i<0)) {
143 csound->Message(csound, "ndx: %f\n", ndx[n]);
144 return csound->PerfError(csound, &(p->h), Str("tabw off end"));
145 }
146 tab[i] = rslt[n];
147 }
148 }
149 else {
150 int32_t len = p->tablen;
151 for (n=offset; n<nsmps; n++) {
152 int32_t i = MYFLT2LRND(ndx[n]);
153 if (UNLIKELY(i > len || i<0)) {
154 return csound->PerfError(csound, &(p->h), Str("tabw off end"));
155 }
156 tab[i] = rslt[n];
157 }
158 }
159 return OK;
160 }
161
fastabk(CSOUND * csound,FASTAB * p)162 static int32_t fastabk(CSOUND *csound, FASTAB *p)
163 {
164 int32_t i;
165 if (p->xmode)
166 i = (int32_t) MYFLT2LRND(*p->xndx * p->xbmul);
167 else
168 i = (int32_t) MYFLT2LRND(*p->xndx);
169 if (UNLIKELY(i > p->tablen || i<0)) {
170 return csound->PerfError(csound, &(p->h), Str("tab off end %i"), i);
171 }
172 *p->rslt = p->table[i];
173 return OK;
174 }
175
fastabkw(CSOUND * csound,FASTAB * p)176 static int32_t fastabkw(CSOUND *csound, FASTAB *p)
177 {
178 int32_t i;
179 if (p->xmode)
180 i = (int32_t) MYFLT2LRND(*p->xndx * p->xbmul);
181 else
182 i = (int32_t) MYFLT2LRND(*p->xndx);
183 if (UNLIKELY(i > p->tablen || i<0)) {
184 return csound->PerfError(csound, &(p->h), Str("tabw off end"));
185 }
186 p->table[i] = *p->rslt;
187 return OK;
188 }
189
fastabi(CSOUND * csound,FASTAB * p)190 static int32_t fastabi(CSOUND *csound, FASTAB *p)
191 {
192 FUNC *ftp;
193 int32 i;
194
195 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->xfn)) == NULL)) {
196 return csound->InitError(csound, Str("tab_i: incorrect table number"));
197 }
198 if (*p->ixmode)
199 i = (int32) MYFLT2LRND(*p->xndx * ftp->flen);
200 else
201 i = (int32) MYFLT2LRND(*p->xndx);
202 if (UNLIKELY(i >= (int32)ftp->flen || i<0)) {
203 return csound->InitError(csound, Str("tab_i off end: table number: %d\n"),
204 (int32_t) *p->xfn);
205 }
206 *p->rslt = ftp->ftable[i];
207 return OK;
208 }
209
fastabiw(CSOUND * csound,FASTAB * p)210 static int32_t fastabiw(CSOUND *csound, FASTAB *p)
211 {
212 FUNC *ftp;
213 int32 i;
214 /*ftp = csound->FTFind(p->xfn); */
215 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->xfn)) == NULL)) {
216 return csound->InitError(csound, Str("tabw_i: incorrect table number"));
217 }
218 if (*p->ixmode)
219 i = (int32) MYFLT2LRND(*p->xndx * ftp->flen);
220 else
221 i = (int32) MYFLT2LRND(*p->xndx);
222 if (UNLIKELY(i >= (int32)ftp->flen || i<0)) {
223 return csound->PerfError(csound, &(p->h), Str("tabw_i off end"));
224 }
225 ftp->ftable[i] = *p->rslt;
226 return OK;
227 }
228
fastab(CSOUND * csound,FASTAB * p)229 static int32_t fastab(CSOUND *csound, FASTAB *p)
230 {
231 uint32_t offset = p->h.insdshead->ksmps_offset;
232 uint32_t early = p->h.insdshead->ksmps_no_end;
233 uint32_t i, nsmps = CS_KSMPS;
234 FUNC *ftp = csound->FTnp2Finde(csound, p->xfn);
235 p->table = ftp->ftable;
236 MYFLT *tab = p->table;
237 MYFLT *rslt = p->rslt, *ndx = p->xndx;
238 if (UNLIKELY(offset)) memset(rslt, '\0', offset*sizeof(MYFLT));
239 if (UNLIKELY(early)) {
240 nsmps -= early;
241 memset(&rslt[nsmps], '\0', early*sizeof(MYFLT));
242 }
243 if (p->xmode) {
244 MYFLT xbmul = p->xbmul;
245 int32_t len = p->tablen;
246 for (i=offset; i<nsmps; i++) {
247 int32_t n = (int32_t) MYFLT2LRND(ndx[i] * xbmul);
248 if (UNLIKELY(n > len || n<0)) {
249 return csound->PerfError(csound, &(p->h), Str("tab off end %d"),n);
250 }
251 rslt[i] = tab[n];
252 }
253 }
254 else {
255 int32_t len = p->tablen;
256 for (i=offset; i<nsmps; i++) {
257 int32_t n = (int32_t) MYFLT2LRND(ndx[i]);
258 if (UNLIKELY(n > len || n<0)) {
259 return csound->PerfError(csound, &(p->h), Str("tab off end %d"),n);
260 }
261 rslt[i] = tab[n];
262 }
263 }
264 return OK;
265 }
266
tab_init(CSOUND * csound,TB_INIT * p,int32_t ndx)267 static CS_NOINLINE int32_t tab_init(CSOUND *csound, TB_INIT *p, int32_t ndx)
268 {
269 MYFLT *ft;
270 STDOPCOD_GLOBALS *pp;
271 if (UNLIKELY(csoundGetTable(csound, &ft, MYFLT2LRND(*p->ifn)) < 0))
272 return csound->InitError(csound, Str("tab_init: incorrect table number"));
273 pp = (STDOPCOD_GLOBALS*) csound->stdOp_Env;
274 pp->tb_ptrs[ndx] = ft;
275 return OK;
276 }
277
tab_perf(CSOUND * csound,FASTB * p)278 static CS_NOINLINE int32_t tab_perf(CSOUND *csound, FASTB *p)
279 {
280 IGN(csound);
281 *p->r = (*p->tb_ptr)[(int32_t) MYFLT2LRND(*p->ndx)];
282 return OK;
283 }
284
tab_i_tmp(CSOUND * csound,FASTB * p,int32_t ndx)285 static CS_NOINLINE int32_t tab_i_tmp(CSOUND *csound, FASTB *p, int32_t ndx)
286 {
287 STDOPCOD_GLOBALS *pp;
288 pp = (STDOPCOD_GLOBALS*) csound->stdOp_Env;
289 p->tb_ptr = &(pp->tb_ptrs[ndx]);
290 p->h.iopadr = (SUBR) tab_perf;
291 return tab_perf(csound, p);
292 }
293
tab_k_tmp(CSOUND * csound,FASTB * p,int32_t ndx)294 static CS_NOINLINE int32_t tab_k_tmp(CSOUND *csound, FASTB *p, int32_t ndx)
295 {
296 STDOPCOD_GLOBALS *pp;
297 pp = (STDOPCOD_GLOBALS*) csound->stdOp_Env;
298 p->tb_ptr = &(pp->tb_ptrs[ndx]);
299 p->h.opadr = (SUBR) tab_perf;
300 return tab_perf(csound, p);
301 }
302
303 #ifdef TAB_MACRO
304 #undef TAB_MACRO
305 #endif
306
307 #define TAB_MACRO(W,X,Y,Z) \
308 static int32_t W(CSOUND *csound, TB_INIT *p) \
309 { return tab_init(csound, p, Z); } \
310 static int32_t X(CSOUND *csound, FASTB *p) \
311 { return tab_i_tmp(csound, p, Z); } \
312 static int32_t Y(CSOUND *csound, FASTB *p) \
313 { return tab_k_tmp(csound, p, Z); }
314
315 TAB_MACRO(tab0_init, tab0_i_tmp, tab0_k_tmp, 0)
316 TAB_MACRO(tab1_init, tab1_i_tmp, tab1_k_tmp, 1)
317 TAB_MACRO(tab2_init, tab2_i_tmp, tab2_k_tmp, 2)
318 TAB_MACRO(tab3_init, tab3_i_tmp, tab3_k_tmp, 3)
319 TAB_MACRO(tab4_init, tab4_i_tmp, tab4_k_tmp, 4)
320 TAB_MACRO(tab5_init, tab5_i_tmp, tab5_k_tmp, 5)
321 TAB_MACRO(tab6_init, tab6_i_tmp, tab6_k_tmp, 6)
322 TAB_MACRO(tab7_init, tab7_i_tmp, tab7_k_tmp, 7)
323 TAB_MACRO(tab8_init, tab8_i_tmp, tab8_k_tmp, 8)
324 TAB_MACRO(tab9_init, tab9_i_tmp, tab9_k_tmp, 9)
325 TAB_MACRO(tab10_init, tab10_i_tmp, tab10_k_tmp, 10)
326 TAB_MACRO(tab11_init, tab11_i_tmp, tab11_k_tmp, 11)
327 TAB_MACRO(tab12_init, tab12_i_tmp, tab12_k_tmp, 12)
328 TAB_MACRO(tab13_init, tab13_i_tmp, tab13_k_tmp, 13)
329 TAB_MACRO(tab14_init, tab14_i_tmp, tab14_k_tmp, 14)
330 TAB_MACRO(tab15_init, tab15_i_tmp, tab15_k_tmp, 15)
331
332 /* ====================== */
333 /* opcodes from Jens Groh */
334 /* ====================== */
335
nlalp_set(CSOUND * csound,NLALP * p)336 static int32_t nlalp_set(CSOUND *csound, NLALP *p)
337 {
338 IGN(csound);
339 if (LIKELY(!(*p->istor))) {
340 p->m0 = 0.0;
341 p->m1 = 0.0;
342 }
343 return OK;
344 }
345
nlalp(CSOUND * csound,NLALP * p)346 static int32_t nlalp(CSOUND *csound, NLALP *p)
347 {
348 IGN(csound);
349 uint32_t offset = p->h.insdshead->ksmps_offset;
350 uint32_t early = p->h.insdshead->ksmps_no_end;
351 uint32_t n, nsmps = CS_KSMPS;
352 MYFLT *rp;
353 MYFLT *ip;
354 double m0;
355 double m1;
356 double tm0;
357 double tm1;
358 double klfact;
359 double knfact;
360
361 rp = p->aresult;
362 ip = p->ainsig;
363 klfact = (double)*p->klfact;
364 knfact = (double)*p->knfact;
365 tm0 = p->m0;
366 tm1 = p->m1;
367 if (UNLIKELY(offset)) memset(rp, '\0', offset*sizeof(MYFLT));
368 if (UNLIKELY(early)) {
369 nsmps -= early;
370 memset(&rp[nsmps], '\0', early*sizeof(MYFLT));
371 }
372 if (knfact == 0.0) { /* linear case */
373 if (UNLIKELY(klfact == 0.0)) { /* degenerated linear case */
374 m0 = (double)ip[0] - tm1;
375 rp[offset] = (MYFLT)(tm0);
376 for (n=offset+1; n<nsmps; n++) {
377 rp[n] = (MYFLT)(m0);
378 m0 = (double)ip[n];
379 }
380 tm1 = 0.0;
381 tm0 = m0;
382 }
383 else { /* normal linear case */
384 for (n=offset; n<nsmps; n++) {
385 m0 = (double)ip[n] - tm1;
386 m1 = m0 * klfact;
387 rp[n] = (MYFLT)(tm0 + m1);
388 tm1 = m1;
389 tm0 = m0;
390 }
391 }
392 } else { /* non-linear case */
393 if (UNLIKELY(klfact == 0.0)) { /* simplified non-linear case */
394 for (n=offset; n<nsmps; n++) {
395 m0 = (double)ip[n] - tm1;
396 m1 = fabs(m0) * knfact;
397 rp[n] = (MYFLT)(tm0 + m1);
398 tm1 = m1;
399 tm0 = m0;
400 }
401 } else { /* normal non-linear case */
402 for (n=offset; n<nsmps; n++) {
403 m0 = (double)ip[n] - tm1;
404 m1 = m0 * klfact + fabs(m0) * knfact;
405 rp[n] = (MYFLT)(tm0 + m1);
406 tm1 = m1;
407 tm0 = m0;
408 }
409 }
410 }
411 p->m0 = tm0;
412 p->m1 = tm1;
413 return OK;
414 }
415
416 /* ----------------------------------------------- */
417
adsynt2_set(CSOUND * csound,ADSYNT2 * p)418 static int32_t adsynt2_set(CSOUND *csound,ADSYNT2 *p)
419 {
420 FUNC *ftp;
421 uint32_t count;
422 int32 *lphs;
423 MYFLT iphs = *p->iphs;
424
425 p->inerr = 0;
426
427 if (LIKELY((ftp = csound->FTFind(csound, p->ifn)) != NULL)) {
428 p->ftp = ftp;
429 }
430 else {
431 p->inerr = 1;
432 return csound->InitError(csound, Str("adsynt2: wavetable not found!"));
433 }
434
435 count = (uint32_t)*p->icnt;
436 if (UNLIKELY(count < 1)) count = 1;
437 p->count = count;
438
439 if (LIKELY((ftp = csound->FTnp2Find(csound, p->ifreqtbl)) != NULL)) {
440 p->freqtp = ftp;
441 }
442 else {
443 p->inerr = 1;
444 return csound->InitError(csound, Str("adsynt2: freqtable not found!"));
445 }
446 if (UNLIKELY(ftp->flen < count)) {
447 p->inerr = 1;
448 return csound->InitError(csound,
449 Str("adsynt2: partial count is greater "
450 "than freqtable size!"));
451 }
452
453 if (LIKELY((ftp = csound->FTnp2Find(csound, p->iamptbl)) != NULL)) {
454 p->amptp = ftp;
455 }
456 else {
457 p->inerr = 1;
458 return csound->InitError(csound, Str("adsynt2: amptable not found!"));
459 }
460 if (UNLIKELY(ftp->flen < count)) {
461 p->inerr = 1;
462 return csound->InitError(csound,
463 Str("adsynt2: partial count is greater "
464 "than amptable size!"));
465 }
466
467 if (p->lphs.auxp==NULL ||
468 p->lphs.size < sizeof(int32)*count)
469 csound->AuxAlloc(csound, sizeof(int32)*count, &p->lphs);
470 lphs = (int32*)p->lphs.auxp;
471
472 if (iphs > 1) {
473 uint32_t c;
474 for (c=0; c<count; c++) {
475 lphs[c] = ((int32)
476 ((MYFLT) ((double) (csound->Rand31(&(csound->randSeed1)) - 1)
477 / 2147483645.0) * FMAXLEN)) & PHMASK;
478 }
479 }
480 else if (iphs >= 0) {
481 uint32_t c;
482 for (c=0; c<count; c++) {
483 lphs[c] = ((int32)(iphs * FMAXLEN)) & PHMASK;
484 }
485 }
486 if (p->pamp.auxp==NULL ||
487 p->pamp.size < (uint32_t)(sizeof(MYFLT)*p->count))
488 csound->AuxAlloc(csound, sizeof(MYFLT)*p->count, &p->pamp);
489 else if (iphs >= 0) /* AuxAlloc clear anyway */
490 memset(p->pamp.auxp, 0, sizeof(MYFLT)*p->count);
491 return OK;
492 }
493
adsynt2(CSOUND * csound,ADSYNT2 * p)494 static int32_t adsynt2(CSOUND *csound,ADSYNT2 *p)
495 {
496 FUNC *ftp, *freqtp, *amptp;
497 MYFLT *ar, *ftbl, *freqtbl, *amptbl, *prevAmp;
498 MYFLT amp0, amp, cps0, cps, ampIncr, amp2;
499 int32 phs, inc, lobits;
500 int32 *lphs;
501 int32_t c, count;
502 uint32_t offset = p->h.insdshead->ksmps_offset;
503 uint32_t early = p->h.insdshead->ksmps_no_end;
504 uint32_t n, nsmps = CS_KSMPS;
505
506 /* I believe this can never happen as InitError will remove instance */
507 /* The check should be on p->amptp and p->freqtp -- JPff */
508 if (UNLIKELY(p->inerr || p->amptp==NULL || p->freqtp==NULL)) {
509 return csound->InitError(csound, Str("adsynt2: not initialised"));
510 }
511 ftp = p->ftp;
512 ftbl = ftp->ftable;
513 lobits = ftp->lobits;
514 freqtp = p->freqtp;
515 freqtbl = freqtp->ftable;
516 amptp = p->amptp;
517 amptbl = amptp->ftable;
518 lphs = (int32*)p->lphs.auxp;
519 prevAmp = (MYFLT*)p->pamp.auxp;
520
521 cps0 = *p->kcps;
522 amp0 = *p->kamp;
523 count = p->count;
524
525 ar = p->sr;
526 memset(ar, 0, nsmps*sizeof(MYFLT));
527 if (UNLIKELY(early)) {
528 nsmps -= early;
529 memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
530 }
531
532 for (c=0; c<count; c++) {
533 amp2 = prevAmp[c];
534 amp = amptbl[c] * amp0;
535 cps = freqtbl[c] * cps0;
536 inc = (int32) (cps * csound->sicvt);
537 phs = lphs[c];
538 ampIncr = (amp - amp2) * CS_ONEDKSMPS;
539 for (n=offset; n<nsmps; n++) {
540 ar[n] += *(ftbl + (phs >> lobits)) * amp2;
541 phs += inc;
542 phs &= PHMASK;
543 amp2 += ampIncr;
544 }
545 prevAmp[c] = amp;
546 lphs[c] = phs;
547 }
548 return OK;
549 }
550
exitnow(CSOUND * csound,EXITNOW * p)551 static int32_t exitnow(CSOUND *csound, EXITNOW *p)
552 {
553 (void) p;
554 csound->LongJmp(csound, MYFLT2LRND(*p->retval));
555 return OK; /* compiler only */
556 }
557
tabrec_set(CSOUND * csound,TABREC * p)558 static int32_t tabrec_set(CSOUND *csound,TABREC *p)
559 {
560 IGN(csound);
561 p->recording = 0;
562 p->currtic = 0;
563 p->ndx = 0;
564 p->numins = p->INOCOUNT-4;
565 return OK;
566 }
567
tabrec_k(CSOUND * csound,TABREC * p)568 static int32_t tabrec_k(CSOUND *csound,TABREC *p)
569 {
570 if (*p->ktrig_start) {
571 if (*p->kfn != p->old_fn) {
572 int32_t flen;
573 if (UNLIKELY((flen = csoundGetTable(csound,&(p->table),
574 (int32_t)*p->kfn)) < 0))
575 return csound->PerfError(csound, &(p->h),
576 Str("Invalid ftable no. %f"), *p->kfn);
577 p->tablen = (int64_t) flen;
578 *(p->table++) = *p->numtics;
579 p->old_fn = *p->kfn;
580 }
581 p->recording = 1;
582 p->ndx = 0;
583 p->currtic = 0;
584 }
585 if (*p->ktrig_stop) {
586
587 if (p->currtic >= *p->numtics) {
588 p->recording = 0;
589 return OK;
590 }
591 p->currtic++;
592 }
593 if (p->recording) {
594 int32_t j, curr_frame = p->ndx * p->numins;
595
596 MYFLT *table = p->table;
597 MYFLT **inargs = p->inargs;
598 if (curr_frame + p->numins < p->tablen) {
599 /* record only if table is not full */
600 for (j = 0; j < p->numins; j++)
601 table[curr_frame + j] = *inargs[j];
602 }
603 (p->ndx)++;
604 }
605 return OK;
606 }
607 /*-------------------------*/
tabplay_set(CSOUND * csound,TABPLAY * p)608 static int32_t tabplay_set(CSOUND *csound,TABPLAY *p)
609 {
610 /* FUNC *ftp; */
611 /* if ((ftp = csound->FTFind(p->ifn)) == NULL) { */
612 /* csound->InitError(csound, Str("tabplay: incorrect table number")); */
613 /* return; */
614 /* } */
615 /* p->table = ftp->ftable; */
616 /* p->tablen = ftp->flen; */
617 IGN(csound);
618 p->playing = 0;
619 p->currtic = 0;
620 p->ndx = 0;
621 p->numouts = p->INOCOUNT-3;
622 return OK;
623 }
624
tabplay_k(CSOUND * csound,TABPLAY * p)625 static int32_t tabplay_k(CSOUND *csound,TABPLAY *p)
626 {
627 if (*p->ktrig) {
628 if (*p->kfn != p->old_fn) {
629 int32_t flen;
630 if (UNLIKELY((flen = csoundGetTable(csound, &(p->table),
631 (int32_t)*p->kfn)) < 0))
632 return csound->PerfError(csound, &(p->h),
633 Str("Invalid ftable no. %f"), *p->kfn);
634 p->tablen = (int64_t) flen;
635 p->currtic = 0;
636 p->ndx = 0;
637 *(p->table++) = *p->numtics;
638 p->old_fn = *p->kfn;
639 }
640 p->playing = 1;
641 if (p->currtic == 0)
642 p->ndx = 0;
643 if (p->currtic >= *p->numtics) {
644 p->playing = 0;
645 return OK;
646 }
647 p->currtic++;
648 p->currtic %= (int64_t) *p->numtics;
649
650 }
651 if (p->playing) {
652 int32_t j, curr_frame = p->ndx * p->numouts;
653 MYFLT *table = p->table;
654 MYFLT **outargs = p->outargs;
655 if (UNLIKELY(curr_frame + p->numouts < p->tablen)) {
656 /* play only if ndx is inside table */
657 for (j = 0; j < p->numouts; j++)
658 *outargs[j] = table[curr_frame+j];
659 }
660 (p->ndx)++;
661 }
662 return OK;
663 }
664
isChanged_set(CSOUND * csound,ISCHANGED * p)665 static int32_t isChanged_set(CSOUND *csound,ISCHANGED *p)
666 {
667 IGN(csound);
668 p->numargs = p->INOCOUNT;
669 memset(p->old_inargs, 0, sizeof(MYFLT)*p->numargs); /* Initialise */
670 p->cnt = 1;
671 return OK;
672 }
673
isChanged(CSOUND * csound,ISCHANGED * p)674 static int32_t isChanged(CSOUND *csound,ISCHANGED *p)
675 {
676 IGN(csound);
677 MYFLT **inargs = p->inargs;
678 MYFLT *old_inargs = p->old_inargs;
679 int32_t numargs = p->numargs, ktrig = 0, j;
680
681 if (LIKELY(p->cnt))
682 for (j =0; j< numargs; j++) {
683 if (*inargs[j] != old_inargs[j]) {
684 ktrig = 1;
685 break;
686 }
687 }
688
689 if (ktrig || p->cnt==0) {
690 for (j =0; j< numargs; j++) {
691 old_inargs[j] = *inargs[j];
692 }
693 }
694 *p->ktrig = (MYFLT) ktrig;
695 p->cnt++;
696 return OK;
697 }
698
isChanged2_set(CSOUND * csound,ISCHANGED * p)699 static int32_t isChanged2_set(CSOUND *csound,ISCHANGED *p)
700 {
701 int32_t res = isChanged_set(csound,p);
702 p->cnt = 0;
703 return res;
704 }
705
706 /* changed in array */
isAChanged_set(CSOUND * csound,ISACHANGED * p)707 static int32_t isAChanged_set(CSOUND *csound, ISACHANGED *p)
708 {
709 int32_t size = 0, i;
710 ARRAYDAT *arr = p->chk;
711 //char *tmp;
712 for (i=0; i<arr->dimensions; i++) size += arr->sizes[i];
713 size *= arr->arrayMemberSize;
714 csound->AuxAlloc(csound, size, &p->old_chk);
715 /* tmp = (char*)p->old_chk.auxp; */
716 /* for (i=0; i<size; i++) tmp[i]=rand()&0xff; */
717 /* memset(p->old_chk.auxp, '\0', size); */
718 p->size = size;
719 p->cnt = 0;
720 return OK;
721 }
722
723
isAChanged(CSOUND * csound,ISACHANGED * p)724 static int32_t isAChanged(CSOUND *csound,ISACHANGED *p)
725 {
726 IGN(csound);
727 ARRAYDAT *chk = p->chk;
728 void *old_chk = p->old_chk.auxp;
729 int32_t size = p->size;
730 int32_t ktrig = memcmp(chk->data, old_chk, size);
731 memcpy(old_chk, chk->data, size);
732 *p->ktrig = (p->cnt && ktrig)?FL(1.0):FL(0.0);
733 p->cnt++;
734 return OK;
735 }
736
737
738 /* ------------------------- */
739
partial_maximum_set(CSOUND * csound,P_MAXIMUM * p)740 static int32_t partial_maximum_set(CSOUND *csound,P_MAXIMUM *p)
741 {
742 IGN(csound);
743 int32_t flag = (int32_t) *p->imaxflag;
744 switch (flag) {
745 case 1:
746 p->max = 0; break;
747 case 2:
748 p->max = -FLT_MAX; break;
749 case 3:
750 p->max = FLT_MAX; break;
751 case 4:
752 p->max = 0; break;
753 }
754 p->counter = 0;
755 return OK;
756 }
757
partial_maximum(CSOUND * csound,P_MAXIMUM * p)758 static int32_t partial_maximum(CSOUND *csound,P_MAXIMUM *p)
759 {
760 uint32_t offset = p->h.insdshead->ksmps_offset;
761 uint32_t early = p->h.insdshead->ksmps_no_end;
762 uint32_t n, nsmps = CS_KSMPS;
763 int32_t flag = (int32_t) *p->imaxflag;
764 MYFLT *a = p->asig;
765 MYFLT max = p->max;
766 if (UNLIKELY(early)) nsmps -= early;
767 switch(flag) {
768 case 1: /* absolute maximum */
769 for (n=offset; n<nsmps; n++) {
770 MYFLT temp;
771 if ((temp = FABS(a[n])) > max) max = temp;
772 }
773 if (max > p->max) p->max = max;
774 break;
775 case 2: /* actual maximum */
776 for (n=offset; n<nsmps; n++) {
777 if (a[n] > max) max = a[n];
778 }
779 if (max > p->max) p->max = max;
780 break;
781 case 3: /* actual minimum */
782 for (n=offset; n<nsmps; n++) {
783 if (a[n] < max) max = a[n];
784 }
785 if (max < p->max) p->max = max;
786 break;
787 case 4: { /* average */
788 MYFLT temp = FL(0.0);
789 p->counter += nsmps;
790 for (n=offset; n<nsmps; n++) {
791 temp += a[n];
792 }
793 p->max += temp;
794 }
795 break;
796 default:
797 return csound->PerfError(csound, &(p->h),
798 Str("max_k: invalid imaxflag value"));
799 }
800 if (*p->ktrig) {
801 switch (flag) {
802 case 4:
803 *p->kout = p->max / (MYFLT) p->counter;
804 p->counter = 0;
805 p->max = FL(0.0);
806 break;
807 case 1:
808 *p->kout = p->max;
809 p->max = 0; break;
810 case 2:
811 *p->kout = p->max;
812 p->max = -FLT_MAX; break;
813 case 3:
814 *p->kout = p->max;
815 p->max = FLT_MAX; break;
816 }
817 }
818 return OK;
819 }
820
821 /* From fractals.c */
822 /* mandelbrot set scanner */
mandel_set(CSOUND * csound,MANDEL * p)823 static int32_t mandel_set(CSOUND *csound,MANDEL *p)
824 {
825 IGN(csound);
826 p->oldx=-99999; /*probably unused values */
827 p->oldy=-99999;
828 p->oldCount = -1;
829 return OK;
830 }
831
mandel(CSOUND * csound,MANDEL * p)832 static int32_t mandel(CSOUND *csound,MANDEL *p)
833 {
834 IGN(csound);
835 MYFLT px=*p->kx, py=*p->ky;
836 if (*p->ktrig && (px != p->oldx || py != p->oldy)) {
837 int32_t maxIter = (int32_t) *p->kmaxIter, j;
838 MYFLT x=FL(0.0), y=FL(0.0), newx, newy;
839 for (j=0; j<maxIter; j++) {
840 newx = x*x - y*y + px;
841 newy = FL(2.0)*x*y + py;
842 x=newx;
843 y=newy;
844 if (x*x+y*y >= FL(4.0)) break;
845 }
846 p->oldx = px;
847 p->oldy = py;
848 if (p->oldCount != j) *p->koutrig = FL(1.0);
849 else *p->koutrig = FL(0.0);
850 *p->kr = (MYFLT) (p->oldCount = j);
851 }
852 else {
853 *p->kr = (MYFLT) p->oldCount;
854 *p->koutrig = FL(0.0);
855 }
856 return OK;
857 }
858
859 #define S(x) sizeof(x)
860
861 OENTRY gab_localops[] = {
862 {"resonxk", S(KRESONX), 0, 3, "k", "kkkooo",
863 (SUBR) krsnsetx, (SUBR) kresonx, NULL },
864 { "tab_i",S(FASTAB), TR, 1, "i", "iio", (SUBR) fastabi, NULL, NULL },
865 { "tab",S(FASTAB), TR, 3, "a", "xio",
866 (SUBR) fastab_set, (SUBR) fastab },
867 { "tab.k",S(FASTAB), TR, 3, "k", "kio",
868 (SUBR) fastab_set, (SUBR)fastabk, NULL },
869 { "tabw_i",S(FASTAB), TW, 1, "", "iiio", (SUBR) fastabiw, NULL, NULL },
870 { "tabw",S(FASTAB), TW, 3, "", "kkio",
871 (SUBR)fastab_set, (SUBR)fastabkw },
872 { "tabw",S(FASTAB), TW, 3, "", "aaio",
873 (SUBR)fastab_set, (SUBR)fastabw },
874 { "tb0_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab0_init},
875 { "tb1_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab1_init},
876 { "tb2_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab2_init},
877 { "tb3_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab3_init},
878 { "tb4_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab4_init},
879 { "tb5_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab5_init},
880 { "tb6_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab6_init},
881 { "tb7_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab7_init},
882 { "tb8_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab8_init},
883 { "tb9_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab9_init},
884 { "tb10_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab10_init},
885 { "tb11_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab11_init},
886 { "tb12_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab12_init},
887 { "tb13_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab13_init},
888 { "tb14_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab14_init},
889 { "tb15_init", S(TB_INIT), _QQ, 1, "", "i", (SUBR)tab15_init},
890 /* tbx_t (t-rate version removed here) */
891 { "tb0.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab0_i_tmp },
892 { "tb1.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab1_i_tmp },
893 { "tb2.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab2_i_tmp },
894 { "tb3.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab3_i_tmp },
895 { "tb4.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab4_i_tmp },
896 { "tb5.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab5_i_tmp },
897 { "tb6.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab6_i_tmp },
898 { "tb7.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab7_i_tmp },
899 { "tb8.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab8_i_tmp },
900 { "tb9.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab9_i_tmp },
901 { "tb10.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab10_i_tmp },
902 { "tb11.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab11_i_tmp },
903 { "tb12.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab12_i_tmp },
904 { "tb13.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab13_i_tmp },
905 { "tb14.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab14_i_tmp },
906 { "tb15.i", S(FASTB), _QQ|TR, 1, "i", "i", (SUBR) tab15_i_tmp },
907 { "tb0.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab0_k_tmp },
908 { "tb1.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab1_k_tmp },
909 { "tb2.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab2_k_tmp },
910 { "tb3.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab3_k_tmp },
911 { "tb4.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab4_k_tmp },
912 { "tb5.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab5_k_tmp },
913 { "tb6.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab6_k_tmp },
914 { "tb7.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab7_k_tmp },
915 { "tb8.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab8_k_tmp },
916 { "tb9.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab9_k_tmp },
917 { "tb10.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab10_k_tmp },
918 { "tb11.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab11_k_tmp },
919 { "tb12.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab12_k_tmp },
920 { "tb13.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab13_k_tmp },
921 { "tb14.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab14_k_tmp },
922 { "tb15.k", S(FASTB), _QQ|TR, 2, "k", "k", NULL, (SUBR) tab15_k_tmp },
923 { "nlalp", S(NLALP), 0, 3, "a", "akkoo",
924 (SUBR) nlalp_set, (SUBR) nlalp },
925 { "adsynt2",S(ADSYNT2),TR, 3, "a", "kkiiiio",
926 (SUBR) adsynt2_set, (SUBR)adsynt2 },
927 { "exitnow",S(EXITNOW), 0, 1, "", "o", (SUBR) exitnow, NULL, NULL },
928 /* { "zr_i", S(ZKR), 0, 1, "i", "i", (SUBR)zread, NULL, NULL}, */
929 /* { "zr_k", S(ZKR), 0, 2, "k", "k", NULL, (SUBR)zread, NULL}, */
930 /* { "zr_a", S(ZAR), 0, 3, "a", "a", (SUBR)zaset, (SUBR)zar}, */
931 /* { "k_i", S(ASSIGN), 0, 1, "k", "i", (SUBR)assign}, */
932 /* { "k_t", S(ASSIGN), 0, 2, "k", "t", NULL, (SUBR)assign}, */
933 /* { "a_k", S(INDIFF), 0, 3, "a", "k", (SUBR)a_k_set, (SUBR)interp }, */
934 { "tabrec", S(TABREC), TW, 3, "", "kkkkz",
935 (SUBR) tabrec_set, (SUBR) tabrec_k, NULL },
936 { "tabplay", S(TABPLAY), TR, 3, "", "kkkz",
937 (SUBR) tabplay_set, (SUBR) tabplay_k, NULL },
938 { "changed.k", S(ISCHANGED), 0, 3, "k", "z",
939 (SUBR) isChanged_set, (SUBR)isChanged, NULL },
940 { "changed2.k", S(ISCHANGED), 0, 3, "k", "z",
941 (SUBR) isChanged2_set, (SUBR)isChanged, NULL },
942 { "changed2.A", S(ISACHANGED), 0, 3, "k", ".[]",
943 (SUBR) isAChanged_set, (SUBR)isAChanged, NULL },
944 { "max_k", S(P_MAXIMUM), 0, 3, "k", "aki",
945 (SUBR) partial_maximum_set, (SUBR) partial_maximum },
946 { "mandel",S(MANDEL), 0, 3, "kk", "kkkk",
947 (SUBR) mandel_set, (SUBR) mandel, NULL }
948 };
949
gab_gab_init_(CSOUND * csound)950 int32_t gab_gab_init_(CSOUND *csound)
951 {
952 return csound->AppendOpcodes(csound, &(gab_localops[0]),
953 (int32_t) (sizeof(gab_localops) / sizeof(OENTRY)));
954 }
955
956