1 /* aops.c:
2 
3   Copyright (C) 1991 Barry Vercoe, John ffitch, Gabriel Maldonado
4 
5   This file is part of Csound.
6 
7   The Csound Library is free software; you can redistribute it
8   and/or modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10   version 2.1 of the License, or (at your option) any later version.
11 
12   Csound is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU Lesser General Public License for more details.
16 
17   You should have received a copy of the GNU Lesser General Public
18   License along with Csound; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   02110-1301 USA
21 */
22 
23 #include "csoundCore.h" /*                                      AOPS.C  */
24 #include "aops.h"
25 #include <math.h>
26 #include <time.h>
27 
28 #define POW2TABSIZI 4096
29 #if ULONG_MAX == 18446744073709551615UL
30 #  define POW2MAX   (24.0)
31 #else
32 #  define POW2MAX   (15.0)
33 #endif
34 
35 #define EIPT3       (25.0/3.0)
36 #define LOGTWO      (0.69314718055994530942)
37 #define STEPS       (32768)
38 #define INTERVAL    (4.0)
39 #define ONEdLOG2    FL(1.4426950408889634074)
40 #define MIDINOTE0   (3.00)  /* Lowest midi note is 3.00 in oct & pch formats */
41 
42 /* initialise the tables, called by csoundPreCompile() */
csound_aops_init_tables(CSOUND * csound)43 void csound_aops_init_tables(CSOUND *csound)
44 {
45     int32_t   i;
46     if (csound->cpsocfrc==NULL)
47       csound->cpsocfrc = (MYFLT *) csound->Malloc(csound, sizeof(MYFLT)*OCTRES);
48     /* if (csound->powerof2==NULL) */
49     /*   csound->powerof2 = (MYFLT *) csound->Malloc(csound, */
50     /*                                               sizeof(MYFLT)*POW2TABSIZI); */
51     for (i = 0; i < OCTRES; i++)
52       csound->cpsocfrc[i] = POWER(FL(2.0), (MYFLT)i / OCTRES) * ONEPT;
53     /* for (i = 0; i < POW2TABSIZI; i++) { */
54     /*   csound->powerof2[i] = */
55     /*     POWER(FL(2.0), (MYFLT)i * (MYFLT)(1.0/POW2TABSIZI) - FL(POW2MAX)); */
56     /* } */
57 }
58 
59 
csoundPow2(CSOUND * csound,MYFLT a)60 MYFLT csoundPow2(CSOUND *csound, MYFLT a)
61 {
62     /* int32_t n; */
63     if (a > POW2MAX) a = POW2MAX;
64     else if (a < -POW2MAX) a = -POW2MAX;
65     return POWER(FL(2.0), a);
66     /* 4096 * 15 */
67     /* n = (int32_t)MYFLT2LRND(a * FL(POW2TABSIZI)) + POW2MAX*POW2TABSIZI; */
68     /* return ((MYFLT) (1UL << (n >> 12)) * csound->powerof2[n & (POW2TABSIZI-1)]); */
69 }
70 
71 
72 /*static inline MYFLT pow2(MYFLT a)
73 {
74     int32_t n = (int32_t)MYFLT2LRND(a * FL(POW2TABSIZI)) + POW2MAX*POW2TABSIZI;
75     return ((MYFLT) (1 << (n >> 12)) * powerof2[n & (POW2TABSIZI-1)]);
76 }*/
77 
rassign(CSOUND * csound,ASSIGN * p)78 int32_t rassign(CSOUND *csound, ASSIGN *p)
79 {
80     /* already assigned by otran */
81     IGN(csound);
82     IGN(p);
83     return OK;
84 }
85 
assign(CSOUND * csound,ASSIGN * p)86 int32_t assign(CSOUND *csound, ASSIGN *p)
87 {
88     IGN(csound);
89     *p->r = *p->a;
90     return OK;
91 }
92 
aassign(CSOUND * csound,ASSIGN * p,int32_t islocal)93 int32_t aassign(CSOUND *csound, ASSIGN *p, int32_t islocal)
94 {
95     IGN(csound);
96     uint32_t nsmps = CS_KSMPS;
97     if (LIKELY(nsmps!=1)) {
98       uint32_t offset = p->h.insdshead->ksmps_offset;
99       uint32_t early  = p->h.insdshead->ksmps_no_end;
100       uint32_t nsmps = CS_KSMPS;
101       /* the orchestra parser converts '=' to 'upsamp' if input arg is k-rate, */
102       /* and skips the opcode if outarg == inarg */
103       if (UNLIKELY(islocal &&offset)) memset(p->r, '\0', offset*sizeof(MYFLT));
104       if (UNLIKELY(early)) {
105         nsmps -= early;
106         if (islocal) memset(&p->r[nsmps], '\0', early*sizeof(MYFLT));
107       }
108       memcpy(&p->r[offset], &p->a[offset], (nsmps-offset) * sizeof(MYFLT));
109     }
110     else
111       *p->r =*p->a;
112     return OK;
113 }
114 
gaassign(CSOUND * csound,ASSIGN * p)115 int32_t gaassign(CSOUND *csound, ASSIGN *p)
116 {   return aassign(csound, p, 0); }
117 
laassign(CSOUND * csound,ASSIGN * p)118 int32_t laassign(CSOUND *csound, ASSIGN *p)
119 {   return aassign(csound, p, 1); }
120 
ainit(CSOUND * csound,ASSIGN * p)121 int32_t ainit(CSOUND *csound, ASSIGN *p)
122 {
123     IGN(csound);
124     uint32_t offset = p->h.insdshead->ksmps_offset;
125     uint32_t early  = p->h.insdshead->ksmps_no_end;
126     MYFLT aa = *p->a;
127     int32_t   n, nsmps = CS_KSMPS;
128     if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT));
129     if (UNLIKELY(early)) {
130       nsmps -= early;
131       memset(&p->r[nsmps], '\0', early*sizeof(MYFLT));
132     }
133     for (n = offset; n < nsmps; n++)
134       p->r[n] = aa;
135     return OK;
136 }
137 
minit(CSOUND * csound,ASSIGNM * p)138 int32_t minit(CSOUND *csound, ASSIGNM *p)
139 {
140     uint32_t nargs = p->INCOUNT;
141     uint32_t nout = p->OUTOCOUNT;
142     uint32_t i;
143     MYFLT *tmp;
144     if (UNLIKELY(nargs > p->OUTOCOUNT))
145       return csound->InitError(csound,
146                                Str("Cannot be more In arguments than Out in "
147                                    "init (%d,%d)"),p->OUTOCOUNT, nargs);
148     if (nout==1) {
149       *p->r[0] =  *p->a[0];
150       return OK;
151     }
152     tmp = (MYFLT*)csound->Malloc(csound, sizeof(MYFLT)*p->OUTOCOUNT);
153     for (i=0; i<nargs; i++)
154       tmp[i] =  *p->a[i];
155     for (; i<nout; i++)
156       tmp[i] =  *p->a[nargs-1];
157     for (i=0; i<nout; i++)
158       *p->r[i] = tmp[i];
159     csound->Free(csound, tmp);
160     return OK;
161 }
162 
mainit(CSOUND * csound,ASSIGNM * p)163 int32_t mainit(CSOUND *csound, ASSIGNM *p)
164 {
165     uint32_t nargs = p->INCOUNT;
166     uint32_t nouts = p->OUTOCOUNT;
167     uint32_t offset = p->h.insdshead->ksmps_offset;
168     uint32_t early  = p->h.insdshead->ksmps_no_end;
169     uint32_t i, n, nsmps = CS_KSMPS;
170     MYFLT aa = FL(0.0);
171     early = nsmps - early;      /* Bit at end to ignore */
172     if (UNLIKELY(nargs > nouts))
173       return csound->InitError(csound,
174                                Str("Cannot be more In arguments than Out in "
175                                    "init (%d,%d)"),p->OUTOCOUNT, nargs);
176     for (i=0; i<nargs; i++) {
177       aa = *p->a[i];
178       MYFLT *r =p->r[i];
179       for (n = 0; n < nsmps; n++)
180         r[n] = (n < offset || n > early ? FL(0.0) : aa);
181     }
182     for (; i<nouts; i++) {
183       MYFLT *r =p->r[i];
184       memset(r, '\0', nsmps*sizeof(MYFLT));
185       for (n = 0; n < nsmps; n++)
186         r[n] = (n < offset || n > early ? FL(0.0) : aa);
187     }
188 
189     return OK;
190 }
191 
192 
signum(CSOUND * csound,ASSIGN * p)193 int32_t signum(CSOUND *csound, ASSIGN *p)
194 {
195     IGN(csound);
196     MYFLT a = *p->a;
197     int32_t ans = (a==FL(0.0) ? 0 : a<FL(0.0) ? -1 : 1);
198     *p->r = (MYFLT) ans;
199     return OK;
200 }
201 
asignum(CSOUND * csound,ASSIGN * p)202 int32_t asignum(CSOUND *csound, ASSIGN *p)
203 {
204     IGN(csound);
205     uint32_t offset = p->h.insdshead->ksmps_offset;
206     uint32_t early  = p->h.insdshead->ksmps_no_end;
207     uint32_t   i, nsmps = CS_KSMPS;
208     MYFLT *a = p->a;
209     memset(p->r, '\0', nsmps*sizeof(MYFLT));
210     early = nsmps-early;
211     for (i=offset; i<early; i++) {
212       MYFLT aa = a[i];
213       int32_t ans = (aa==FL(0.0) ? 0 : aa<FL(0.0) ? -1 : 1);
214       p->r[i] = (MYFLT) ans;
215     }
216     return OK;
217 }
218 
219 #define RELATN(OPNAME,OP)                                \
220   int32_t OPNAME(CSOUND *csound, RELAT *p)               \
221   {   IGN(csound); *p->rbool = (*p->a OP *p->b) ? 1 : 0; \
222        return OK; }
223 
224 RELATN(gt,>)
225 RELATN(ge,>=)
226 RELATN(lt,<)
227 RELATN(le,<=)
228 RELATN(eq,==)
229 RELATN(ne,!=)
230 
b_not(CSOUND * csound,LOGCL * p)231 int32_t b_not(CSOUND *csound, LOGCL *p)
232 {
233     IGN(csound); *p->rbool = (*p->ibool) ? 0 : 1; return OK; }
234 
235 #define LOGCLX(OPNAME,OP)                                       \
236   int32_t OPNAME(CSOUND *csound, LOGCL *p)                      \
237   { IGN(csound);*p->rbool = (*p->ibool OP *p->jbool) ? 1 : 0; return OK; }
238 
239 LOGCLX(and,&&)
240 LOGCLX(or,||)
241 
242 #define KK(OPNAME,OP)                                           \
243   int32_t OPNAME(CSOUND *csound, AOP *p)                        \
244   { IGN(csound); *p->r = *p->a OP *p->b; return OK; }
245 
246 KK(addkk,+)
247 KK(subkk,-)
248 KK(mulkk,*)
249 //KK(divkk,/)
divkk(CSOUND * csound,AOP * p)250 int32_t divkk(CSOUND *csound, AOP *p)
251 {
252     MYFLT div = *p->b;
253     IGN(csound);
254     if (UNLIKELY(div==FL(0.0)))
255       csound->Warning(csound, Str("Division by zero"));
256     *p->r = *p->a / div;
257     return OK;
258 }
259 
MOD(MYFLT a,MYFLT bb)260 MYFLT MOD(MYFLT a, MYFLT bb)
261 {
262     if (UNLIKELY(bb==FL(0.0))) return FL(0.0);
263     else {
264       MYFLT b = (bb<0 ? -bb : bb);
265       MYFLT d = FMOD(a, b);
266       while (d>b) d -= b;
267       while (-d>b) d += b;
268       return d;
269   }
270 }
271 
modkk(CSOUND * csound,AOP * p)272 int32_t modkk(CSOUND *csound, AOP *p)
273 {
274     IGN(csound);
275     *p->r = MOD(*p->a, *p->b);
276     return OK;
277 }
278 
279 #define KA(OPNAME,OP)                                  \
280   int32_t OPNAME(CSOUND *csound, AOP *p) {             \
281     uint32_t n, nsmps = CS_KSMPS;                      \
282     IGN(csound);                                       \
283     if (LIKELY(nsmps!=1)) {                            \
284       MYFLT   *r, a, *b;                               \
285       uint32_t offset = p->h.insdshead->ksmps_offset;  \
286       uint32_t early  = p->h.insdshead->ksmps_no_end;  \
287       r = p->r;                                        \
288       a = *p->a;                                       \
289       b = p->b;                                        \
290       if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT)); \
291       if (UNLIKELY(early)) {                           \
292         nsmps -= early;                                \
293         memset(&r[nsmps], '\0', early*sizeof(MYFLT));  \
294       }                                                \
295       for (n=offset; n<nsmps; n++)                     \
296         r[n] = a OP b[n];                              \
297       return OK;                                       \
298     }                                                  \
299     else {                                             \
300         *p->r = *p->a OP *p->b;                        \
301       return OK;                                       \
302     }                                                  \
303   }
304 
305 
306 KA(addka,+)
307 KA(subka,-)
308 KA(mulka,*)
309 KA(divka,/)
310 
modka(CSOUND * csound,AOP * p)311 int32_t modka(CSOUND *csound, AOP *p)
312 {
313     IGN(csound);
314     MYFLT   *r, a, *b;
315     uint32_t offset = p->h.insdshead->ksmps_offset;
316     uint32_t early  = p->h.insdshead->ksmps_no_end;
317     uint32_t n, nsmps = CS_KSMPS;
318 
319     r = p->r;
320     a = *p->a;
321     b = p->b;
322     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
323     if (UNLIKELY(early)) {
324       nsmps -= early;
325       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
326     }
327     for (n=offset; n<nsmps; n++)
328       r[n] = MOD(a, b[n]);
329     return OK;
330 }
331 
332 #define AK(OPNAME,OP)                           \
333   int32_t OPNAME(CSOUND *csound, AOP *p) {      \
334     uint32_t n, nsmps = CS_KSMPS;               \
335     IGN(csound);                                \
336     if (LIKELY(nsmps != 1)) {                   \
337       MYFLT   *r, *a, b;                        \
338       uint32_t offset = p->h.insdshead->ksmps_offset;  \
339       uint32_t early  = p->h.insdshead->ksmps_no_end;  \
340       r = p->r;                                 \
341       a = p->a;                                 \
342       b = *p->b;                                \
343       if (UNLIKELY(offset))                     \
344         memset(r, '\0', offset*sizeof(MYFLT));  \
345       if (UNLIKELY(early)) {                    \
346         nsmps -= early;                         \
347         memset(&r[nsmps], '\0', early*sizeof(MYFLT)); \
348       }                                         \
349       for (n=offset; n<nsmps; n++)              \
350         r[n] = a[n] OP b;                       \
351       return OK;                                \
352     }                                           \
353     else {                                      \
354       p->r[0] = p->a[0] OP *p->b;               \
355       return OK;                                \
356     }                                           \
357 }
358 
359 AK(addak,+)
360 AK(subak,-)
361 AK(mulak,*)
362 //AK(divak,/)
divak(CSOUND * csound,AOP * p)363 int32_t divak(CSOUND *csound, AOP *p) {
364     uint32_t n, nsmps = CS_KSMPS;
365     MYFLT b = *p->b;
366     if (LIKELY(nsmps != 1)) {
367       MYFLT   *r, *a;
368       uint32_t offset = p->h.insdshead->ksmps_offset;
369       uint32_t early  = p->h.insdshead->ksmps_no_end;
370       r = p->r;
371       a = p->a;
372       b = *p->b;
373       if (UNLIKELY(b==FL(0.0)))
374         csound->Warning(csound, Str("Division by zero"));
375       if (UNLIKELY(offset))
376         memset(r, '\0', offset*sizeof(MYFLT));
377       if (UNLIKELY(early)) {
378         nsmps -= early;
379         memset(&r[nsmps], '\0', early*sizeof(MYFLT));
380       }
381       for (n=offset; n<nsmps; n++)
382         r[n] = a[n] / b;
383       return OK;
384     }
385     else {
386       if (UNLIKELY(b==FL(0.0)))
387         csound->Warning(csound, Str("Division by zero"));
388       p->r[0] = p->a[0] / b;
389       return OK;
390     }
391 }
392 
393 
modak(CSOUND * csound,AOP * p)394 int32_t modak(CSOUND *csound, AOP *p)
395 {
396     IGN(csound);
397     MYFLT   *r, *a, b;
398     uint32_t offset = p->h.insdshead->ksmps_offset;
399     uint32_t early  = p->h.insdshead->ksmps_no_end;
400     uint32_t n, nsmps = CS_KSMPS;
401 
402     r = p->r;
403     a = p->a;
404     b = *p->b;
405     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
406     if (UNLIKELY(early)) {
407       nsmps -= early;
408       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
409     }
410     for (n=offset; n<nsmps; n++)
411       r[n] = MOD(a[n], b);
412     return OK;
413 }
414 
415 #define AA(OPNAME,OP)                           \
416   int32_t OPNAME(CSOUND *csound, AOP *p) {      \
417   MYFLT   *r, *a, *b;                           \
418   IGN(csound);                                  \
419   uint32_t n, nsmps = CS_KSMPS;                 \
420   if (LIKELY(nsmps!=1)) {                       \
421     uint32_t offset = p->h.insdshead->ksmps_offset;  \
422     uint32_t early  = p->h.insdshead->ksmps_no_end;  \
423     r = p->r;                                   \
424     a = p->a;                                   \
425     b = p->b;                                   \
426     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT)); \
427     if (UNLIKELY(early)) {                      \
428       nsmps -= early;                           \
429       memset(&r[nsmps], '\0', early*sizeof(MYFLT)); \
430     }                                           \
431     for (n=offset; n<nsmps; n++)                \
432       r[n] = a[n] OP b[n];                      \
433     return OK;                                  \
434   }                                             \
435     else {                                      \
436       *p->r = *p->a OP *p->b;                   \
437       return OK;                                \
438     }                                           \
439   }
440 
441 /* VL
442    experimental code using SSE for operations
443    needs memory alignment - 16 bytes
444 */
445 #ifdef USE_SSE
446 #include "emmintrin.h"
447 #define AA_VEC(OPNAME,OP)                   \
448 int32_t OPNAME(CSOUND *csound, AOP *p){     \
449   MYFLT   *r, *a, *b;                       \
450   __m128d va, vb;                           \
451   uint32_t n, nsmps = CS_KSMPS, end;        \
452   if (LIKELY(nsmps!=1)) {                   \
453   uint32_t offset = p->h.insdshead->ksmps_offset; \
454   uint32_t early  = p->h.insdshead->ksmps_no_end; \
455   r = p->r; a = p->a; b = p->b;             \
456   if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT)); \
457   if (UNLIKELY(early)) {                    \
458       nsmps -= early;                       \
459       memset(&r[nsmps], '\0', early*sizeof(MYFLT));  \
460   } \
461   end = nsmps; \
462   for (n=offset; n<end; n+=2) { \
463    va = _mm_loadu_pd(&a[n]); \
464    vb = _mm_loadu_pd(&b[n]); \
465    va = OP(va,vb);\
466    _mm_storeu_pd(&r[n],va); \
467   }     \
468   return OK; \
469   } \
470    else { \
471      *p->r = *p->a + *p->b;\
472       return OK; \
473    }             \
474 } \
475 
AA_VEC(addaa,_mm_add_pd)476 AA_VEC(addaa,_mm_add_pd)
477 AA_VEC(subaa,_mm_sub_pd)
478 AA_VEC(mulaa,_mm_mul_pd)
479 AA_VEC(divaa,_mm_div_pd)
480 
481 #else
482 AA(addaa,+)
483 AA(subaa,-)
484 AA(mulaa,*)
485 //AA(divaa,/)
486 #endif
487 
488 int32_t divaa(CSOUND *csound, AOP *p)
489 {
490     MYFLT   *r, *a, *b;
491     int     err = 0;
492     IGN(csound);
493     uint32_t n, nsmps = CS_KSMPS;
494     if (LIKELY(nsmps!=1)) {
495       uint32_t offset = p->h.insdshead->ksmps_offset;
496       uint32_t early  = p->h.insdshead->ksmps_no_end;
497       r = p->r;
498       a = p->a;
499       b = p->b;
500       if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
501       if (UNLIKELY(early)) {
502         nsmps -= early;
503         memset(&r[nsmps], '\0', early*sizeof(MYFLT));
504       }
505       for (n=offset; n<nsmps; n++ ) {
506         MYFLT bb = b[n];
507         if (UNLIKELY(bb==FL(0.0) && err==0)) {
508           csound->Warning(csound, Str("Division by zero"));
509           err = 1;
510         }
511         r[n] = a[n] / bb;
512       }
513       return OK;
514     }
515     else {
516       if (UNLIKELY(*p->b==FL(0.0)))
517         csound->Warning(csound, Str("Division by zero"));
518       *p->r = *p->a / *p->b;
519       return OK;
520     }
521 }
522 
modaa(CSOUND * csound,AOP * p)523   int32_t modaa(CSOUND *csound, AOP *p)
524 {
525     MYFLT   *r, *a, *b;
526     IGN(csound);
527     uint32_t offset = p->h.insdshead->ksmps_offset;
528     uint32_t early  = p->h.insdshead->ksmps_no_end;
529     uint32_t n, nsmps = CS_KSMPS;
530 
531     r = p->r;
532     a = p->a;
533     b = p->b;
534     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
535     if (UNLIKELY(early)) {
536       nsmps -= early;
537       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
538     }
539     for (n=offset; n<nsmps; n++)
540       r[n] = MOD(a[n], b[n]);
541     return OK;
542 }
543 
divzkk(CSOUND * csound,DIVZ * p)544 int32_t divzkk(CSOUND *csound, DIVZ *p)
545 {
546     IGN(csound);
547     *p->r = (*p->b != FL(0.0) ? *p->a / *p->b : *p->def);
548     return OK;
549 }
550 
divzka(CSOUND * csound,DIVZ * p)551 int32_t divzka(CSOUND *csound, DIVZ *p)
552 {
553     uint32_t n;
554     IGN(csound);
555     MYFLT    *r, a, *b, def;
556     uint32_t offset = p->h.insdshead->ksmps_offset;
557     uint32_t early  = p->h.insdshead->ksmps_no_end;
558     uint32_t nsmps = CS_KSMPS;
559 
560     r = p->r;
561     a = *p->a;
562     b = p->b;
563     def = *p->def;
564     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
565     if (UNLIKELY(early)) {
566       nsmps -= early;
567       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
568     }
569      for (n=offset; n<nsmps; n++) {
570       MYFLT bb = b[n];
571       r[n] = (bb==FL(0.0) ? def : a / bb);
572     }
573     return OK;
574 }
575 
divzak(CSOUND * csound,DIVZ * p)576 int32_t divzak(CSOUND *csound, DIVZ *p)
577 {
578     uint32_t n;
579     IGN(csound);
580     MYFLT    *r, *a, b, def;
581     uint32_t offset = p->h.insdshead->ksmps_offset;
582     uint32_t early  = p->h.insdshead->ksmps_no_end;
583     uint32_t nsmps = CS_KSMPS;
584 
585     r = p->r;
586     a = p->a;
587     b = *p->b;
588     def = *p->def;
589     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
590     if (UNLIKELY(early)) {
591       nsmps -= early;
592       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
593     }
594     if (UNLIKELY(b==FL(0.0))) {
595       for (n=offset; n<nsmps; n++) r[n] = def;
596     }
597     else {
598       for (n=offset; n<nsmps; n++) r[n] = a[n] / b;
599     }
600     return OK;
601 }
602 
divzaa(CSOUND * csound,DIVZ * p)603 int32_t divzaa(CSOUND *csound, DIVZ *p)
604 {
605     uint32_t n;
606     IGN(csound);
607     MYFLT    *r, *a, *b, def;
608     uint32_t offset = p->h.insdshead->ksmps_offset;
609     uint32_t early  = p->h.insdshead->ksmps_no_end;
610     uint32_t nsmps = CS_KSMPS;
611 
612     r = p->r;
613     a = p->a;
614     b = p->b;
615     def = *p->def;
616     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
617     if (UNLIKELY(early)) {
618       nsmps -= early;
619       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
620     }
621     for (n=offset; n<nsmps; n++) {
622       MYFLT bb=b[n];
623       r[n] = (bb==FL(0.0) ? def : a[n] / bb);
624     }
625     return OK;
626 }
627 
conval(CSOUND * csound,CONVAL * p)628 int32_t conval(CSOUND *csound, CONVAL *p)
629 {
630     IGN(csound);
631     if (*p->cond)
632       *p->r = *p->a;
633     else
634       *p->r = *p->b;
635     return OK;
636 }
637 
aconval(CSOUND * csound,CONVAL * p)638 int32_t aconval(CSOUND *csound, CONVAL *p)
639 {
640     uint32_t offset = p->h.insdshead->ksmps_offset*sizeof(MYFLT);
641     uint32_t early  = p->h.insdshead->ksmps_no_end*sizeof(MYFLT);
642     MYFLT   *r, *s;
643     IGN(csound);
644 
645     r = p->r;
646     if (*p->cond)
647       s = p->a;
648     else s = p->b;
649     if (r!=s) {
650       memset(r, '\0', offset);
651       memcpy(&r[offset], &s[offset], CS_KSMPS*sizeof(MYFLT)-offset-early);
652       memset(&r[offset-early], '\0', early);
653     }
654     return OK;
655 }
656 
int1(CSOUND * csound,EVAL * p)657 int32_t int1(CSOUND *csound, EVAL *p)               /* returns signed whole no. */
658 {
659     MYFLT intpart;
660     IGN(csound);
661     MODF(*p->a, &intpart);
662     *p->r = intpart;
663     return OK;
664 }
665 
int1a(CSOUND * csound,EVAL * p)666 int32_t int1a(CSOUND *csound, EVAL *p)              /* returns signed whole no. */
667 {
668     MYFLT        intpart, *a=p->a, *r=p->r;
669     uint32_t offset = p->h.insdshead->ksmps_offset;
670     uint32_t early  = p->h.insdshead->ksmps_no_end;
671     uint32_t n, nsmps =CS_KSMPS;
672     IGN(csound);
673 
674     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
675     if (UNLIKELY(early)) {
676       nsmps -= early;
677       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
678     }
679     for (n = offset; n < nsmps; n++) {
680       MODF(a[n], &intpart);
681       r[n] = intpart;
682     }
683     return OK;
684 }
685 
frac1(CSOUND * csound,EVAL * p)686 int32_t frac1(CSOUND *csound, EVAL *p)              /* returns positive frac part */
687 {
688     MYFLT intpart, fracpart;
689     IGN(csound);
690     fracpart = MODF(*p->a, &intpart);
691     *p->r = fracpart;
692     return OK;
693 }
694 
frac1a(CSOUND * csound,EVAL * p)695 int32_t frac1a(CSOUND *csound, EVAL *p)             /* returns positive frac part */
696 {
697     MYFLT intpart, fracpart, *r = p->r, *a = p->a;
698     uint32_t offset = p->h.insdshead->ksmps_offset;
699     uint32_t early  = p->h.insdshead->ksmps_no_end;
700     uint32_t n, nsmps =CS_KSMPS;
701     IGN(csound);
702 
703     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
704     if (UNLIKELY(early)) {
705       nsmps -= early;
706       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
707     }
708     for (n = offset; n < nsmps; n++) {
709       fracpart = MODF(a[n], &intpart);
710       r[n] = fracpart;
711     }
712     return OK;
713 }
714 
715 #ifdef MYFLOOR
716 #undef MYFLOOR
717 #endif
718 #define MYFLOOR(x) ((int32_t)((double)(x) >= 0.0 ? (x) : (x) - 0.99999999))
719 
720 #ifdef MYCEIL
721 #undef MYCEIL
722 #endif
723 #define MYCEIL(x) ((int32_t)((double)(x) >= 0.0 ? (x) + 0.99999999 : (x)))
724 
int1_round(CSOUND * csound,EVAL * p)725 int32_t int1_round(CSOUND *csound, EVAL *p)         /* round to nearest integer */
726 {
727     IGN(csound);
728     *p->r = (MYFLT) MYFLT2LRND(*p->a);
729     return OK;
730 }
731 
int1a_round(CSOUND * csound,EVAL * p)732 int32_t int1a_round(CSOUND *csound, EVAL *p)        /* round to nearest integer */
733 {
734     uint32_t offset = p->h.insdshead->ksmps_offset;
735     uint32_t early  = p->h.insdshead->ksmps_no_end;
736     uint32_t n, nsmps =CS_KSMPS;
737     MYFLT *r=p->r, *a=p->a;
738     IGN(csound);
739 
740     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
741     if (UNLIKELY(early)) {
742       nsmps -= early;
743       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
744     }
745     for (n = offset; n < nsmps; n++)
746       r[n] = (MYFLT)MYFLT2LRND(a[n]);
747     return OK;
748 }
749 
int1_floor(CSOUND * csound,EVAL * p)750 int32_t int1_floor(CSOUND *csound, EVAL *p)         /* round down */
751 {
752     IGN(csound);
753     *p->r = (MYFLT)(MYFLOOR(*p->a));
754     return OK;
755 }
756 
int1a_floor(CSOUND * csound,EVAL * p)757 int32_t int1a_floor(CSOUND *csound, EVAL *p)        /* round down */
758 {
759     MYFLT    *a=p->a, *r=p->r;
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     IGN(csound);
764 
765     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
766     if (UNLIKELY(early)) {
767       nsmps -= early;
768       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
769     }
770     for (n = offset; n < nsmps; n++)
771       r[n] = (MYFLT)(MYFLOOR(a[n]));
772     return OK;
773 }
774 
int1_ceil(CSOUND * csound,EVAL * p)775 int32_t int1_ceil(CSOUND *csound, EVAL *p)          /* round up */
776 {
777     IGN(csound);
778     *p->r = (MYFLT)(MYCEIL(*p->a));
779     return OK;
780 }
781 
int1a_ceil(CSOUND * csound,EVAL * p)782 int32_t int1a_ceil(CSOUND *csound, EVAL *p)         /* round up */
783 {
784     MYFLT    *a=p->a, *r=p->r;
785     uint32_t offset = p->h.insdshead->ksmps_offset;
786     uint32_t early  = p->h.insdshead->ksmps_no_end;
787     uint32_t n, nsmps =CS_KSMPS;
788     IGN(csound);
789 
790     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
791     if (UNLIKELY(early)) {
792       nsmps -= early;
793       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
794     }
795     for (n = offset; n < nsmps; n++)
796       r[n] = (MYFLT)(MYCEIL(a[n]));
797     return OK;
798 }
799 
800 #define rndmlt (105.947)
801 
rnd1seed(CSOUND * csound,INM * p)802 int32_t rnd1seed(CSOUND *csound, INM *p)
803 {
804     double intpart;
805     csound->rndfrac = modf(*p->ar, &intpart);
806     return OK;
807 }
808 
rnd1(CSOUND * csound,EVAL * p)809 int32_t rnd1(CSOUND *csound, EVAL *p)               /* returns unipolar rand(x) */
810 {
811     double intpart;
812     csound->rndfrac = modf(csound->rndfrac * rndmlt, &intpart);
813     *p->r = *p->a * (MYFLT)csound->rndfrac;
814     return OK;
815 }
816 
birnd1(CSOUND * csound,EVAL * p)817 int32_t birnd1(CSOUND *csound, EVAL *p)             /* returns bipolar rand(x) */
818 {
819     double intpart;
820     csound->rndfrac = modf(csound->rndfrac * rndmlt, &intpart);
821     *p->r = *p->a * (FL(2.0) * (MYFLT)csound->rndfrac - FL(1.0));
822     return OK;
823 }
824 
825 #define LIB1(OPNAME,LIBNAME)  int32_t OPNAME(CSOUND *csound, EVAL *p)       \
826   {  IGN(csound); *p->r = LIBNAME(*p->a); return OK; }
LIB1(abs1,FABS)827 LIB1(abs1,FABS)
828 LIB1(exp01,EXP)
829 LIB1(log01,LOG)
830 LIB1(sqrt1,SQRT)
831 LIB1(sin1,SIN)
832 LIB1(cos1,COS)
833 LIB1(tan1,TAN)
834 LIB1(asin1,ASIN)
835 LIB1(acos1,ACOS)
836 LIB1(atan1,ATAN)
837 LIB1(sinh1,SINH)
838 LIB1(cosh1,COSH)
839 LIB1(tanh1,TANH)
840 LIB1(log101,LOG10)
841 LIB1(log21,LOG2)
842 
843 int32_t atan21(CSOUND *csound, AOP *p)
844 {
845     IGN(csound);
846     *p->r = ATAN2(*p->a, *p->b);
847     return OK;
848 }
849 
850 #define LIBA(OPNAME,LIBNAME) int32_t OPNAME(CSOUND *csound, EVAL *p) {      \
851     IGN(csound); \
852     uint32_t offset = p->h.insdshead->ksmps_offset;                     \
853     uint32_t early  = p->h.insdshead->ksmps_no_end;                     \
854     uint32_t n, nsmps =CS_KSMPS;                                        \
855     MYFLT   *r, *a;                                                     \
856     r = p->r;                                                           \
857     a = p->a;                                                           \
858     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));        \
859     if (UNLIKELY(early)) {                                              \
860       nsmps -= early;                                                   \
861       memset(&r[nsmps], '\0', early*sizeof(MYFLT));                     \
862     }                                                                   \
863     for (n = offset; n < nsmps; n++)                                    \
864       r[n] = LIBNAME(a[n]);                                             \
865     return OK;                                                          \
866   }
LIBA(absa,FABS)867 LIBA(absa,FABS)
868 LIBA(expa,EXP)
869 LIBA(loga,LOG)
870 LIBA(sqrta,SQRT)
871 LIBA(sina,SIN)
872 LIBA(cosa,COS)
873 LIBA(tana,TAN)
874 LIBA(asina,ASIN)
875 LIBA(acosa,ACOS)
876 LIBA(atana,ATAN)
877 LIBA(sinha,SINH)
878 LIBA(cosha,COSH)
879 LIBA(tanha,TANH)
880 LIBA(log10a,LOG10)
881 LIBA(log2a,LOG2)
882 
883 int32_t atan2aa(CSOUND *csound, AOP *p)
884 {
885     MYFLT   *r, *a, *b;
886     uint32_t offset = p->h.insdshead->ksmps_offset;
887     uint32_t early  = p->h.insdshead->ksmps_no_end;
888     uint32_t n, nsmps =CS_KSMPS;
889     IGN(csound);
890     r = p->r;
891     a = p->a;
892     b = p->b;
893     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
894     if (UNLIKELY(early)) {
895       nsmps -= early;
896       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
897     }
898     for (n = offset; n < nsmps; n++)
899       r[n] = ATAN2(a[n], b[n]);
900     return OK;
901 }
902 
dbamp(CSOUND * csound,EVAL * p)903 int32_t dbamp(CSOUND *csound, EVAL *p)
904 {
905     IGN(csound);
906     *p->r = LOG(FABS(*p->a)) / LOG10D20;
907     return OK;
908 }
909 
ampdb(CSOUND * csound,EVAL * p)910 int32_t ampdb(CSOUND *csound, EVAL *p)
911 {
912     IGN(csound);
913     *p->r = EXP(*p->a * LOG10D20);
914     return OK;
915 }
916 
aampdb(CSOUND * csound,EVAL * p)917 int32_t aampdb(CSOUND *csound, EVAL *p)
918 {
919     uint32_t offset = p->h.insdshead->ksmps_offset;
920     uint32_t early  = p->h.insdshead->ksmps_no_end;
921     uint32_t n, nsmps =CS_KSMPS;
922     MYFLT   *r = p->r, *a = p->a;
923     IGN(csound);
924 
925     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
926     if (UNLIKELY(early)) {
927       nsmps -= early;
928       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
929     }
930     for (n = offset; n < nsmps; n++)
931       r[n] = EXP(a[n] * LOG10D20);
932     return OK;
933 }
934 
dbfsamp(CSOUND * csound,EVAL * p)935 int32_t dbfsamp(CSOUND *csound, EVAL *p)
936 {
937     *p->r = LOG(FABS(*p->a) / csound->e0dbfs) / LOG10D20;
938     return OK;
939 }
940 
ampdbfs(CSOUND * csound,EVAL * p)941 int32_t ampdbfs(CSOUND *csound, EVAL *p)
942 {
943     *p->r =  csound->e0dbfs * EXP(*p->a * LOG10D20);
944     return OK;
945 }
946 
aampdbfs(CSOUND * csound,EVAL * p)947 int32_t aampdbfs(CSOUND *csound, EVAL *p)
948 {
949     uint32_t offset = p->h.insdshead->ksmps_offset;
950     uint32_t early  = p->h.insdshead->ksmps_no_end;
951     uint32_t n, nsmps =CS_KSMPS;
952     MYFLT   *r, *a;
953 
954     r = p->r;
955     a = p->a;
956     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
957     if (UNLIKELY(early)) {
958       nsmps -= early;
959       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
960     }
961     for (n = offset; n < nsmps; n++)
962       r[n] = csound->e0dbfs * EXP(a[n] * LOG10D20);
963     return OK;
964 }
965 
ftlen(CSOUND * csound,EVAL * p)966 int32_t ftlen(CSOUND *csound, EVAL *p)
967 {
968     FUNC    *ftp;
969 
970     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->a)) == NULL)) {
971       *p->r = -FL(1.0);       /* Return something */
972       return NOTOK;
973     }
974     *p->r = (MYFLT)ftp->flen;
975 
976     return OK;
977 }
978 
ftchnls(CSOUND * csound,EVAL * p)979 int32_t ftchnls(CSOUND *csound, EVAL *p)
980 {
981     FUNC    *ftp;
982 
983     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->a)) == NULL)) {
984       *p->r = -FL(1.0);       /* Return something */
985       return NOTOK;
986     }
987     *p->r = (MYFLT)ftp->nchanls;
988 
989     return OK;
990 }
991 
ftcps(CSOUND * csound,EVAL * p)992 int32_t ftcps(CSOUND *csound, EVAL *p)
993 {
994     FUNC    *ftp;
995 
996     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->a)) == NULL)
997         || ftp->cpscvt == FL(0.0)) {
998       *p->r = -FL(1.0);       /* Return something */
999       return NOTOK;
1000     }
1001     *p->r = (MYFLT)(ftp->cvtbas/ftp->cpscvt);
1002 
1003     return OK;
1004 }
1005 
1006 
1007 
ftlptim(CSOUND * csound,EVAL * p)1008 int32_t ftlptim(CSOUND *csound, EVAL *p)
1009 {
1010     FUNC    *ftp;
1011 
1012     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->a)) == NULL))
1013       return NOTOK;
1014     if (LIKELY(ftp->loopmode1))
1015       *p->r = ftp->begin1 * csound->onedsr;
1016     else {
1017       *p->r = FL(0.0);
1018       csound->Warning(csound, Str("non-looping sample"));
1019     }
1020     return OK;
1021 }
1022 
numsamp(CSOUND * csound,EVAL * p)1023 int32_t numsamp(CSOUND *csound, EVAL *p)        /***** nsamp by G.Maldonado ****/
1024 {
1025     FUNC    *ftp;
1026 
1027     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->a)) == NULL)) {
1028       *p->r = FL(0.0);
1029       return NOTOK;
1030     }
1031     /* if (ftp->soundend) */
1032     *p->r = (MYFLT)ftp->soundend;
1033     /* else
1034      *p->r = (MYFLT)(ftp->flen + 1); */
1035 
1036     return OK;
1037 }
1038 
ftsr(CSOUND * csound,EVAL * p)1039 int32_t ftsr(CSOUND *csound, EVAL *p)               /**** ftsr by G.Maldonado ****/
1040 {
1041     FUNC    *ftp;
1042 
1043     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->a)) == NULL)) {
1044       *p->r = FL(0.0);
1045       return NOTOK;
1046     }
1047     *p->r = ftp->gen01args.sample_rate;
1048 
1049     return OK;
1050 }
1051 
rtclock(CSOUND * csound,EVAL * p)1052 int32_t rtclock(CSOUND *csound, EVAL *p)
1053 {
1054     *p->r = (MYFLT)csoundGetRealTime(csound->csRtClock);
1055     return OK;
1056 }
1057 
octpch(CSOUND * csound,EVAL * p)1058 int32_t octpch(CSOUND *csound, EVAL *p)
1059 {
1060     IGN(csound);
1061     double fract, oct;
1062     fract = modf((double)*p->a, &oct);
1063     fract *= EIPT3;
1064     *p->r = (MYFLT)(oct + fract);
1065     return OK;
1066 }
1067 
pchoct(CSOUND * csound,EVAL * p)1068 int32_t pchoct(CSOUND *csound, EVAL *p)
1069 {
1070     IGN(csound);
1071     double fract, oct;
1072     fract = modf((double)*p->a, &oct);
1073     fract *= 0.12;
1074     *p->r = (MYFLT)(oct + fract);
1075     return OK;
1076 }
1077 
cpsoct(CSOUND * csound,EVAL * p)1078 int32_t cpsoct(CSOUND *csound, EVAL *p)
1079 {
1080     int32_t loct = (int32_t)(*p->a * OCTRES);
1081     *p->r = (MYFLT)CPSOCTL(loct);
1082     return OK;
1083 }
1084 
acpsoct(CSOUND * csound,EVAL * p)1085 int32_t acpsoct(CSOUND *csound, EVAL *p)
1086 {
1087     MYFLT   *r, *a;
1088     int32_t    loct;
1089     uint32_t offset = p->h.insdshead->ksmps_offset;
1090     uint32_t early  = p->h.insdshead->ksmps_no_end;
1091     uint32_t n, nsmps =CS_KSMPS;
1092 
1093     a = p->a;
1094     r = p->r;
1095     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
1096     if (UNLIKELY(early)) {
1097       nsmps -= early;
1098       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
1099     }
1100     for (n = offset; n < nsmps; n++) {
1101       loct = (int32_t)(a[n] * OCTRES);
1102       r[n] = CPSOCTL(loct);
1103     }
1104     return OK;
1105 }
1106 
octcps(CSOUND * csound,EVAL * p)1107 int32_t octcps(CSOUND *csound, EVAL *p)
1108 {
1109     IGN(csound);
1110     *p->r = (LOG(*p->a /(MYFLT)ONEPT) / (MYFLT)LOGTWO);
1111     return OK;
1112 }
1113 
cpspch(CSOUND * csound,EVAL * p)1114 int32_t cpspch(CSOUND *csound, EVAL *p)
1115 {
1116     double fract, oct;
1117     int32_t    loct;
1118     fract = modf((double)*p->a, &oct);
1119     fract *= EIPT3;
1120     loct = (int32_t)MYFLT2LRND((oct + fract) * OCTRES);
1121     *p->r = (MYFLT)CPSOCTL(loct);
1122     return OK;
1123 }
1124 
cpsmidinn(CSOUND * csound,EVAL * p)1125 int32_t cpsmidinn(CSOUND *csound, EVAL *p)
1126 {
1127     IGN(csound);
1128     *p->r = pow(FL(2.0),
1129                 (*p->a - FL(69.0)) / FL(12.0)) * (MYFLT)(csound->A4);
1130     return OK;
1131 }
1132 
octmidinn(CSOUND * csound,EVAL * p)1133 int32_t octmidinn(CSOUND *csound, EVAL *p)
1134 {
1135     IGN(csound);
1136     /* Convert Midi Note number to 8ve.decimal format */
1137     *p->r = (*p->a / FL(12.0)) + FL(MIDINOTE0);
1138     return OK;
1139 }
1140 
pchmidinn(CSOUND * csound,EVAL * p)1141 int32_t pchmidinn(CSOUND *csound, EVAL *p)
1142 {
1143     IGN(csound);
1144     double fract, oct, octdec;
1145     /* Convert Midi Note number to 8ve.decimal format */
1146     octdec = ((double)*p->a / 12.0) + MIDINOTE0;
1147     /* then convert to 8ve.pc format */
1148     fract = modf(octdec, &oct);
1149     fract *= 0.12;
1150     *p->r = (MYFLT)(oct + fract);
1151     return OK;
1152 }
1153 
cpsxpch(CSOUND * csound,XENH * p)1154 int32_t cpsxpch(CSOUND *csound, XENH *p)
1155 {                               /* This may be too expensive */
1156     double  fract;
1157     double  loct;
1158 
1159     fract = modf((double)*p->pc, &loct); /* Get octave */
1160     if (*p->et > 0) {
1161       fract = pow((double)*p->cy, loct + (100.0*fract)/((double)*p->et));
1162       *p->r = (MYFLT)fract * *p->ref;
1163     }
1164     else {                      /* Values in a table */
1165       MYFLT t = - *p->et;
1166       FUNC* ftp = csound->FTnp2Finde(csound, &t);
1167       int32_t len, frt;
1168       if (UNLIKELY(ftp == NULL))
1169         return csound->PerfError(csound, &(p->h),Str("No tuning table %d"),
1170                                  -((int32_t)*p->et));
1171       len = ftp->flen;
1172       frt = (int32_t)(100.0*fract+0.5);
1173       while (frt>len) {
1174         frt -= len; loct++;
1175       }
1176       *p->r = *p->ref * *(ftp->ftable + frt) *
1177         POWER(*p->cy, (MYFLT)loct);
1178     }
1179     return OK;
1180 }
1181 
cps2pch(CSOUND * csound,XENH * p)1182 int32_t cps2pch(CSOUND *csound, XENH *p)
1183 {
1184     double  fract;
1185     double  loct;
1186 
1187     fract = modf((double)*p->pc, &loct);        /* Get octave */
1188     if (*p->et > 0) {
1189       fract = pow(2.0, loct + (100.0*fract)/((double)*p->et));
1190       *p->r = (MYFLT)(fract * 1.02197503906); /* Refer to base frequency */
1191     }
1192     else {
1193       MYFLT t = - *p->et;
1194       FUNC* ftp = csound->FTnp2Finde(csound, &t);
1195       int32_t len, frt;
1196       if (UNLIKELY(ftp == NULL))
1197         return csound->PerfError(csound, &(p->h),Str("No tuning table %d"),
1198                                  -((int32_t)*p->et));
1199       len = ftp->flen;
1200       frt = (int32_t)(100.0*fract+0.5);
1201       //printf("len=%d fract=%g frt=%d\n", len, fract, frt);
1202       while (frt>len) {
1203         frt -= len; loct++;
1204       }
1205       //printf("len=%d loct=%g frt=%d\n", len, loct, frt);
1206       *p->r = (MYFLT)(1.02197503906 * *(ftp->ftable + frt) *
1207                       pow(2.0, loct));
1208     }
1209 
1210     /*  double ref = 261.62561 / pow(2.0, 8.0); */
1211     return OK;
1212 }
1213 
cpstun_i(CSOUND * csound,CPSTUNI * p)1214 int32_t cpstun_i(CSOUND *csound, CPSTUNI *p)
1215 {
1216     FUNC  *ftp;
1217     MYFLT *func;
1218     int32_t notenum = (int32_t)*p->input;
1219     int32_t grade;
1220     int32_t numgrades;
1221     int32_t basekeymidi;
1222     MYFLT basefreq, factor, interval;
1223     if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->tablenum)) == NULL)) goto err1;
1224     func = ftp->ftable;
1225     numgrades = (int32_t)*func++;
1226     interval = *func++;
1227     basefreq = *func++;
1228     basekeymidi = (int32_t)*func++;
1229 
1230     if (notenum < basekeymidi) {
1231       notenum = basekeymidi - notenum;
1232       grade  = (numgrades-(notenum % numgrades)) % numgrades;
1233       factor = - (MYFLT)(int32_t)((notenum+numgrades-1) / numgrades) ;
1234     }
1235     else {
1236       notenum = notenum - basekeymidi;
1237       grade  = notenum % numgrades;
1238       factor = (MYFLT)(int32_t)(notenum / numgrades);
1239     }
1240     factor = POWER(interval, factor);
1241     *p->r = func[grade] * factor * basefreq;
1242     return OK;
1243  err1:
1244     return csound->PerfError(csound, &(p->h),Str("cpstun: invalid table"));
1245 }
1246 
cpstun(CSOUND * csound,CPSTUN * p)1247 int32_t cpstun(CSOUND *csound, CPSTUN *p)
1248 {
1249     if (*p->ktrig) {
1250       FUNC  *ftp;
1251       MYFLT *func;
1252       int32_t notenum = (int32_t)*p->kinput;
1253       int32_t grade;
1254       int32_t numgrades;
1255       int32_t basekeymidi;
1256       MYFLT basefreq, factor, interval;
1257       if (UNLIKELY((ftp = csound->FTnp2Finde(csound, p->tablenum)) == NULL))
1258         goto err1;
1259       func = ftp->ftable;
1260       numgrades = (int32_t)*func++;
1261       interval = *func++;
1262       basefreq = *func++;
1263       basekeymidi = (int32_t)*func++;
1264 
1265       if (notenum < basekeymidi) {
1266         notenum = basekeymidi - notenum;
1267         grade  = (numgrades-(notenum % numgrades)) % numgrades;
1268         factor = - (MYFLT)(int32_t)((notenum+numgrades-1) / numgrades) ;
1269       }
1270       else {
1271         notenum = notenum - basekeymidi;
1272         grade  = notenum % numgrades;
1273         factor = (MYFLT)(int32_t)(notenum / numgrades);
1274       }
1275       factor = POWER(interval, factor);
1276       p->old_r = (*p->r = func[grade] * factor * basefreq);
1277 
1278 }
1279     else *p->r = p->old_r;
1280     return OK;
1281  err1:
1282     return csound->PerfError(csound, &(p->h),Str("cpstun: invalid table"));
1283 }
1284 
logbasetwo_set(CSOUND * csound,EVAL * p)1285 int32_t logbasetwo_set(CSOUND *csound, EVAL *p)
1286 {
1287     IGN(p);
1288     if (UNLIKELY(csound->logbase2 == NULL)) {
1289       double  x = (1.0 / INTERVAL);
1290       int32_t     i;
1291       csound->logbase2 = (MYFLT*) csound->Malloc(csound, (STEPS + 1)
1292                                                  * sizeof(MYFLT));
1293       for (i = 0; i <= STEPS; i++) {
1294         csound->logbase2[i] = ONEdLOG2 * LOG((MYFLT)x);
1295         x += ((INTERVAL - 1.0 / INTERVAL) / (double)STEPS);
1296       }
1297     }
1298     return OK;
1299 }
1300 
powoftwo(CSOUND * csound,EVAL * p)1301 int32_t powoftwo(CSOUND *csound, EVAL *p)
1302 {
1303     *p->r = POWER(FL(2.0), *p->a);
1304     return OK;
1305 }
1306 
powoftwoa(CSOUND * csound,EVAL * p)1307 int32_t powoftwoa(CSOUND *csound, EVAL *p)
1308 {                                   /* by G.Maldonado, liberalised by JPff */
1309     MYFLT    *a=p->a, *r=p->r;
1310     uint32_t offset = p->h.insdshead->ksmps_offset;
1311     uint32_t early  = p->h.insdshead->ksmps_no_end;
1312     uint32_t n, nsmps =CS_KSMPS;
1313     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
1314     if (UNLIKELY(early)) {
1315       nsmps -= early;
1316       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
1317     }
1318     for (n = offset; n < nsmps; n++)
1319       r[n] = POWER(FL(2.0), a[n]);
1320     return OK;
1321 }
1322 
1323 #define ONEd12          (FL(0.08333333333333333333333))
1324 #define ONEd1200        (FL(0.00083333333333333333333))
1325 
semitone(CSOUND * csound,EVAL * p)1326 int32_t semitone(CSOUND *csound, EVAL *p)
1327 {
1328     MYFLT a = *p->a*ONEd12;
1329     *p->r = POWER(FL(2.0), a);
1330     return OK;
1331 }
1332 
asemitone(CSOUND * csound,EVAL * p)1333 int32_t asemitone(CSOUND *csound, EVAL *p)            /* JPff */
1334 {
1335     MYFLT *r, *a;
1336     uint32_t offset = p->h.insdshead->ksmps_offset;
1337     uint32_t early  = p->h.insdshead->ksmps_no_end;
1338     uint32_t n, nsmps =CS_KSMPS;
1339     a = p->a;
1340     r = p->r;
1341     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
1342     if (UNLIKELY(early)) {
1343       nsmps -= early;
1344       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
1345     }
1346     for (n = offset; n < nsmps; n++) {
1347       MYFLT aa = (a[n])*ONEd12;
1348       r[n] = POWER(FL(2.0), aa);
1349     }
1350     return OK;
1351 }
1352 
cent(CSOUND * csound,EVAL * p)1353 int32_t cent(CSOUND *csound, EVAL *p)
1354 {
1355     MYFLT a = *p->a;
1356     *p->r = POWER(FL(2.0), a/FL(1200.0));
1357     return OK;
1358 }
1359 
acent(CSOUND * csound,EVAL * p)1360 int32_t acent(CSOUND *csound, EVAL *p)        /* JPff */
1361 {
1362     MYFLT *r, *a;
1363     uint32_t offset = p->h.insdshead->ksmps_offset;
1364     uint32_t early  = p->h.insdshead->ksmps_no_end;
1365     uint32_t n, nsmps =CS_KSMPS;
1366     a = p->a;
1367     r = p->r;
1368     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
1369     if (UNLIKELY(early)) {
1370       nsmps -= early;
1371       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
1372     }
1373     for (n = offset; n < nsmps; n++) {
1374       MYFLT aa = (a[n])*ONEd1200;
1375       r[n] = POWER(FL(2.0), aa);
1376   }
1377   return OK;
1378 }
1379 
1380 #define LOG2_10D20      (FL(0.166096404744368117393515971474))
1381 
db(CSOUND * csound,EVAL * p)1382 int32_t db(CSOUND *csound, EVAL *p)
1383 {
1384     *p->r = POWER(FL(2.0), *p->a*LOG2_10D20);
1385     return OK;
1386 }
1387 
dba(CSOUND * csound,EVAL * p)1388 int32_t dba(CSOUND *csound, EVAL *p)          /* JPff */
1389 {
1390     MYFLT *r, *a;
1391     uint32_t offset = p->h.insdshead->ksmps_offset;
1392     uint32_t early  = p->h.insdshead->ksmps_no_end;
1393     uint32_t n, nsmps =CS_KSMPS;
1394     a = p->a;
1395     r = p->r;
1396     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
1397     if (UNLIKELY(early)) {
1398       nsmps -= early;
1399       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
1400     }
1401     for (n = offset; n < nsmps; n++) {
1402       MYFLT aa = a[n];
1403       r[n] = POWER(FL(2.0), aa*LOG2_10D20);
1404     }
1405     return OK;
1406 }
1407 
logbasetwo(CSOUND * csound,EVAL * p)1408 int32_t logbasetwo(CSOUND *csound, EVAL *p)
1409 {
1410     int32_t n = (int32_t)((*p->a -(FL(1.0)/INTERVAL)) / (INTERVAL-FL(1.0)/INTERVAL)
1411                   *  STEPS + FL(0.5));
1412     if (n<0 || n>STEPS)
1413       *p->r = LOG(*p->a)*ONEdLOG2;
1414     else
1415       *p->r = csound->logbase2[n];
1416     return OK;
1417 }
1418 
logbasetwoa(CSOUND * csound,EVAL * p)1419 int32_t logbasetwoa(CSOUND *csound, EVAL *p)
1420 {                                   /* by G.Maldonado liberalised by JPff */
1421     MYFLT *r, *a;
1422     uint32_t offset = p->h.insdshead->ksmps_offset;
1423     uint32_t early  = p->h.insdshead->ksmps_no_end;
1424     uint32_t n, nsmps =CS_KSMPS;
1425     a = p->a;
1426     r = p->r;
1427     if (UNLIKELY(offset)) memset(r, '\0', offset*sizeof(MYFLT));
1428     if (UNLIKELY(early)) {
1429       nsmps -= early;
1430       memset(&r[nsmps], '\0', early*sizeof(MYFLT));
1431     }
1432     for (n = offset; n < nsmps; n++) {
1433       MYFLT aa = a[n];
1434       int32_t n = (int32_t)((aa -(FL(1.0)/INTERVAL)) / (INTERVAL-FL(1.0)/INTERVAL)
1435                     *  STEPS + FL(0.5));
1436       if (n<0 || n>STEPS) r[n] = LOG(aa)*ONEdLOG2;
1437       else                r[n] = csound->logbase2[n];
1438     }
1439     return OK;
1440 }
1441 
ilogbasetwo(CSOUND * csound,EVAL * p)1442 int32_t ilogbasetwo(CSOUND *csound, EVAL *p)
1443 {
1444     logbasetwo_set(csound, p);
1445     logbasetwo(csound, p);
1446     return OK;
1447 }
1448 
in(CSOUND * csound,INM * p)1449 int32_t in(CSOUND *csound, INM *p)
1450 {
1451     uint32_t offset = p->h.insdshead->ksmps_offset*sizeof(MYFLT);
1452     uint32_t early  = p->h.insdshead->ksmps_no_end;
1453     if (csound->inchnls != 1)
1454       return csound->PerfError(csound,
1455                                &(p->h),
1456                                "Wrong numnber of input channels\n");
1457     CSOUND_SPIN_SPINLOCK
1458     if (UNLIKELY(offset)) memset(p->ar, '\0', offset);
1459     memcpy(&p->ar[offset], CS_SPIN, (CS_KSMPS-early) * sizeof(MYFLT)-offset);
1460     if (UNLIKELY(early))
1461       memset(&p->ar[CS_KSMPS-early], '\0', early * sizeof(MYFLT));
1462     CSOUND_SPIN_SPINUNLOCK
1463     return OK;
1464 }
1465 
inarray(CSOUND * csound,INA * p)1466 int32_t inarray(CSOUND *csound, INA *p)
1467 {
1468     MYFLT *data = p->tabout->data;
1469     uint32_t n = p->tabout->sizes[0];
1470     uint32_t offset = p->h.insdshead->ksmps_offset*sizeof(MYFLT);
1471     uint32_t early  = p->h.insdshead->ksmps_no_end;
1472     MYFLT *sp = CS_SPIN;
1473     uint32_t m, nsmps =CS_KSMPS, i;
1474     uint32_t ksmps = nsmps;
1475 
1476     if ((int32_t)n>csound->inchnls) n = csound->inchnls;
1477     CSOUND_SPIN_SPINLOCK
1478     if (UNLIKELY(offset))
1479       for (i = 0; i < n; i++)
1480         memset(&data[i*ksmps], '\0', offset*sizeof(MYFLT));
1481     if (UNLIKELY(early)) {
1482       nsmps -= early;
1483       for (i = 0; i < n; i++)
1484         memset(&data[nsmps+i*ksmps], '\0', early*sizeof(MYFLT));
1485     }
1486     for (m = offset; m < nsmps; m++) {
1487       for (i = 0; i < n; i++)
1488         data[m+i*ksmps] = *sp++;
1489     }
1490     CSOUND_SPIN_SPINUNLOCK
1491     return OK;
1492 }
1493 
ins(CSOUND * csound,INS * p)1494 int32_t ins(CSOUND *csound, INS *p)
1495 {
1496     MYFLT       *sp, *ar1, *ar2;
1497     uint32_t offset = p->h.insdshead->ksmps_offset;
1498     uint32_t early  = p->h.insdshead->ksmps_no_end;
1499     uint32_t n, nsmps =CS_KSMPS, k;
1500     if (UNLIKELY(csound->inchnls != 2))
1501       return csound->PerfError(csound, &(p->h),
1502                                "Wrong numnber of input channels\n");
1503     CSOUND_SPIN_SPINLOCK
1504     sp = CS_SPIN;
1505     ar1 = p->ar1;
1506     ar2 = p->ar2;
1507     if (UNLIKELY(offset)) {
1508       memset(ar1, '\0', offset*sizeof(MYFLT));
1509       memset(ar2, '\0', offset*sizeof(MYFLT));
1510     }
1511     if (UNLIKELY(early)) {
1512       nsmps -= early;
1513       memset(&p->ar1[nsmps], '\0', early * sizeof(MYFLT));
1514       memset(&p->ar2[nsmps], '\0', early * sizeof(MYFLT));
1515     }
1516     for (n=offset, k=0; n<nsmps; n++, k+=2) {
1517       ar1[n] = sp[k];
1518       ar2[n] = sp[k+1];
1519     }
1520     CSOUND_SPIN_SPINUNLOCK
1521     return OK;
1522 }
1523 
inq(CSOUND * csound,INQ * p)1524 int32_t inq(CSOUND *csound, INQ *p)
1525 {
1526     MYFLT       *sp = CS_SPIN, *ar1 = p->ar1, *ar2 = p->ar2,
1527                                *ar3 = p->ar3, *ar4 = p->ar4;
1528     uint32_t offset = p->h.insdshead->ksmps_offset;
1529     uint32_t early  = p->h.insdshead->ksmps_no_end;
1530     uint32_t n, nsmps =CS_KSMPS, k;
1531     if (UNLIKELY(csound->inchnls != 4))
1532       return csound->PerfError(csound,
1533                                &(p->h),
1534                                "Wrong numnber of input channels\n");
1535     CSOUND_SPIN_SPINLOCK
1536     if (UNLIKELY(offset)) {
1537       memset(ar1, '\0', offset*sizeof(MYFLT));
1538       memset(ar2, '\0', offset*sizeof(MYFLT));
1539       memset(ar3, '\0', offset*sizeof(MYFLT));
1540       memset(ar4, '\0', offset*sizeof(MYFLT));
1541     }
1542     if (UNLIKELY(early)) {
1543       nsmps -= early;
1544       memset(&ar1[nsmps], '\0', early * sizeof(MYFLT));
1545       memset(&ar2[nsmps], '\0', early * sizeof(MYFLT));
1546       memset(&ar3[nsmps], '\0', early * sizeof(MYFLT));
1547       memset(&ar4[nsmps], '\0', early * sizeof(MYFLT));
1548     }
1549     for (n=offset, k=0; n<nsmps; n++, k+=4) {
1550       ar1[n] = sp[k];
1551       ar2[n] = sp[k+1];
1552       ar3[n] = sp[k+2];
1553       ar4[n] = sp[k+3];
1554     }
1555     CSOUND_SPIN_SPINUNLOCK
1556     return OK;
1557 }
1558 
inh(CSOUND * csound,INH * p)1559 int32_t inh(CSOUND *csound, INH *p)
1560 {
1561     MYFLT       *sp = CS_SPIN, *ar1 = p->ar1, *ar2 = p->ar2, *ar3 = p->ar3,
1562                                *ar4 = p->ar4, *ar5 = p->ar5, *ar6 = p->ar6;
1563     uint32_t offset = p->h.insdshead->ksmps_offset;
1564     uint32_t early  = p->h.insdshead->ksmps_no_end;
1565     uint32_t n, nsmps =CS_KSMPS, k;
1566     if (UNLIKELY(csound->inchnls != 6))
1567       return csound->PerfError(csound,
1568                                &(p->h),
1569                                "Wrong numnber of input channels\n");
1570     CSOUND_SPIN_SPINLOCK
1571     if (UNLIKELY(offset)) {
1572       memset(ar1, '\0', offset*sizeof(MYFLT));
1573       memset(ar2, '\0', offset*sizeof(MYFLT));
1574       memset(ar3, '\0', offset*sizeof(MYFLT));
1575       memset(ar4, '\0', offset*sizeof(MYFLT));
1576       memset(ar5, '\0', offset*sizeof(MYFLT));
1577       memset(ar6, '\0', offset*sizeof(MYFLT));
1578     }
1579     if (UNLIKELY(early)) {
1580       nsmps -= early;
1581       memset(&ar1[nsmps], '\0', early * sizeof(MYFLT));
1582       memset(&ar2[nsmps], '\0', early * sizeof(MYFLT));
1583       memset(&ar3[nsmps], '\0', early * sizeof(MYFLT));
1584       memset(&ar4[nsmps], '\0', early * sizeof(MYFLT));
1585       memset(&ar5[nsmps], '\0', early * sizeof(MYFLT));
1586       memset(&ar6[nsmps], '\0', early * sizeof(MYFLT));
1587     }
1588     for (n=offset, k=0; n<nsmps; n++, k+=6) {
1589       ar1[n] = sp[k];
1590       ar2[n] = sp[k+1];
1591       ar3[n] = sp[k+2];
1592       ar4[n] = sp[k+3];
1593       ar5[n] = sp[k+4];
1594       ar6[n] = sp[k+5];
1595     }
1596     CSOUND_SPIN_SPINUNLOCK
1597     return OK;
1598 }
1599 
ino(CSOUND * csound,INO * p)1600 int32_t ino(CSOUND *csound, INO *p)
1601 {
1602     MYFLT       *sp = CS_SPIN, *ar1 = p->ar1, *ar2 = p->ar2, *ar3 = p->ar3,
1603                                *ar4 = p->ar4, *ar5 = p->ar5, *ar6 = p->ar6,
1604                                *ar7 = p->ar7, *ar8 = p->ar8;
1605     uint32_t offset = p->h.insdshead->ksmps_offset;
1606     uint32_t early  = p->h.insdshead->ksmps_no_end;
1607     uint32_t n, nsmps =CS_KSMPS, k;
1608     if (UNLIKELY(csound->inchnls != 8))
1609       return csound->PerfError(csound,
1610                                &(p->h),
1611                                "Wrong numnber of input channels\n");
1612     CSOUND_SPIN_SPINLOCK
1613     if (UNLIKELY(offset)) {
1614       memset(ar1, '\0', offset*sizeof(MYFLT));
1615       memset(ar2, '\0', offset*sizeof(MYFLT));
1616       memset(ar3, '\0', offset*sizeof(MYFLT));
1617       memset(ar4, '\0', offset*sizeof(MYFLT));
1618       memset(ar5, '\0', offset*sizeof(MYFLT));
1619       memset(ar6, '\0', offset*sizeof(MYFLT));
1620       memset(ar7, '\0', offset*sizeof(MYFLT));
1621       memset(ar8, '\0', offset*sizeof(MYFLT));
1622     }
1623     if (UNLIKELY(early)) {
1624       nsmps -= early;
1625       memset(&ar1[nsmps], '\0', early * sizeof(MYFLT));
1626       memset(&ar2[nsmps], '\0', early * sizeof(MYFLT));
1627       memset(&ar3[nsmps], '\0', early * sizeof(MYFLT));
1628       memset(&ar4[nsmps], '\0', early * sizeof(MYFLT));
1629       memset(&ar5[nsmps], '\0', early * sizeof(MYFLT));
1630       memset(&ar6[nsmps], '\0', early * sizeof(MYFLT));
1631       memset(&ar7[nsmps], '\0', early * sizeof(MYFLT));
1632       memset(&ar8[nsmps], '\0', early * sizeof(MYFLT));
1633     }
1634     for (n=offset, k=0; n<nsmps; n++, k+=8) {
1635       ar1[n] = sp[k];
1636       ar2[n] = sp[k+1];
1637       ar3[n] = sp[k+2];
1638       ar4[n] = sp[k+3];
1639       ar5[n] = sp[k+4];
1640       ar6[n] = sp[k+5];
1641       ar7[n] = sp[k+6];
1642       ar8[n] = sp[k+7];
1643     }
1644     CSOUND_SPIN_SPINUNLOCK
1645     return OK;
1646 }
1647 
inn(CSOUND * csound,INALL * p,uint32_t n)1648 static int32_t inn(CSOUND *csound, INALL *p, uint32_t n)
1649 {
1650     MYFLT *sp = CS_SPIN, **ara = p->ar;
1651     uint32_t offset = p->h.insdshead->ksmps_offset;
1652     uint32_t early  = p->h.insdshead->ksmps_no_end;
1653     uint32_t m, nsmps =CS_KSMPS, i;
1654     if (UNLIKELY(csound->inchnls != (int32_t) n))
1655       return csound->PerfError(csound,
1656                                &(p->h),
1657                                "Wrong numnber of input channels\n");
1658 
1659     CSOUND_SPIN_SPINLOCK
1660     if (UNLIKELY(offset))
1661       for (i = 0; i < n; i++)
1662         memset(ara[i], '\0', offset*sizeof(MYFLT));
1663     if (UNLIKELY(early)) {
1664       nsmps -= early;
1665       for (i = 0; i < n; i++)
1666         memset(ara[i], '\0', early*sizeof(MYFLT));
1667     }
1668     for (m = offset; m < nsmps; m++) {
1669       for (i = 0; i < n; i++)
1670         *ara[i] = *sp++;
1671     }
1672     CSOUND_SPIN_SPINUNLOCK
1673     return OK;
1674 }
1675 
in16(CSOUND * csound,INALL * p)1676 int32_t in16(CSOUND *csound, INALL *p)
1677 {
1678     return inn(csound, p, 16u);
1679 }
1680 
in32(CSOUND * csound,INALL * p)1681 int32_t in32(CSOUND *csound, INALL *p)
1682 {
1683     return inn(csound, p, 32u);
1684 }
1685 
inch1_set(CSOUND * csound,INCH1 * p)1686 int32_t inch1_set(CSOUND *csound, INCH1 *p)
1687 {
1688     IGN(csound);
1689     p->init = 1;
1690     return OK;
1691 }
1692 
inch_opcode1(CSOUND * csound,INCH1 * p)1693 int32_t inch_opcode1(CSOUND *csound, INCH1 *p)
1694 {
1695     uint32_t offset = p->h.insdshead->ksmps_offset;
1696     uint32_t early  = p->h.insdshead->ksmps_no_end;
1697     uint32_t n, nsmps = CS_KSMPS, ch;
1698     MYFLT *sp, *ain;
1699 
1700     ch = MYFLT2LRND(*p->ch);
1701     if (UNLIKELY(ch > (uint32_t)csound->inchnls)) {
1702       if (p->init)
1703         csound->Message(csound, Str("Input channel %d too large; ignored\n"), ch);
1704       memset(p->ar, 0, sizeof(MYFLT)*nsmps);
1705       p->init = 0;
1706       //        return OK;
1707     } else if (UNLIKELY(ch < 1)) {
1708       if (p->init)
1709         csound->Message(csound, Str("Input channel %d is invalid; ignored"), ch);
1710       memset(p->ar, 0, sizeof(MYFLT)*nsmps);
1711       p->init = 0;
1712     }
1713     else {
1714       sp = CS_SPIN + (ch - 1);
1715       ain = p->ar;
1716       if (UNLIKELY(offset)) memset(ain, '\0', offset*sizeof(MYFLT));
1717       if (UNLIKELY(early)) {
1718         nsmps -= early;
1719         memset(&ain[nsmps], '\0', early*sizeof(MYFLT));
1720       }
1721       for (n = offset; n < nsmps; n++) {
1722         ain[n] = *sp;
1723         sp += csound->inchnls;
1724       }
1725     }
1726 
1727     return OK;
1728 }
1729 
inch_set(CSOUND * csound,INCH * p)1730 int32_t inch_set(CSOUND *csound, INCH *p)
1731 {
1732     IGN(csound);
1733     p->init = 1;
1734     return OK;
1735 }
1736 
inch_opcode(CSOUND * csound,INCH * p)1737 int32_t inch_opcode(CSOUND *csound, INCH *p)
1738 {                               /* Rewritten to allow multiple args upto 40 */
1739     uint32_t nc, nChannels = p->INCOUNT;
1740     uint32_t offset = p->h.insdshead->ksmps_offset;
1741     uint32_t early  = p->h.insdshead->ksmps_no_end;
1742     uint32_t n, nsmps = CS_KSMPS, ch;
1743     MYFLT *sp, *ain;
1744     if (UNLIKELY(nChannels != p->OUTOCOUNT))
1745       return
1746         csound->PerfError(csound, &(p->h),
1747                           Str("Input and output argument count differs in inch"));
1748     for (nc=0; nc<nChannels; nc++) {
1749       ch = MYFLT2LRND(*p->ch[nc]);
1750       if (UNLIKELY(ch > (uint32_t)csound->inchnls)) {
1751         if (p->init)
1752           csound->Warning(csound, Str("Input channel %d too large; ignored"), ch);
1753         memset(p->ar[nc], 0, sizeof(MYFLT)*nsmps);
1754         p->init = 0;
1755         //        return OK;
1756       } else if (UNLIKELY(ch < 1)) {
1757         if (UNLIKELY(p->init))
1758           csound->Warning(csound, Str("Input channel %d is invalid; ignored"), ch);
1759         memset(p->ar[nc], 0, sizeof(MYFLT)*nsmps);
1760         p->init = 0;
1761       } else {
1762         sp = CS_SPIN + (ch - 1);
1763         ain = p->ar[nc];
1764         if (UNLIKELY(offset)) memset(ain, '\0', offset*sizeof(MYFLT));
1765         if (UNLIKELY(early)) {
1766           nsmps -= early;
1767           memset(&ain[nsmps], '\0', early*sizeof(MYFLT));
1768         }
1769         for (n = offset; n < nsmps; n++) {
1770           ain[n] = *sp;
1771           sp += csound->inchnls;
1772         }
1773 
1774       }
1775     }
1776     return OK;
1777 }
1778 
1779 
inall_opcode(CSOUND * csound,INALL * p)1780 int32_t inall_opcode(CSOUND *csound, INALL *p)
1781 {
1782     uint32_t n = (int32_t)p->OUTOCOUNT, m;
1783     uint32_t offset = p->h.insdshead->ksmps_offset;
1784     uint32_t    i,j = 0, k = 0, nsmps = CS_KSMPS;
1785     uint32_t early  = nsmps - p->h.insdshead->ksmps_no_end;
1786     MYFLT *spin = CS_SPIN;
1787 
1788     CSOUND_SPIN_SPINLOCK
1789     m = (n < (uint32_t)csound->inchnls ? n : (uint32_t)csound->inchnls);
1790     for (j=0; j<nsmps; j++)
1791       if (j<offset || j>early) {
1792         for (i=0 ; i < n; i++)
1793           p->ar[i][j] = FL(0.0);
1794       }
1795       else {
1796         for (i=0; i<m; i++) {
1797           p->ar[i][j] = spin[k + i];
1798         }
1799         for ( ; i < n; i++)
1800           p->ar[i][j] = FL(0.0);
1801         k += csound->inchnls;
1802       }
1803     CSOUND_SPIN_SPINUNLOCK
1804     return OK;
1805 }
1806 
outs1(CSOUND * csound,OUTM * p)1807 int32_t outs1(CSOUND *csound, OUTM *p)
1808 {
1809     MYFLT       *sp=  CS_SPOUT /*csound->spraw*/, *ap1= p->asig;
1810     uint32_t offset = p->h.insdshead->ksmps_offset;
1811     uint32_t nsmps =CS_KSMPS,  n;
1812     uint32_t early  = nsmps-p->h.insdshead->ksmps_no_end;
1813 
1814     CSOUND_SPOUT_SPINLOCK
1815     if (!csound->spoutactive) {
1816       if (offset) memset(sp, '\0', offset*sizeof(MYFLT));
1817       memcpy(&sp[offset], &ap1[offset], (early-offset)*sizeof(MYFLT));
1818       if (early!=nsmps) memset(&sp[early], '\0', (nsmps-early)*sizeof(MYFLT));
1819       /* for (n=0; n<nsmps; n++) { */
1820       /*   sp[n] = (n<offset || n>early) ? FL(0.0) : ap1[n]; */
1821       /* } */
1822       if (csound->nchnls>1)
1823         memset(&sp[nsmps], '\0', nsmps*(csound->nchnls-1)*sizeof(MYFLT));
1824       csound->spoutactive = 1;
1825     }
1826     else {
1827       for (n=0; n<early; n++) {
1828         if (n>=offset) sp[n]   += ap1[n];
1829       }
1830     }
1831     CSOUND_SPOUT_SPINUNLOCK
1832     return OK;
1833 }
1834 
1835 #define OUTCN(n)  if (n>csound->nchnls) return          \
1836                                           csound->InitError(csound, "%s", \
1837                                               Str("Channel greater than nchnls")); \
1838   return OK;
1839 
och2(CSOUND * csound,OUTM * p)1840 int32_t och2(CSOUND *csound, OUTM *p) { IGN(p); OUTCN(2) }
och3(CSOUND * csound,OUTM * p)1841 int32_t och3(CSOUND *csound, OUTM *p) { IGN(p); OUTCN(3) }
och4(CSOUND * csound,OUTM * p)1842 int32_t och4(CSOUND *csound, OUTM *p) { IGN(p); OUTCN(4) }
1843 
outs2(CSOUND * csound,OUTM * p)1844 int32_t outs2(CSOUND *csound, OUTM *p)
1845 {
1846     MYFLT       *sp =  CS_SPOUT /*csound->spraw*/, *ap2 = p->asig;
1847     uint32_t offset = p->h.insdshead->ksmps_offset;
1848     uint32_t nsmps =CS_KSMPS,  n;
1849     uint32_t early  = nsmps-p->h.insdshead->ksmps_no_end;
1850 
1851     CSOUND_SPOUT_SPINLOCK
1852     if (!csound->spoutactive) {
1853       memset(sp, '\0', nsmps*sizeof(MYFLT));
1854       sp +=nsmps;
1855       if (offset) memset(sp, '\0', offset*sizeof(MYFLT));
1856       memcpy(&sp[offset], &ap2[offset], (early-offset)*sizeof(MYFLT));
1857       if (early!=nsmps) memset(&sp[early], '\0', (nsmps-early)*sizeof(MYFLT));
1858       if (csound->nchnls>2)
1859         memset(&sp[nsmps], '\0', (csound->nchnls-2)*sizeof(MYFLT));
1860       csound->spoutactive = 1;
1861     }
1862     else {
1863       sp +=nsmps;
1864       for (n=offset; n<early; n++) {
1865         sp[n] += ap2[n];
1866       }
1867     }
1868     CSOUND_SPOUT_SPINUNLOCK
1869     return OK;
1870 }
1871 
outq3(CSOUND * csound,OUTM * p)1872 int32_t outq3(CSOUND *csound, OUTM *p)
1873 {
1874     MYFLT       *sp = CS_SPOUT /*csound->spraw*/, *ap3 = p->asig;
1875     uint32_t offset = p->h.insdshead->ksmps_offset;
1876     uint32_t nsmps =CS_KSMPS,  n;
1877     uint32_t early  = nsmps-p->h.insdshead->ksmps_no_end;
1878     CSOUND_SPOUT_SPINLOCK
1879     if (!csound->spoutactive) {
1880        memset(sp, '\0', 2*nsmps*sizeof(MYFLT));
1881       sp += 2*nsmps;
1882       if (offset) memset(sp, '\0', offset*sizeof(MYFLT));
1883       memcpy(&sp[offset], &ap3[offset], (early-offset)*sizeof(MYFLT));
1884       if (early!=nsmps) memset(&sp[early], '\0', (nsmps-early)*sizeof(MYFLT));
1885       if (csound->nchnls>3)
1886         memset(&sp[nsmps], '\0', (csound->nchnls-3)*sizeof(MYFLT));
1887       csound->spoutactive = 1;
1888     }
1889     else {
1890       sp += 2*nsmps;
1891       for (n=offset; n<early; n++) {
1892         sp[n]   += ap3[n];
1893       }
1894     }
1895     CSOUND_SPOUT_SPINUNLOCK
1896     return OK;
1897 }
1898 
outq4(CSOUND * csound,OUTM * p)1899 int32_t outq4(CSOUND *csound, OUTM *p)
1900 {
1901     MYFLT       *sp = CS_SPOUT /*csound->spraw*/, *ap4 = p->asig;
1902     uint32_t offset = p->h.insdshead->ksmps_offset;
1903     uint32_t nsmps =CS_KSMPS,  n;
1904     uint32_t early  = nsmps-p->h.insdshead->ksmps_no_end;
1905     CSOUND_SPOUT_SPINLOCK
1906     if (!csound->spoutactive) {
1907       memset(sp, '\0', 3*nsmps*sizeof(MYFLT));
1908       sp += 3*nsmps;
1909       if (offset) memset(sp, '\0', offset*sizeof(MYFLT));
1910       memcpy(&sp[offset], &ap4[offset], (early-offset)*sizeof(MYFLT));
1911       if (early!=nsmps) memset(&sp[early], '\0', (nsmps-early)*sizeof(MYFLT));
1912       if (csound->nchnls>4)
1913         memset(&sp[nsmps], '\0', (csound->nchnls-4)*sizeof(MYFLT));
1914       csound->spoutactive = 1;
1915     }
1916     else {
1917       sp += 3*nsmps;
1918       for (n=offset; n<early; n++) {
1919         sp[n]   += ap4[n];
1920       }
1921     }
1922     CSOUND_SPOUT_SPINUNLOCK
1923     return OK;
1924 }
1925 
outn(CSOUND * csound,uint32_t n,OUTX * p)1926 inline static int32_t outn(CSOUND *csound, uint32_t n, OUTX *p)
1927 {
1928     uint32_t nsmps = CS_KSMPS,  i, j, k=0;
1929     MYFLT *spout = CS_SPOUT; ///csound->spraw;
1930     uint32_t offset = p->h.insdshead->ksmps_offset;
1931     uint32_t early  = p->h.insdshead->ksmps_no_end;
1932         if (UNLIKELY((offset|early))) {
1933           printf("OUT; spout=%p early=%d offset=%d\n", spout, early, offset);}
1934     early = nsmps - early;
1935     CSOUND_SPOUT_SPINLOCK
1936 
1937     if (!csound->spoutactive) {
1938       //printf("inactive: spout=%p size=%ld\n",
1939       //       spout, csound->nspout*sizeof(MYFLT));
1940       memset(spout, '\0', csound->nspout*sizeof(MYFLT));
1941       for (i=0; i<n; i++) {
1942         //printf("        : spout=%p size=%ld\n",
1943         //       spout+k+offset, (early-offset)*sizeof(MYFLT));
1944         memcpy(&spout[k+offset], p->asig[i]+offset, (early-offset)*sizeof(MYFLT));
1945         k += nsmps;
1946       }
1947       csound->spoutactive = 1;
1948     }
1949     else {
1950       for (i=0; i<n; i++) {
1951         for (j=offset; j<early; j++) {
1952           //printf("active: spout=%p k=%d j=%d\n", spout, k, j);
1953           spout[k + j] += p->asig[i][j];
1954         }
1955         k += nsmps;
1956       }
1957     }
1958     CSOUND_SPOUT_SPINUNLOCK
1959         //    }
1960     /* else { */
1961     /*   CSOUND_SPOUT_SPINLOCK */
1962 
1963     /*   if (!csound->spoutactive) { */
1964     /*     for (i=0; i<n; i++) { */
1965     /*       memcpy(&spout[k], p->asig[i], nsmps*sizeof(MYFLT)); */
1966     /*       k += nsmps; */
1967     /*     } */
1968     /*     if (csound->nchnls>n+1) { */
1969     /*       printf("nchnks, n = %d,%d\n", csound->nchnls, n); */
1970     /*       memset(&spout[k], '\0', (nsmps*(csound->nchnls-n))*sizeof(MYFLT)); */
1971     /*     } */
1972     /*     csound->spoutactive = 1; */
1973     /*   } */
1974     /*   else { */
1975     /*     for (i=0; i<n; i++) { */
1976     /*       for (j=0; j<nsmps; j++) { */
1977     /*         spout[k + j] += p->asig[i][j]; */
1978     /*       } */
1979     /*       k += nsmps; */
1980     /*     } */
1981     /*   } */
1982     /*   CSOUND_SPOUT_SPINUNLOCK */
1983     /* } */
1984     return OK;
1985 }
1986 
ochn(CSOUND * csound,OUTX * p)1987 int32_t ochn(CSOUND *csound, OUTX *p)
1988 {
1989     uint32_t nch = p->INOCOUNT;
1990     if (nch>csound->nchnls)
1991       csound->Warning(csound, Str("Excess channels ignored\n"));
1992     return OK;
1993 }
1994 
outall(CSOUND * csound,OUTX * p)1995 int32_t outall(CSOUND *csound, OUTX *p)             /* Output a list of channels */
1996 {
1997     uint32_t nch = p->INOCOUNT;
1998     return outn(csound, (nch <= csound->nchnls ? nch : csound->nchnls), p);
1999 }
2000 
outarr_init(CSOUND * csound,OUTARRAY * p)2001 int32_t outarr_init(CSOUND *csound, OUTARRAY *p)
2002 {
2003     IGN(csound);
2004     p->nowarn = 0;
2005     return OK;
2006 }
2007 
outarr(CSOUND * csound,OUTARRAY * p)2008 int32_t outarr(CSOUND *csound, OUTARRAY *p)
2009 {
2010     uint32_t nsmps =CS_KSMPS,  i, j;
2011     uint32_t ksmps = nsmps;
2012     uint32_t n = p->tabin->sizes[0];
2013     MYFLT *data = p->tabin->data;
2014     MYFLT *spout = CS_SPOUT; //csound->spraw;
2015     if (n>csound->nchnls) {
2016       if (p->nowarn==0) {
2017         csound->Warning(csound,
2018                         Str("out: number of channels truncated from %d to %d"),
2019                         n, csound->nchnls);
2020       }
2021       n = csound->nchnls;
2022       p->nowarn = 1;
2023     }
2024     if (csound->oparms->sampleAccurate) {
2025       uint32_t offset = p->h.insdshead->ksmps_offset;
2026       uint32_t early  = nsmps-p->h.insdshead->ksmps_no_end;
2027 
2028       CSOUND_SPOUT_SPINLOCK
2029       if (!csound->spoutactive) {
2030         memset(spout, '\0', csound->nspout*sizeof(MYFLT));
2031         for (i=0; i<n; i++) {
2032           for (j=offset; j<early; j++) {
2033             spout[j+i*ksmps] = data[j+i*ksmps];
2034           }
2035         }
2036         csound->spoutactive = 1;
2037       }
2038       else {
2039         /* no need to offset data is already offset in the buffer*/
2040         for (i=0; i<n; i++) {
2041           for (j=offset; j<early; j++) {
2042             spout[j+i*ksmps] += data[j+i*ksmps];
2043           }
2044         }
2045       }
2046       CSOUND_SPOUT_SPINUNLOCK
2047     }
2048     else {
2049       CSOUND_SPOUT_SPINLOCK
2050       if (!csound->spoutactive) {
2051         memcpy(spout, data, n*ksmps*sizeof(MYFLT));
2052         if (csound->nchnls>n)
2053           memset(&spout[n*ksmps], '\0', (csound->nchnls-n)*ksmps*sizeof(MYFLT));
2054         csound->spoutactive = 1;
2055       }
2056       else {
2057         for (i=0; i<n*nsmps; i++) {
2058           spout[i] += data[i];
2059         }
2060       }
2061       CSOUND_SPOUT_SPINUNLOCK
2062     }
2063     return OK;
2064 }
2065 
outch(CSOUND * csound,OUTCH * p)2066 int32_t outch(CSOUND *csound, OUTCH *p)
2067 {
2068     uint32_t    ch;
2069     MYFLT       *sp, *apn;
2070     uint32_t    offset = p->h.insdshead->ksmps_offset;
2071     uint32_t    nsmps = CS_KSMPS, j, n;
2072     uint32_t    early = nsmps-p->h.insdshead->ksmps_no_end;
2073     uint32_t    count = p->INOCOUNT;
2074     MYFLT       **args = p->args;
2075     uint32_t    nchnls = csound->nchnls;
2076     MYFLT *spout = CS_SPOUT;
2077     if (UNLIKELY((count&1)!=0))
2078       return
2079         csound->PerfError(csound, &(p->h),
2080                           Str("outch must have an even number of arguments"));
2081     CSOUND_SPOUT_SPINLOCK
2082     for (j = 0; j < count; j += 2) {
2083       ch = MYFLT2LRND(*args[j]);
2084       if (ch < 1) ch = 1;
2085       apn = args[j + 1];
2086       if (ch > nchnls) continue;
2087       if (!csound->spoutactive) {
2088         ch--;
2089         memset(spout, '\0', csound->nspout*sizeof(MYFLT));
2090         memcpy(&spout[offset+ch*nsmps], apn, (early-offset)*sizeof(MYFLT));
2091         csound->spoutactive = 1;
2092       }
2093       else {
2094         sp = spout + (ch - 1)*nsmps;
2095         for (n=offset; n<early; n++) {
2096           sp[n] += apn[n];
2097         }
2098       }
2099     }
2100     CSOUND_SPOUT_SPINUNLOCK
2101     return OK;
2102 }
2103 
2104 /* For parallel mixin template */
addina(CSOUND * csound,ASSIGN * p)2105 int32_t addina(CSOUND *csound, ASSIGN *p)
2106 {
2107     MYFLT* val = p->a;
2108     MYFLT* ans = p->r;
2109     uint32_t    offset = p->h.insdshead->ksmps_offset;
2110     uint32_t    nsmps = CS_KSMPS, n;
2111     uint32_t    early = nsmps-p->h.insdshead->ksmps_no_end;
2112 
2113     CSOUND_SPOUT_SPINLOCK
2114     for (n=offset; n<early; n++)
2115       ans[n] += val[n];
2116     CSOUND_SPOUT_SPINUNLOCK
2117     return OK;
2118 }
2119 
addinak(CSOUND * csound,ASSIGN * p)2120 int32_t addinak(CSOUND *csound, ASSIGN *p)
2121 {
2122     MYFLT val;
2123     MYFLT* ans = p->r;
2124     uint32_t    offset = p->h.insdshead->ksmps_offset;
2125     uint32_t    nsmps = CS_KSMPS, n;
2126     uint32_t    early = nsmps-p->h.insdshead->ksmps_no_end;
2127 
2128     CSOUND_SPOUT_SPINLOCK
2129     val = *p->a;
2130     for (n=offset; n<early; n++)
2131       ans[n] += val;
2132     CSOUND_SPOUT_SPINUNLOCK
2133     return OK;
2134 }
2135 
addin(CSOUND * csound,ASSIGN * p)2136 int32_t addin(CSOUND *csound, ASSIGN *p)
2137 {
2138     CSOUND_SPOUT_SPINLOCK
2139     *p->r += *p->a;
2140     CSOUND_SPOUT_SPINUNLOCK
2141     return OK;
2142 }
2143 
subin(CSOUND * csound,ASSIGN * p)2144 int32_t subin(CSOUND *csound, ASSIGN *p)
2145 {
2146     CSOUND_SPOUT_SPINLOCK
2147     *p->r -= *p->a;
2148     CSOUND_SPOUT_SPINUNLOCK
2149     return OK;
2150 }
2151 
subina(CSOUND * csound,ASSIGN * p)2152 int32_t subina(CSOUND *csound, ASSIGN *p)
2153 {
2154     MYFLT* val = p->a;
2155     MYFLT* ans = p->r;
2156     uint32_t    offset = p->h.insdshead->ksmps_offset;
2157     uint32_t    nsmps = CS_KSMPS, n;
2158     uint32_t    early = nsmps-p->h.insdshead->ksmps_no_end;
2159 
2160     CSOUND_SPOUT_SPINLOCK
2161     for (n=offset; n<early; n++)
2162       ans[n] -= val[n];
2163     CSOUND_SPOUT_SPINUNLOCK
2164     return OK;
2165 }
2166 
subinak(CSOUND * csound,ASSIGN * p)2167 int32_t subinak(CSOUND *csound, ASSIGN *p)
2168 {
2169     MYFLT val;
2170     MYFLT* ans = p->r;
2171     uint32_t    offset = p->h.insdshead->ksmps_offset;
2172     uint32_t    nsmps = CS_KSMPS, n;
2173     uint32_t    early = nsmps-p->h.insdshead->ksmps_no_end;
2174 
2175     CSOUND_SPOUT_SPINLOCK
2176     val = *p->a;
2177     for (n=offset; n<early; n++)
2178       ans[n] -= val;
2179     CSOUND_SPOUT_SPINUNLOCK
2180     return OK;
2181 }
2182 
is_NaN(CSOUND * csound,ASSIGN * p)2183 int32_t is_NaN(CSOUND *csound, ASSIGN *p)
2184 {
2185     IGN(csound);
2186     *p->r = isnan(*p->a);
2187     return OK;
2188 }
2189 
2190 /* ********COULD BE IMPROVED******** */
is_NaNa(CSOUND * csound,ASSIGN * p)2191 int32_t is_NaNa(CSOUND *csound, ASSIGN *p)
2192 {
2193     IGN(csound);
2194     uint32_t offset = p->h.insdshead->ksmps_offset;
2195     uint32_t k, nsmps = CS_KSMPS;
2196     uint32_t early  = nsmps - p->h.insdshead->ksmps_no_end;
2197     MYFLT *a = p->a;
2198     *p->r = FL(0.0);
2199     for (k=offset; k<early; k++)
2200       *p->r += isnan(a[k]);
2201     return OK;
2202 }
2203 
is_inf(CSOUND * csound,ASSIGN * p)2204 int32_t is_inf(CSOUND *csound, ASSIGN *p)
2205 {
2206     IGN(csound);
2207     *p->r = isinf(*p->a);
2208     return OK;
2209 }
2210 
2211 /* ********COULD BE IMPROVED******** */
is_infa(CSOUND * csound,ASSIGN * p)2212 int32_t is_infa(CSOUND *csound, ASSIGN *p)
2213 {
2214     IGN(csound);
2215     uint32_t offset = p->h.insdshead->ksmps_offset;
2216     uint32_t k, nsmps = CS_KSMPS;
2217     uint32_t early  = nsmps-p->h.insdshead->ksmps_no_end;
2218     MYFLT *a = p->a;
2219     MYFLT ans = FL(0.0);
2220     int32_t sign = 1;
2221     for (k=offset; k<early; k++) {
2222       if (isinf(a[k]))
2223         if (ans==FL(0.0)) sign = (int32_t)isinf(a[k]);
2224       ans++;
2225     }
2226     *p->r = ans*sign;
2227     return OK;
2228 }
2229 
error_fn(CSOUND * csound,ERRFN * p)2230 int32_t error_fn(CSOUND *csound, ERRFN *p)
2231 {
2232     IGN(p);
2233     return csound->InitError(csound, Str("Unknown function called"));
2234 }
2235 
2236  /* ------------------------------------------------------------------------ */
2237 
monitor_opcode_perf(CSOUND * csound,MONITOR_OPCODE * p)2238 int32_t monitor_opcode_perf(CSOUND *csound, MONITOR_OPCODE *p)
2239 {
2240     uint32_t offset = p->h.insdshead->ksmps_offset;
2241     uint32_t early  = p->h.insdshead->ksmps_no_end;
2242     uint32_t i, j, nsmps = CS_KSMPS, nchnls = csound->GetNchnls(csound);
2243     MYFLT *spout = csound->spraw;
2244 
2245     if (csound->spoutactive) {
2246       for (j = 0; j<nchnls; j++) {
2247         for (i = 0; i<nsmps; i++) {
2248           if (i<offset||i>nsmps-early)
2249             p->ar[j][i] = FL(0.0);
2250           else
2251             p->ar[j][i] = spout[i+j*nsmps];
2252         }
2253       }
2254     }
2255     else {
2256       for (j = 0; j<nchnls; j++) {
2257         memset(p->ar[j], '\0', nsmps*sizeof(MYFLT));
2258       }
2259     }
2260     return OK;
2261 }
2262 
monitor_opcode_init(CSOUND * csound,MONITOR_OPCODE * p)2263 int32_t monitor_opcode_init(CSOUND *csound, MONITOR_OPCODE *p)
2264 {
2265     if (UNLIKELY(csound->GetOutputArgCnt(p) != (int32_t)csound->GetNchnls(csound)))
2266       return csound->InitError(csound, Str("number of arguments != nchnls"));
2267     p->h.opadr = (SUBR) monitor_opcode_perf;
2268     return OK;
2269 }
2270 
2271 /* -------------------------------------------------------------------- */
2272 
outRange_i(CSOUND * csound,OUTRANGE * p)2273 int32_t outRange_i(CSOUND *csound, OUTRANGE *p)
2274 {
2275     IGN(csound);
2276     p->narg = p->INOCOUNT-1;
2277 
2278     return OK;
2279 }
2280 
outRange(CSOUND * csound,OUTRANGE * p)2281 int32_t outRange(CSOUND *csound, OUTRANGE *p)
2282 {
2283     int32_t j;
2284     uint32_t offset = p->h.insdshead->ksmps_offset;
2285     uint32_t early  = p->h.insdshead->ksmps_no_end;
2286     uint32_t n, nsmps = CS_KSMPS;
2287     //int32_t nchnls = csound->GetNchnls(csound);
2288     MYFLT *ara[VARGMAX];
2289     int32_t startChan = (int32_t) *p->kstartChan -1;
2290     MYFLT *sp = csound->spraw + startChan*nsmps;
2291     int32_t narg = p->narg;
2292 
2293     if (UNLIKELY(startChan < 0))
2294       return csound->PerfError(csound, &(p->h),
2295                                Str("outrg: channel number cannot be < 1 "
2296                                    "(1 is the first channel)"));
2297 
2298     for (j = 0; j < narg; j++)
2299       ara[j] = p->argums[j];
2300 
2301     if (!csound->spoutactive) {
2302       memset(csound->spraw, '\0', csound->nspout * sizeof(MYFLT));
2303       /* no need to offset ?? why ?? */
2304       int32_t i;
2305       for (i=0; i < narg; i++) {
2306         memcpy(sp, ara[i], nsmps*sizeof(MYFLT));
2307         sp += nsmps;
2308       }
2309       csound->spoutactive = 1;
2310     }
2311     else {
2312       int32_t i;
2313       for (i=0; i < narg; i++) {
2314         for (n=offset; n<nsmps-early; n++) {
2315           sp[n] += ara[i][n];
2316         }
2317         sp += nsmps;
2318       }
2319     }
2320     return OK;
2321 }
2322 /* -------------------------------------------------------------------- */
2323 
hw_channels(CSOUND * csound,ASSIGN * p)2324 int32_t hw_channels(CSOUND *csound, ASSIGN *p){
2325 
2326     int32_t *dachans =
2327       (int32_t *) csound->QueryGlobalVariable(csound, "_DAC_CHANNELS_");
2328     if (UNLIKELY(dachans == NULL)) {
2329       csound->Warning(csound, Str("number of hardware output channels"
2330                                   " not currently available"));
2331     }
2332     else *p->r = *dachans;
2333     dachans = (int32_t *) csound->QueryGlobalVariable(csound, "_ADC_CHANNELS_");
2334     if (UNLIKELY(dachans == NULL)) {
2335       csound->Warning(csound, Str("number of hardware input channels"
2336                                   " not currently available"));
2337     }
2338     else *p->a = *dachans;
2339     return OK;
2340 }
2341