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