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