1 /*
2 ugtabs.c: new implementation of table readers and writers
3
4 Copyright (C) 2013 V Lazzarini
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"
25 #include "ugtabs.h"
26 #include "ugens2.h"
27 #include <math.h>
28
29 //(x >= FL(0.0) ? (int32_t)x : (int32_t)((double)x - 0.99999999))
30 #define MYFLOOR(x) FLOOR(x)
31
isPowerOfTwo(unsigned int x)32 static inline unsigned int isPowerOfTwo (unsigned int x) {
33 return (x > 0) && !(x & (x - 1)) ? 1 : 0;
34 }
35
tabler_init(CSOUND * csound,TABL * p)36 int32_t tabler_init(CSOUND *csound, TABL *p) {
37
38 int32_t ndx, len;
39 int32_t mask;
40
41 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
42 return csound->InitError(csound,
43 Str("table: could not find ftable %d"),
44 (int32_t) *p->ftable);
45 len = p->ftp->flen;
46 mask = p->ftp->lenmask;
47 p->np2 = isPowerOfTwo(len) ? 0 : 1;
48
49 if (*p->mode)
50 p->mul = len;
51 else
52 p->mul = 1;
53
54 ndx = FLOOR((*p->ndx + *p->offset)*p->mul);
55 if (*p->wrap) {
56 if (p->np2) {
57 while(ndx >= len) ndx -= len;
58 while(ndx < 0) ndx += len;
59 }
60 else ndx &= mask;
61 } else {
62 if (UNLIKELY(ndx >= len)) ndx = len - 1;
63 else if (UNLIKELY(ndx < 0)) ndx = 0;
64 }
65 *p->sig = p->ftp->ftable[ndx];
66 return OK;
67 }
68
69
tabl_setup(CSOUND * csound,TABL * p)70 int32_t tabl_setup(CSOUND *csound, TABL *p) {
71 if(p->ftp == NULL) {
72 /* check for this only on first allocation */
73 if (UNLIKELY(IS_ASIG_ARG(p->ndx) != IS_ASIG_ARG(p->sig))) {
74 if (CS_KSMPS != 1)
75 return
76 csound->InitError(csound,
77 Str("table: index type inconsistent with output"));
78 }
79 }
80 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
81 return csound->InitError(csound,
82 Str("table: could not find ftable %d"),
83 (int32_t) *p->ftable);
84
85 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
86 if (*p->mode)
87 p->mul = p->ftp->flen;
88 else
89 p->mul = 1;
90 p->len = p->ftp->flen;
91
92 p->iwrap = (int32_t) *p->wrap;
93 return OK;
94 }
95
tabler_kontrol(CSOUND * csound,TABL * p)96 int32_t tabler_kontrol(CSOUND *csound, TABL *p) {
97 int32_t ndx, len = p->len;
98 int32_t mask = p->ftp->lenmask;
99 IGN(csound);
100
101 ndx = MYFLOOR((*p->ndx + *p->offset)*p->mul);
102 if (p->iwrap) {
103 if (p->np2) {
104 while(ndx >= len) ndx -= len;
105 while(ndx < 0) ndx += len;
106 }
107 else ndx &= mask;
108 } else {
109 if (UNLIKELY(ndx >= len)) ndx = len - 1;
110 else if (UNLIKELY(ndx < 0)) ndx = 0;
111 }
112 *p->sig = p->ftp->ftable[ndx];
113 return OK;
114 }
115
116
117
tabler_audio(CSOUND * csound,TABL * p)118 int32_t tabler_audio(CSOUND *csound, TABL *p)
119 {
120 IGN(csound);
121 int32_t ndx, len = p->len, n, nsmps = CS_KSMPS;
122 int32_t mask = p->ftp->lenmask;
123 MYFLT *sig = p->sig;
124 MYFLT *ndx_f = p->ndx;
125 MYFLT *func = p->ftp->ftable;
126 MYFLT offset = *p->offset;
127 MYFLT mul = p->mul;
128 int32_t iwrap = p->iwrap;
129 uint32_t koffset = p->h.insdshead->ksmps_offset;
130 uint32_t early = p->h.insdshead->ksmps_no_end;
131
132 if (UNLIKELY(koffset)) memset(sig, '\0', koffset*sizeof(MYFLT));
133 if (UNLIKELY(early)) {
134 nsmps -= early;
135 memset(&sig[nsmps], '\0', early*sizeof(MYFLT));
136 }
137
138 for (n=koffset; n < nsmps; n++) {
139 ndx = MYFLOOR((ndx_f[n] + offset)*mul);
140 if (iwrap) {
141 if (p->np2) {
142 while(ndx >= len) ndx -= len;
143 while(ndx < 0) ndx += len;
144 }
145 else ndx &= mask;
146 } else {
147 if (UNLIKELY(ndx >= len)) ndx = len - 1;
148 else if (UNLIKELY(ndx < 0)) ndx = 0;
149 }
150 p->sig[n] = func[ndx];
151 }
152
153 return OK;
154 }
155
tableir_init(CSOUND * csound,TABL * p)156 int32_t tableir_init(CSOUND *csound, TABL *p) {
157
158 int32_t ndx, len;
159 int32_t mask;
160 MYFLT tmp, frac;
161 MYFLT x1, x2;
162
163 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
164 return csound->InitError(csound,
165 Str("table: could not find ftable %d"),
166 (int32_t) *p->ftable);
167 len = p->ftp->flen;
168 p->np2 = isPowerOfTwo(len) ? 0 : 1;
169 mask = p->ftp->lenmask;
170
171 if (*p->mode)
172 p->mul = len;
173 else
174 p->mul = 1;
175
176 tmp = (*p->ndx + *p->offset)*p->mul;
177 ndx = MYFLOOR(tmp);
178 frac = tmp - ndx;
179
180 if (*p->wrap) {
181 if (p->np2) {
182 while(ndx >= len) ndx -= len;
183 while(ndx < 0) ndx += len;
184 }
185 else ndx &= mask;
186 } else {
187 if (UNLIKELY(ndx >= len)) ndx = len - 1;
188 else if (UNLIKELY(ndx < 0)) ndx = 0;
189 }
190 x1 = p->ftp->ftable[ndx];
191 x2 = p->ftp->ftable[ndx+1];
192 *p->sig = x1 + (x2 - x1)*frac;
193 return OK;
194 }
195
196
197
tableir_kontrol(CSOUND * csound,TABL * p)198 int32_t tableir_kontrol(CSOUND *csound, TABL *p) {
199 int32_t ndx, len = p->len;
200 int32_t mask = p->ftp->lenmask;
201 MYFLT tmp, frac;
202 MYFLT x1, x2;
203 IGN(csound);
204
205 tmp = (*p->ndx + *p->offset)*p->mul;
206 ndx = MYFLOOR(tmp);
207 frac = tmp - ndx;
208
209 if (p->iwrap) {
210 if (p->np2) {
211 while(ndx >= len) ndx -= len;
212 while(ndx < 0) ndx += len;
213 }
214 else ndx &= mask;
215 } else {
216 if (UNLIKELY(ndx >= len)) ndx = len - 1;
217 else if (UNLIKELY(ndx < 0)) ndx = 0;
218 }
219 x1 = p->ftp->ftable[ndx];
220 x2 = p->ftp->ftable[ndx+1];
221 *p->sig = x1 + (x2 - x1)*frac;
222 return OK;
223 }
224
tableir_audio(CSOUND * csound,TABL * p)225 int32_t tableir_audio(CSOUND *csound, TABL *p)
226 {
227 IGN(csound);
228 int32_t ndx, len = p->len, n, nsmps = CS_KSMPS;
229 int32_t mask = p->ftp->lenmask;
230 MYFLT *sig = p->sig;
231 MYFLT *ndx_f = p->ndx;
232 MYFLT *func = p->ftp->ftable;
233 MYFLT offset = *p->offset;
234 MYFLT mul = p->mul, tmp, frac;
235 int32_t iwrap = p->iwrap;
236 uint32_t koffset = p->h.insdshead->ksmps_offset;
237 uint32_t early = p->h.insdshead->ksmps_no_end;
238
239 if (UNLIKELY(koffset)) memset(sig, '\0', koffset*sizeof(MYFLT));
240 if (UNLIKELY(early)) {
241 nsmps -= early;
242 memset(&sig[nsmps], '\0', early*sizeof(MYFLT));
243 }
244
245 for (n=koffset; n < nsmps; n++) {
246 MYFLT x1, x2;
247 tmp = (ndx_f[n] + offset)*mul;
248 ndx = MYFLOOR(tmp);
249 frac = tmp - ndx;
250 if (iwrap) {
251 if (p->np2) {
252 while(ndx >= len) ndx -= len;
253 while(ndx < 0) ndx += len;
254 }
255 else ndx &= mask;
256 } else {
257 if (UNLIKELY(ndx >= len)) ndx = len - 1;
258 else if (UNLIKELY(ndx < 0)) ndx = 0;
259 }
260 x1 = func[ndx];
261 x2 = func[ndx+1];
262 p->sig[n] = x1 + (x2 - x1)*frac;
263 }
264
265 return OK;
266 }
267
table3r_init(CSOUND * csound,TABL * p)268 int32_t table3r_init(CSOUND *csound, TABL *p) {
269
270 int32_t ndx, len;
271 int32_t mask;
272 MYFLT tmp, frac;
273 MYFLT x0, x1, x2, x3;
274 MYFLT fracub, fracsq, temp1;
275 MYFLT *func;
276
277 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
278 return csound->InitError(csound,
279 Str("table: could not find ftable %d"),
280 (int32_t) *p->ftable);
281 len = p->ftp->flen;
282 mask = p->ftp->lenmask;
283 p->np2 = isPowerOfTwo(len) ? 0 : 1;
284 func =p->ftp->ftable;
285
286 if (*p->mode)
287 p->mul = len;
288 else
289 p->mul = 1;
290
291 tmp = (*p->ndx + *p->offset)*p->mul;
292 ndx = MYFLOOR(tmp);
293 frac = tmp - ndx;
294
295 if (*p->wrap) {
296 if (p->np2) {
297 while(ndx >= len) ndx -= len;
298 while(ndx < 0) ndx += len;
299 }
300 else ndx &= mask;
301 } else {
302 if (UNLIKELY(ndx >= len)) ndx = len - 1;
303 else if (UNLIKELY(ndx < 0)) ndx = 0;
304 }
305 if (UNLIKELY(ndx<1 || ndx==len-1 || len <4)) {
306 x1 = func[ndx];
307 x2 = func[ndx+1];
308 *p->sig = x1 + (x2 - x1)*frac;
309 } else {
310 x0 = func[ndx-1];
311 x1 = func[ndx];
312 x2 = func[ndx+1];
313 x3 = func[ndx+2];
314 fracsq = frac*frac;
315 fracub = fracsq*x0;
316 temp1 = x3+FL(3.0)*x1;
317 *p->sig = x1 + FL(0.5)*fracub +
318 frac*(x2 - fracub/FL(6.0) - temp1/FL(6.0) - x0/FL(3.0)) +
319 frac*fracsq*(temp1/FL(6.0) - FL(0.5)*x2) + fracsq*(FL(0.5)*x2 - x1);
320 }
321 return OK;
322 }
323
324
325
table3r_kontrol(CSOUND * csound,TABL * p)326 int32_t table3r_kontrol(CSOUND *csound, TABL *p) {
327 int32_t ndx, len = p->len;
328 int32_t mask = p->ftp->lenmask;
329 MYFLT tmp, frac;
330 MYFLT x0, x1, x2, x3;
331 MYFLT *func =p->ftp->ftable;
332 MYFLT fracub, fracsq, temp1;
333
334 IGN(csound);
335
336 tmp = (*p->ndx + *p->offset)*p->mul;
337 ndx = MYFLOOR(tmp);
338 frac = tmp - ndx;
339
340 if (p->iwrap) {
341 if (p->np2) {
342 while(ndx >= len) ndx -= len;
343 while(ndx < 0) ndx += len;
344 }
345 else ndx &= mask;
346 } else {
347 if (UNLIKELY(ndx >= len)) ndx = len - 1;
348 else if (UNLIKELY(ndx < 0)) ndx = 0;
349 }
350 if (UNLIKELY(ndx<1 || ndx==len-1 || len <4)) {
351 x1 = func[ndx];
352 x2 = func[ndx+1];
353 *p->sig = x1 + (x2 - x1)*frac;
354 } else {
355 x0 = func[ndx-1];
356 x1 = func[ndx];
357 x2 = func[ndx+1];
358 x3 = func[ndx+2];
359 fracsq = frac*frac;
360 fracub = fracsq*x0;
361 temp1 = x3+FL(3.0)*x1;
362 *p->sig = x1 + FL(0.5)*fracub +
363 frac*(x2 - fracub/FL(6.0) - temp1/FL(6.0) - x0/FL(3.0)) +
364 frac*fracsq*(temp1/FL(6.0) - FL(0.5)*x2) + fracsq*(FL(0.5)*x2 - x1);
365 }
366 return OK;
367 }
368
table3r_audio(CSOUND * csound,TABL * p)369 int32_t table3r_audio(CSOUND *csound, TABL *p)
370 {
371 IGN(csound);
372 int32_t ndx, len = p->len, n, nsmps = CS_KSMPS;
373 int32_t mask = p->ftp->lenmask;
374 MYFLT *sig = p->sig;
375 MYFLT *ndx_f = p->ndx;
376 MYFLT *func = p->ftp->ftable;
377 MYFLT offset = *p->offset;
378 MYFLT mul = p->mul, tmp, frac;
379 int32_t iwrap = p->iwrap;
380 uint32_t koffset = p->h.insdshead->ksmps_offset;
381 uint32_t early = p->h.insdshead->ksmps_no_end;
382
383 if (UNLIKELY(koffset)) memset(sig, '\0', koffset*sizeof(MYFLT));
384 if (UNLIKELY(early)) {
385 nsmps -= early;
386 memset(&sig[nsmps], '\0', early*sizeof(MYFLT));
387 }
388
389 for (n=koffset; n < nsmps; n++) {
390 MYFLT x0,x1,x2,x3,temp1,fracub,fracsq;
391 tmp = (ndx_f[n] + offset)*mul;
392 ndx = MYFLOOR(tmp);
393 frac = tmp - ndx;
394 if (iwrap) {
395 if (p->np2) {
396 while(ndx >= len) ndx -= len;
397 while(ndx < 0) ndx += len;
398 }
399 else ndx &= mask;
400 } else {
401 if (UNLIKELY(ndx >= len)) ndx = len - 1;
402 else if (UNLIKELY(ndx < 0)) ndx = 0;
403 }
404
405 if (UNLIKELY(ndx<1 || ndx==len-1 || len <4)) {
406 x1 = func[ndx];
407 x2 = func[ndx+1];
408 p->sig[n] = x1 + (x2 - x1)*frac;
409 } else {
410 x0 = func[ndx-1];
411 x1 = func[ndx];
412 x2 = func[ndx+1];
413 x3 = func[ndx+2];
414 fracsq = frac*frac;
415 fracub = fracsq*x0;
416 temp1 = x3+x1+x1+x1;
417 p->sig[n] = x1 + FL(0.5)*fracub +
418 frac*(x2 - fracub/FL(6.0) - temp1/FL(6.0) - x0/FL(3.0)) +
419 fracsq*frac*(temp1/FL(6.0) - FL(0.5)*x2) + fracsq*(FL(0.5)*x2 - x1);
420 }
421 }
422 return OK;
423 }
424
tablkt_setup(CSOUND * csound,TABL * p)425 int32_t tablkt_setup(CSOUND *csound, TABL *p) {
426
427 if (UNLIKELY(IS_ASIG_ARG(p->ndx) != IS_ASIG_ARG(p->sig))) {
428 if (CS_KSMPS != 1)
429 return
430 csound->InitError(csound,
431 Str("tablekt: index type inconsistent with output"));
432 }
433
434 p->iwrap = (int32_t) *p->wrap;
435 return OK;
436 }
437
tablerkt_kontrol(CSOUND * csound,TABL * p)438 int32_t tablerkt_kontrol(CSOUND *csound, TABL *p) {
439
440 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
441 return csound->PerfError(csound, &(p->h),
442 Str("table: could not find ftable %d"),
443 (int32_t) *p->ftable);
444 p->len = p->ftp->flen;
445 p->np2 = isPowerOfTwo(p->len) ? 0 : 1;
446 if (*p->mode)
447 p->mul = p->ftp->flen;
448 else
449 p->mul = 1;
450
451 return tabler_kontrol(csound,p);
452 }
453
454
tablerkt_audio(CSOUND * csound,TABL * p)455 int32_t tablerkt_audio(CSOUND *csound, TABL *p) {
456
457 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
458 return csound->PerfError(csound, &(p->h),
459 Str("table: could not find ftable %d"),
460 (int32_t) *p->ftable);
461 p->np2 = isPowerOfTwo(p->ftp->lenmask) ? 0 : 1;
462 if (*p->mode)
463 p->mul = p->ftp->flen;
464 else
465 p->mul = 1;
466 p->len = p->ftp->flen;
467
468 return tabler_audio(csound,p);
469 }
470
tableirkt_kontrol(CSOUND * csound,TABL * p)471 int32_t tableirkt_kontrol(CSOUND *csound, TABL *p) {
472
473 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
474 return csound->PerfError(csound, &(p->h),
475 Str("table: could not find ftable %d"),
476 (int32_t) *p->ftable);
477 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
478 if (*p->mode)
479 p->mul = p->ftp->flen;
480 else
481 p->mul = 1;
482 p->len = p->ftp->flen;
483
484 return tableir_kontrol(csound,p);
485 }
486
tableirkt_audio(CSOUND * csound,TABL * p)487 int32_t tableirkt_audio(CSOUND *csound, TABL *p)
488 {
489
490 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
491 return csound->PerfError(csound, &(p->h),
492 Str("table: could not find ftable %d"),
493 (int32_t) *p->ftable);
494 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
495 if (*p->mode)
496 p->mul = p->ftp->flen;
497 else
498 p->mul = 1;
499 p->len = p->ftp->flen;
500 return tableir_audio(csound,p);
501 }
502
table3rkt_kontrol(CSOUND * csound,TABL * p)503 int32_t table3rkt_kontrol(CSOUND *csound, TABL *p) {
504
505 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
506 return csound->PerfError(csound, &(p->h),
507 Str("table: could not find ftable %d"),
508 (int32_t) *p->ftable);
509 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
510 if (*p->mode)
511 p->mul = p->ftp->flen;
512 else
513 p->mul = 1;
514 p->len = p->ftp->flen;
515 return table3r_kontrol(csound,p);;
516 }
517
table3rkt_audio(CSOUND * csound,TABL * p)518 int32_t table3rkt_audio(CSOUND *csound, TABL *p) {
519
520 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
521 return csound->PerfError(csound, &(p->h),
522 Str("table: could not find ftable %d"),
523 (int32_t) *p->ftable);
524 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
525 if (*p->mode)
526 p->mul = p->ftp->flen;
527 else
528 p->mul = 1;
529 p->len = p->ftp->flen;
530 return table3r_audio(csound,p);
531 }
532
tablew_init(CSOUND * csound,TABL * p)533 int32_t tablew_init(CSOUND *csound, TABL *p) {
534
535 int32_t ndx, len;
536 int32_t mask;
537 MYFLT *func;
538 int32 iwrap = *p->wrap;
539
540 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
541 return csound->InitError(csound,
542 Str("table: could not find ftable %d"),
543 (int32_t) *p->ftable);
544 func = p->ftp->ftable;
545 mask = p->ftp->lenmask;
546 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
547 len = p->ftp->flen;
548
549 if (*p->mode)
550 p->mul = len;
551 else
552 p->mul = 1;
553
554 ndx = MYFLOOR((*p->ndx + *p->offset)*p->mul + (iwrap==2 ? 0.5:0));
555 if (iwrap) {
556 ndx = iwrap == 2 ? MYFLOOR(ndx+0.5) : ndx;
557 if (p->np2) {
558 while(ndx >= len) ndx -= len;
559 while(ndx < 0) ndx += len;
560 }
561 else ndx &= mask;
562 } else {
563 if (UNLIKELY(ndx >= len)) ndx = len - 1;
564 else if (UNLIKELY(ndx < 0)) ndx = 0;
565 }
566 p->ftp->ftable[ndx] = *p->sig;
567 if (ndx == 0 && iwrap==2) func[len] = func[ndx];
568 return OK;
569 }
570
tablew_kontrol(CSOUND * csound,TABL * p)571 int32_t tablew_kontrol(CSOUND *csound, TABL *p) {
572 int32_t ndx, len = p->len;
573 int32_t mask = p->ftp->lenmask;
574 MYFLT *func = p->ftp->ftable;
575 int32 iwrap = p->iwrap;
576 IGN(csound);
577
578 ndx = MYFLOOR((*p->ndx + *p->offset)*p->mul + (iwrap==2 ? 0.5:0));
579 if (iwrap) {
580 if (p->np2) {
581 while(ndx >= len) ndx -= len;
582 while(ndx < 0) ndx += len;
583 }
584 else ndx &= mask;
585 } else {
586 if (UNLIKELY(ndx >= len)) ndx = len - 1;
587 else if (UNLIKELY(ndx < 0)) ndx = 0;
588 }
589 func[ndx] = *p->sig;
590 if (ndx == 0 && iwrap==2) func[len] = func[ndx];
591 return OK;
592 }
593
tablew_audio(CSOUND * csound,TABL * p)594 int32_t tablew_audio(CSOUND *csound, TABL *p) {
595 IGN(csound);
596 int32_t ndx, len = p->len, n, nsmps = CS_KSMPS;
597 int32_t mask = p->ftp->lenmask;
598 MYFLT *sig = p->sig;
599 MYFLT *ndx_f = p->ndx;
600 MYFLT *func = p->ftp->ftable;
601 MYFLT offset = *p->offset;
602 MYFLT mul = p->mul;
603 int32 iwrap = p->iwrap;
604 uint32_t koffset = p->h.insdshead->ksmps_offset;
605 uint32_t early = p->h.insdshead->ksmps_no_end;
606
607 if (UNLIKELY(early)) nsmps -= early;
608
609 for (n=koffset; n < nsmps; n++) {
610 ndx = MYFLOOR((ndx_f[n] + offset)*mul + (iwrap==2 ? 0.5:0));
611 if (iwrap) {
612 if (p->np2) {
613 while(ndx >= len) ndx -= len;
614 while(ndx < 0) ndx += len;
615 }
616 else ndx &= mask;
617 } else {
618 if (UNLIKELY(ndx >= len)) ndx = len - 1;
619 else if (UNLIKELY(ndx < 0)) ndx = 0;
620 }
621 func[ndx] = sig[n];
622 if (iwrap==2 && ndx == 0) func[len] = func[ndx];
623 }
624 return OK;
625 }
626
tablewkt_kontrol(CSOUND * csound,TABL * p)627 int32_t tablewkt_kontrol(CSOUND *csound, TABL *p) {
628
629 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
630 return csound->PerfError(csound, &(p->h),
631 Str("table: could not find ftable %d"),
632 (int32_t) *p->ftable);
633 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
634 if (*p->mode)
635 p->mul = p->ftp->flen;
636 else
637 p->mul = 1;
638 p->len = p->ftp->flen;
639
640 return tablew_kontrol(csound,p);
641 }
642
643
tablewkt_audio(CSOUND * csound,TABL * p)644 int32_t tablewkt_audio(CSOUND *csound, TABL *p) {
645
646 if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
647 return csound->PerfError(csound, &(p->h),
648 Str("table: could not find ftable %d"),
649 (int32_t) *p->ftable);
650 p->np2 = isPowerOfTwo(p->ftp->flen) ? 0 : 1;
651 if (*p->mode)
652 p->mul = p->ftp->flen;
653 else
654 p->mul = 1;
655 p->len = p->ftp->flen;
656 return tablew_audio(csound,p);;
657 }
658
table_length(CSOUND * csound,TLEN * p)659 int32_t table_length(CSOUND *csound, TLEN *p) {
660 FUNC *ftp;
661 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->ftable)) == NULL)) {
662 csound->Warning(csound, Str("table: could not find ftable %d"),
663 (int32_t) *p->ftable);
664 *p->ans = FL(-1.0);
665 return NOTOK;
666 }
667 else *p->ans = (MYFLT) ftp->flen;
668 return OK;
669 }
670
table_gpw(CSOUND * csound,TGP * p)671 int32_t table_gpw(CSOUND *csound, TGP *p) {
672 FUNC *ftp;
673 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->ftable)) == NULL)) {
674 csound->Warning(csound,
675 Str("table: could not find ftable %d"),
676 (int32_t) *p->ftable);
677 return NOTOK;
678 }
679 ftp->ftable[ftp->flen] = ftp->ftable[0];
680 return OK;
681 }
682
table_copy(CSOUND * csound,TGP * p)683 int32_t table_copy(CSOUND *csound, TGP *p) {
684 FUNC *dest, *src;
685 int32 len1, len2, i, rp;
686 if (UNLIKELY((dest = csound->FTnp2Find(csound, p->ftable)) == NULL ||
687 (src = csound->FTnp2Find(csound, p->ftsrc)) == NULL)) {
688 csound->Warning(csound,
689 Str("table: could not find ftables %d and/or %d"),
690 (int32_t) *p->ftable, (int32_t) *p->ftsrc);
691 return NOTOK;
692 }
693 len1 = dest->flen;
694 len2 = src->flen;
695 for (i=rp=0; i<len1;i++) {
696 dest->ftable[i] = src->ftable[rp];
697 rp = rp == len2 ? 0 : rp+1;
698 }
699 return OK;
700 }
701
table_mix(CSOUND * csound,TABLMIX * p)702 int32_t table_mix(CSOUND *csound, TABLMIX *p) {
703 int32 np2, np21, np22;
704 FUNC *ftp, *ftp1, *ftp2;
705 int32 len, len1, len2, flen;
706 MYFLT g1, g2, *func, *func1, *func2;
707 int32 off, off1, off2;
708
709 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->tab)) == NULL)) {
710 csound->Warning(csound,
711 Str("table: could not find ftable %d"), (int32_t) *p->tab);
712 return NOTOK;
713 }
714 np2 = isPowerOfTwo(ftp->flen) ? 0 : 1;
715
716 if (UNLIKELY((ftp1 = csound->FTnp2Find(csound, p->tab1)) == NULL)) {
717 csound->Warning(csound,
718 Str("table: could not find ftable %d"), (int32_t) *p->tab1);
719 return NOTOK;
720 }
721 np21 = isPowerOfTwo(ftp->flen) ? 0 : 1;
722
723 if (UNLIKELY((ftp2 = csound->FTnp2Find(csound, p->tab2)) == NULL)) {
724 csound->Warning(csound,
725 Str("table: could not find ftable %d"), (int32_t) *p->tab2);
726 return NOTOK;
727 }
728 np22 = isPowerOfTwo(ftp2->flen) ? 0 : 1;
729
730 len = MYFLOOR(*p->len);
731 flen = ftp->flen;
732 len1 = ftp1->flen;
733 len2 = ftp2->flen;
734 func = ftp->ftable;
735 func1 = ftp1->ftable;
736 func2 = ftp2->ftable;
737 off = *p->off;
738 off1 = *p->off1;
739 off2 = *p->off2;
740 g1 = *p->g1;
741 g2 = *p->g2;
742
743 if (len>0) {
744 int32_t i, p0, p1, p2;
745 for (i=0; i < len; i++) {
746 p0 = i+off;
747 p1 = i+off1;
748 p2 = i+off2;
749 if (np2) {
750 while(p0 < 0) p0 += flen;
751 while(p0 >= len1) p0 -= flen;
752 }
753 else p0 &= ftp->lenmask;
754 if (np21) {
755 while(p1 < 0) p1 += len1;
756 while(p1 >= len1) p1 -= len1;
757 }
758 else p1 &= ftp1->lenmask;
759 if (np22) {
760 while (p2 < 0) p2 += len2;
761 while (p2 >= len2) p2 -= len2;
762 }
763 else p2 &= ftp2->lenmask;
764 func[p0] = func1[p1]*g1 + func2[p2]*g2;
765 }
766 } else {
767 int32_t i, p0, p1, p2;
768 for (i=0; i > len; i--) {
769 p0 = i+off;
770 p1 = i+off1;
771 p2 = i+off2;
772 if (np2) {
773 while(p0 < 0) p0 += flen;
774 while(p0 >= len1) p0 -= flen;
775 }
776 else p0 &= ftp->lenmask;
777 if (np21) {
778 while(p1 < 0) p1 += len1;
779 while(p1 >= len1) p1 -= len1;
780 }
781 else p1 &= ftp1->lenmask;
782 if (np22) {
783 while(p2 < 0) p2 += len2;
784 while(p2 >= len2) p2 -= len2;
785 }
786 else p2 &= ftp2->lenmask;
787 func[p0] = func1[p1]*g1 + func2[p2]*g2;
788 }
789 }
790 return OK;
791 }
792
table_ra_set(CSOUND * csound,TABLRA * p)793 int32_t table_ra_set(CSOUND *csound, TABLRA *p) {
794 IGN(csound);
795 IGN(p);
796 return OK;
797 }
798
table_ra(CSOUND * csound,TABLRA * p)799 int32_t table_ra(CSOUND *csound, TABLRA *p) {
800 int32 pos, np2, nsmps, len, i;
801 MYFLT *sig= p->sig, *func;
802 int32_t mask;
803 FUNC *ftp;
804 uint32_t koffset = p->h.insdshead->ksmps_offset;
805 uint32_t early = p->h.insdshead->ksmps_no_end;
806 nsmps = CS_KSMPS;
807
808 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
809 return csound->PerfError(csound, &(p->h),
810 Str("table: could not find ftable %d"),
811 (int32_t) *p->ftable);
812 np2 = isPowerOfTwo(ftp->flen) ? 0 : 1;
813
814 mask = ftp->lenmask;
815 pos = *p->strt + *p->off;
816
817 if (pos < 0)
818 return csound->PerfError(csound, &(p->h),
819 Str("table: could not read negative pos %d"), pos);
820
821 if (UNLIKELY(koffset)) memset(sig, '\0', koffset*sizeof(MYFLT));
822 if (UNLIKELY(early)) {
823 nsmps -= early;
824 memset(&sig[nsmps], '\0', early*sizeof(MYFLT));
825 }
826
827 func = ftp->ftable;
828 len = ftp->flen;
829 for (i=koffset; i < nsmps; i++) {
830 if (np2) pos %= len;
831 else pos &= mask;
832 sig[i] = func[pos];
833 pos++;
834 }
835
836 return OK;
837 }
838
table_wa_set(CSOUND * csound,TABLWA * p)839 int32_t table_wa_set(CSOUND *csound, TABLWA *p) {
840 IGN(csound);
841 if(!*p->skipinit) p->pos = 0;
842 p->pos += *p->off;
843 return OK;
844 }
845
table_wa(CSOUND * csound,TABLWA * p)846 int32_t table_wa(CSOUND *csound, TABLWA *p) {
847 int32 pos, np2, nsmps, len, i;
848 MYFLT *sig= p->sig, *func;
849 int32_t mask;
850 FUNC *ftp;
851 uint32_t koffset = p->h.insdshead->ksmps_offset;
852 uint32_t early = p->h.insdshead->ksmps_no_end;
853 nsmps = CS_KSMPS;
854
855 if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
856 return csound->PerfError(csound, &(p->h),
857 Str("table: could not find ftable %d"),
858 (int32_t) *p->ftable);
859 np2 = isPowerOfTwo(ftp->flen) ? 0 : 1;
860
861 mask = ftp->lenmask;
862 pos = p->pos; /*+ *p->off;*/
863
864 if (pos < 0)
865 return csound->PerfError(csound, &(p->h),
866 Str("table: could not read negative pos %d"), pos);
867
868 if (UNLIKELY(early)) nsmps -= early;
869
870 func = ftp->ftable;
871 len = ftp->flen;
872 for (i=koffset; i < nsmps; i++) {
873 if (np2) pos %= len;
874 else pos &= mask;
875 func[pos] = sig[i];
876 pos++;
877 }
878 p->pos = pos;
879 *p->strt = pos;
880 return OK;
881 }
882