1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*
22 compound formulas :
23 amclip out = B<=0 ? 0 : A*B; // two quadrant amplitude modulation
24 ring1 out = A*(B+1) = A*B + A; // amplitude modulation of a by b.
25 ring2 out = A*B + A + B; // ring modulation plus both original signals
26 ring3 out = A*A*B; // ring modulation variant
27 ring4 out = A*A*B - A*B*B; // ring modulation variant
28 difsqr out = A*A - B*B; // difference of squares
29 sumsqr out = A*A + B*B; // sum of squares
30 sqrdif out = (A - B)^2 // square of the difference = a^2 + b^2 - 2ab
31 sqrsum out = (A + B)^2 // square of the sum = a^2 + b^2 + 2ab
32 */
33
34 #include <math.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include "PyrSignal.h"
38 #include "PyrKernel.h"
39 #include "SC_InlineUnaryOp.h"
40 #include "SC_InlineBinaryOp.h"
41 #include "SCBase.h"
42 #include "InitAlloc.h"
43
newPyrSignal(VMGlobals * g,long size)44 PyrObject* newPyrSignal(VMGlobals* g, long size) {
45 PyrObject* signal;
46 long numbytes = size * sizeof(float);
47 signal = (PyrObject*)g->gc->New(numbytes, 0, obj_float, true);
48 if (signal) {
49 signal->classptr = class_signal;
50 signal->size = size;
51 }
52 // note: signal is filled with garbage
53 return signal;
54 }
55
56 /*PyrObject* newPyrSignalFrom(VMGlobals *g, PyrObject* inSignal, long size)
57 {
58 PyrObject *signal;
59 double *pslot, *qslot, *endptr;
60 long set, m, mmax;
61 long numbytes = size * sizeof(float);
62 signal = (PyrObject*)g->gc->New(numbytes, 0, obj_float, true);
63 signal->classptr = inSignal->classptr;
64 signal->size = size;
65 return signal;
66 }
67 */
68
signal_fill(PyrObject * outSignal,float inValue)69 PyrObject* signal_fill(PyrObject* outSignal, float inValue) {
70 float* out = (float*)(outSignal->slots) - 1;
71 UNROLL_CODE(outSignal->size, out, *++out = inValue;);
72 return outSignal;
73 }
74
signal_scale(PyrObject * outSignal,float inValue)75 PyrObject* signal_scale(PyrObject* outSignal, float inValue) {
76 if (inValue != 1.f) {
77 float* out = (float*)(outSignal->slots) - 1;
78 UNROLL_CODE(outSignal->size, out, *++out *= inValue;)
79 }
80 return outSignal;
81 }
82
signal_offset(PyrObject * outSignal,float inValue)83 PyrObject* signal_offset(PyrObject* outSignal, float inValue) {
84 if (inValue != 0.f) {
85 float* out = (float*)(outSignal->slots) - 1;
86 UNROLL_CODE(outSignal->size, out, *++out += inValue;)
87 }
88 return outSignal;
89 }
90
signal_add_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)91 PyrObject* signal_add_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP1(+); }
92
signal_mul_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)93 PyrObject* signal_mul_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP1(*); }
94
signal_sub_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)95 PyrObject* signal_sub_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP2(*++c = *++a - *++b;); }
96
signal_ring1_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)97 PyrObject* signal_ring1_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP2(++a; *++c = *a * *++b + *a;); }
98
signal_ring2_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)99 PyrObject* signal_ring2_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
100 BINOP_LOOP2(++a; ++b; *++c = *a * *b + *a + *b;);
101 }
102
signal_ring3_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)103 PyrObject* signal_ring3_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP2(++a; *++c = *a * *a * *++b;); }
104
signal_ring4_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)105 PyrObject* signal_ring4_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
106 BINOP_LOOP2(++a; ++b; *++c = *a * *a * *b - *a * *b * *b;);
107 }
108
signal_thresh_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)109 PyrObject* signal_thresh_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
110 BINOP_LOOP2(++a; ++b; *++c = *a < *b ? 0.f : *a;);
111 }
112
signal_amclip_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)113 PyrObject* signal_amclip_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
114 BINOP_LOOP2(++a; ++b; *++c = *b <= 0.f ? 0.f : *a * *b;);
115 }
116
signal_div_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)117 PyrObject* signal_div_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP2(*++c = *++a / *++b;); }
118
signal_difsqr_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)119 PyrObject* signal_difsqr_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
120 BINOP_LOOP2(++a; ++b; *c = *a * *a - *b * *b;);
121 }
122
signal_sumsqr_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)123 PyrObject* signal_sumsqr_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
124 BINOP_LOOP2(++a; ++b; *c = *a * *a + *b * *b;);
125 }
126
signal_sqrsum_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)127 PyrObject* signal_sqrsum_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
128 float z;
129 BINOP_LOOP2(z = *++a + *++b; *++c = z * z;);
130 }
131
signal_sqrdif_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)132 PyrObject* signal_sqrdif_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
133 float z;
134 BINOP_LOOP2(z = *++a - *++b; *++c = z * z;);
135 }
136
signal_absdif_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)137 PyrObject* signal_absdif_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) { BINOP_LOOP2(*++c = fabs(*++a - *++b);); }
138
signal_add_xf(VMGlobals * g,PyrObject * ina,float inb)139 PyrObject* signal_add_xf(VMGlobals* g, PyrObject* ina, float inb) {
140 PyrObject* outc = newPyrSignal(g, ina->size);
141 if (inb == 0.f) {
142 float* a = (float*)(ina->slots);
143 memcpy((float*)(outc->slots), a, ina->size * sizeof(float));
144 } else {
145 float* a = (float*)(ina->slots) - 1;
146 float* c = (float*)(outc->slots) - 1;
147 UNROLL_CODE(outc->size, c, *++c = *++a + inb;)
148 }
149 return outc;
150 }
151
signal_sub_xf(VMGlobals * g,PyrObject * ina,float inb)152 PyrObject* signal_sub_xf(VMGlobals* g, PyrObject* ina, float inb) {
153 PyrObject* outc = newPyrSignal(g, ina->size);
154 if (inb == 0.f) {
155 float* a = (float*)(ina->slots);
156 memcpy((float*)(outc->slots), a, ina->size * sizeof(float));
157 } else {
158 float* a = (float*)(ina->slots) - 1;
159 float* c = (float*)(outc->slots) - 1;
160 UNROLL_CODE(outc->size, c, *++c = *++a - inb;)
161 }
162 return outc;
163 }
164
signal_mul_xf(VMGlobals * g,PyrObject * ina,float inb)165 PyrObject* signal_mul_xf(VMGlobals* g, PyrObject* ina, float inb) {
166 PyrObject* outc = newPyrSignal(g, ina->size);
167 if (inb == 1.f) {
168 float* a = (float*)(ina->slots);
169 memcpy((float*)(outc->slots), a, ina->size * sizeof(float));
170 } else {
171 float* a = (float*)(ina->slots) - 1;
172 float* c = (float*)(outc->slots) - 1;
173 UNROLL_CODE(outc->size, c, *++c = *++a * inb;)
174 }
175 return outc;
176 }
177
signal_ring1_xf(VMGlobals * g,PyrObject * ina,float inb)178 PyrObject* signal_ring1_xf(VMGlobals* g, PyrObject* ina, float inb) {
179 PyrObject* outc = newPyrSignal(g, ina->size);
180 float* a = (float*)(ina->slots) - 1;
181 float* c = (float*)(outc->slots) - 1;
182 UNROLL_CODE(outc->size, c, ++a; *++c = *a * inb + *a;)
183 return outc;
184 }
185
signal_ring2_xf(VMGlobals * g,PyrObject * ina,float inb)186 PyrObject* signal_ring2_xf(VMGlobals* g, PyrObject* ina, float inb) {
187 PyrObject* outc = newPyrSignal(g, ina->size);
188 float* a = (float*)(ina->slots) - 1;
189 float* c = (float*)(outc->slots) - 1;
190 UNROLL_CODE(outc->size, c, ++a; *++c = *a * inb + *a + inb;)
191 return outc;
192 }
193
signal_ring3_xf(VMGlobals * g,PyrObject * ina,float inb)194 PyrObject* signal_ring3_xf(VMGlobals* g, PyrObject* ina, float inb) {
195 PyrObject* outc = newPyrSignal(g, ina->size);
196 float* a = (float*)(ina->slots) - 1;
197 float* c = (float*)(outc->slots) - 1;
198 UNROLL_CODE(outc->size, c, ++a; *++c = *a * *a * inb;)
199 return outc;
200 }
201
signal_ring4_xf(VMGlobals * g,PyrObject * ina,float inb)202 PyrObject* signal_ring4_xf(VMGlobals* g, PyrObject* ina, float inb) {
203 PyrObject* outc = newPyrSignal(g, ina->size);
204 float* a = (float*)(ina->slots) - 1;
205 float* c = (float*)(outc->slots) - 1;
206 float inb2 = inb * inb;
207 UNROLL_CODE(outc->size, c, ++a; *++c = *a * *a * inb + *a * inb2;)
208 return outc;
209 }
210
211
signal_thresh_xf(VMGlobals * g,PyrObject * ina,float inb)212 PyrObject* signal_thresh_xf(VMGlobals* g, PyrObject* ina, float inb) {
213 PyrObject* outc = newPyrSignal(g, ina->size);
214 float* a = (float*)(ina->slots) - 1;
215 float* c = (float*)(outc->slots) - 1;
216 float inb2 = inb * inb;
217 UNROLL_CODE(outc->size, c, ++a; *++c = *a < inb2 ? 0.f : *a;)
218 return outc;
219 }
220
signal_amclip_xf(VMGlobals * g,PyrObject * ina,float inb)221 PyrObject* signal_amclip_xf(VMGlobals* g, PyrObject* ina, float inb) {
222 PyrObject* res;
223 PyrObject* outc = newPyrSignal(g, ina->size);
224 if (inb <= 0.f)
225 res = signal_fill(outc, 0.f);
226 else
227 res = signal_scale(outc, inb);
228 return res;
229 }
230
signal_div_xf(VMGlobals * g,PyrObject * ina,float inb)231 PyrObject* signal_div_xf(VMGlobals* g, PyrObject* ina, float inb) {
232 PyrObject* outc = newPyrSignal(g, ina->size);
233 if (inb == 1.f) {
234 float* a = (float*)(ina->slots);
235 memcpy((float*)(outc->slots), a, ina->size * sizeof(float));
236 } else {
237 float* a = (float*)(ina->slots) - 1;
238 float* c = (float*)(outc->slots) - 1;
239 inb = 1.f / inb;
240 UNROLL_CODE(outc->size, c, *++c = *++a * inb;)
241 }
242 return outc;
243 }
244
signal_difsqr_xf(VMGlobals * g,PyrObject * ina,float inb)245 PyrObject* signal_difsqr_xf(VMGlobals* g, PyrObject* ina, float inb) {
246 PyrObject* outc = newPyrSignal(g, ina->size);
247 float* a = (float*)(ina->slots) - 1;
248 float* c = (float*)(outc->slots) - 1;
249 inb = inb * inb;
250 UNROLL_CODE(outc->size, c, ++a; *++c = *a * *a - inb;)
251 return outc;
252 }
253
signal_sumsqr_xf(VMGlobals * g,PyrObject * ina,float inb)254 PyrObject* signal_sumsqr_xf(VMGlobals* g, PyrObject* ina, float inb) {
255 PyrObject* outc = newPyrSignal(g, ina->size);
256 float* a = (float*)(ina->slots) - 1;
257 float* c = (float*)(outc->slots) - 1;
258 inb = inb * inb;
259 UNROLL_CODE(outc->size, c, ++a; *++c = *a * *a + inb;)
260 return outc;
261 }
262
signal_sqrsum_xf(VMGlobals * g,PyrObject * ina,float inb)263 PyrObject* signal_sqrsum_xf(VMGlobals* g, PyrObject* ina, float inb) {
264 PyrObject* outc = newPyrSignal(g, ina->size);
265 float* a = (float*)(ina->slots) - 1;
266 float* c = (float*)(outc->slots) - 1;
267 float temp;
268 UNROLL_CODE(outc->size, c, ++a; temp = *a + inb; *++c = temp * temp;)
269 return outc;
270 }
271
signal_sqrdif_xf(VMGlobals * g,PyrObject * ina,float inb)272 PyrObject* signal_sqrdif_xf(VMGlobals* g, PyrObject* ina, float inb) {
273 PyrObject* outc = newPyrSignal(g, ina->size);
274 float* a = (float*)(ina->slots) - 1;
275 float* c = (float*)(outc->slots) - 1;
276 float temp;
277 UNROLL_CODE(outc->size, c, ++a; temp = *a - inb; *++c = temp * temp;)
278 return outc;
279 }
280
signal_absdif_xf(VMGlobals * g,PyrObject * ina,float inb)281 PyrObject* signal_absdif_xf(VMGlobals* g, PyrObject* ina, float inb) {
282 PyrObject* outc = newPyrSignal(g, ina->size);
283 float* a = (float*)(ina->slots) - 1;
284 float* c = (float*)(outc->slots) - 1;
285 UNROLL_CODE(outc->size, c, ++a; *++c = fabs(*a - inb);)
286 return outc;
287 }
288
signal_ring1_fx(VMGlobals * g,float ina,PyrObject * inb)289 PyrObject* signal_ring1_fx(VMGlobals* g, float ina, PyrObject* inb) {
290 PyrObject* outc = newPyrSignal(g, inb->size);
291 float* b = (float*)(inb->slots) - 1;
292 float* c = (float*)(outc->slots) - 1;
293 UNROLL_CODE(outc->size, c, *++c = ina * *++b + ina;)
294 return outc;
295 }
296
signal_ring2_fx(VMGlobals * g,float ina,PyrObject * inb)297 PyrObject* signal_ring2_fx(VMGlobals* g, float ina, PyrObject* inb) {
298 PyrObject* outc = newPyrSignal(g, inb->size);
299 float* b = (float*)(inb->slots) - 1;
300 float* c = (float*)(outc->slots) - 1;
301 UNROLL_CODE(outc->size, c, ++b; *++c = ina * *b + ina + *b;)
302 return outc;
303 }
304
signal_ring3_fx(VMGlobals * g,float ina,PyrObject * inb)305 PyrObject* signal_ring3_fx(VMGlobals* g, float ina, PyrObject* inb) {
306 PyrObject* outc = newPyrSignal(g, inb->size);
307 float* b = (float*)(inb->slots) - 1;
308 float* c = (float*)(outc->slots) - 1;
309 float ina2 = ina * ina;
310 UNROLL_CODE(outc->size, c, *++c = ina2 * *++b;)
311 return outc;
312 }
313
signal_ring4_fx(VMGlobals * g,float ina,PyrObject * inb)314 PyrObject* signal_ring4_fx(VMGlobals* g, float ina, PyrObject* inb) {
315 PyrObject* outc = newPyrSignal(g, inb->size);
316 float* b = (float*)(inb->slots) - 1;
317 float* c = (float*)(outc->slots) - 1;
318 float ina2 = ina * ina;
319 UNROLL_CODE(outc->size, c, ++b; *++c = ina2 * *b - ina * *b * *b;)
320 return outc;
321 }
322
signal_thresh_fx(VMGlobals * g,float ina,PyrObject * inb)323 PyrObject* signal_thresh_fx(VMGlobals* g, float ina, PyrObject* inb) {
324 PyrObject* outc = newPyrSignal(g, inb->size);
325 float* b = (float*)(inb->slots) - 1;
326 float* c = (float*)(outc->slots) - 1;
327 UNROLL1_CODE(outc->size, c, ++b; *++c = ina < *b ? 0.f : ina;)
328 return outc;
329 }
330
signal_amclip_fx(VMGlobals * g,float ina,PyrObject * inb)331 PyrObject* signal_amclip_fx(VMGlobals* g, float ina, PyrObject* inb) {
332 PyrObject* outc = newPyrSignal(g, inb->size);
333 float* b = (float*)(inb->slots) - 1;
334 float* c = (float*)(outc->slots) - 1;
335 UNROLL1_CODE(outc->size, c, ++b; *++c = *b <= 0.f ? 0.f : ina * *b;)
336 return outc;
337 }
338
signal_sub_fx(VMGlobals * g,float ina,PyrObject * inb)339 PyrObject* signal_sub_fx(VMGlobals* g, float ina, PyrObject* inb) {
340 PyrObject* outc = newPyrSignal(g, inb->size);
341 float* b = (float*)(inb->slots) - 1;
342 float* c = (float*)(outc->slots) - 1;
343 UNROLL_CODE(outc->size, c, *++c = ina - *++b;)
344 return outc;
345 }
346
signal_div_fx(VMGlobals * g,float ina,PyrObject * inb)347 PyrObject* signal_div_fx(VMGlobals* g, float ina, PyrObject* inb) {
348 PyrObject* outc = newPyrSignal(g, inb->size);
349 float* b = (float*)(inb->slots) - 1;
350 float* c = (float*)(outc->slots) - 1;
351 UNROLL_CODE(outc->size, c, *++c = ina / *++b;)
352 return outc;
353 }
354
signal_difsqr_fx(VMGlobals * g,float ina,PyrObject * inb)355 PyrObject* signal_difsqr_fx(VMGlobals* g, float ina, PyrObject* inb) {
356 PyrObject* outc = newPyrSignal(g, inb->size);
357 float* b = (float*)(inb->slots) - 1;
358 float* c = (float*)(outc->slots) - 1;
359 ina = ina * ina;
360 UNROLL_CODE(outc->size, c, ++b; *++c = ina - *b * *b;)
361 return outc;
362 }
363
signal_sumsqr_fx(VMGlobals * g,float ina,PyrObject * inb)364 PyrObject* signal_sumsqr_fx(VMGlobals* g, float ina, PyrObject* inb) {
365 PyrObject* outc = newPyrSignal(g, inb->size);
366 float* b = (float*)(inb->slots) - 1;
367 float* c = (float*)(outc->slots) - 1;
368 ina = ina * ina;
369 UNROLL_CODE(outc->size, c, ++b; *++c = ina + *b * *b;)
370 return outc;
371 }
372
signal_sqrsum_fx(VMGlobals * g,float ina,PyrObject * inb)373 PyrObject* signal_sqrsum_fx(VMGlobals* g, float ina, PyrObject* inb) {
374 PyrObject* outc = newPyrSignal(g, inb->size);
375 float temp;
376 float* b = (float*)(inb->slots) - 1;
377 float* c = (float*)(outc->slots) - 1;
378 UNROLL_CODE(outc->size, c, ++b; temp = ina + *b; *++c = temp * temp;)
379 return outc;
380 }
381
signal_sqrdif_fx(VMGlobals * g,float ina,PyrObject * inb)382 PyrObject* signal_sqrdif_fx(VMGlobals* g, float ina, PyrObject* inb) {
383 PyrObject* outc = newPyrSignal(g, inb->size);
384 float temp;
385 float* b = (float*)(inb->slots) - 1;
386 float* c = (float*)(outc->slots) - 1;
387 UNROLL_CODE(outc->size, c, ++b; temp = ina - *b; *++c = temp * temp;)
388 return outc;
389 }
390
signal_absdif_fx(VMGlobals * g,float ina,PyrObject * inb)391 PyrObject* signal_absdif_fx(VMGlobals* g, float ina, PyrObject* inb) {
392 PyrObject* outc = newPyrSignal(g, inb->size);
393 float* b = (float*)(inb->slots) - 1;
394 float* c = (float*)(outc->slots) - 1;
395 UNROLL_CODE(outc->size, c, ++b; *++c = fabs(ina - *b);)
396 return outc;
397 }
398
signal_min_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)399 PyrObject* signal_min_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
400 BINOP_LOOP2(++a; ++b; *++c = *a < *b ? *a : *b;);
401 }
402
signal_max_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)403 PyrObject* signal_max_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
404 BINOP_LOOP2(++a; ++b; *++c = *a > *b ? *a : *b;);
405 }
406
signal_scaleneg_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)407 PyrObject* signal_scaleneg_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
408 BINOP_LOOP2(++a; ++b; *++c = *a < 0.f ? *a * *b : *a;);
409 }
410
signal_clip2_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)411 PyrObject* signal_clip2_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
412 BINOP_LOOP2(++a; ++b; *++c = *a > *b ? *b : (*a < -*b ? -*b : *a););
413 }
414
signal_fold2_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)415 PyrObject* signal_fold2_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
416 BINOP_LOOP2(++a; ++b; *++c = sc_fold(*a, -*b, *b););
417 }
418
signal_wrap2_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)419 PyrObject* signal_wrap2_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
420 BINOP_LOOP2(++a; ++b; *++c = sc_wrap(*a, -*b, *b););
421 }
422
signal_excess_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)423 PyrObject* signal_excess_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
424 BINOP_LOOP2(++a; ++b; *++c = *a > *b ? *a - *b : (*a < -*b ? *a + *b : 0.f););
425 }
426
signal_equal_xx(VMGlobals * g,PyrObject * ina,PyrObject * inb)427 bool signal_equal_xx(VMGlobals* g, PyrObject* ina, PyrObject* inb) {
428 if (ina->size != inb->size)
429 return false;
430 if (slotRawSymbol(&ina->slots[kSignalRate]) != slotRawSymbol(&inb->slots[kSignalRate]))
431 return false;
432 float* a = (float*)(ina->slots);
433 float* b = (float*)(inb->slots);
434 for (int i = 0; i < ina->size; i++) {
435 if (a[i] != b[i]) {
436 return false;
437 }
438 }
439 return true;
440 }
441
signal_min_xf(VMGlobals * g,PyrObject * ina,float inb)442 PyrObject* signal_min_xf(VMGlobals* g, PyrObject* ina, float inb) {
443 PyrObject* outc = newPyrSignal(g, ina->size);
444 float* a = (float*)(ina->slots) - 1;
445 float* c = (float*)(outc->slots) - 1;
446 UNROLL1_CODE(outc->size, c, ++a; *++c = *a < inb ? *a : inb;)
447 return outc;
448 }
449
signal_max_xf(VMGlobals * g,PyrObject * ina,float inb)450 PyrObject* signal_max_xf(VMGlobals* g, PyrObject* ina, float inb) {
451 PyrObject* outc = newPyrSignal(g, ina->size);
452 float* a = (float*)(ina->slots) - 1;
453 float* c = (float*)(outc->slots) - 1;
454 UNROLL1_CODE(outc->size, c, ++a; *++c = *a > inb ? *a : inb;)
455 return outc;
456 }
457
signal_scaleneg_xf(VMGlobals * g,PyrObject * ina,float inb)458 PyrObject* signal_scaleneg_xf(VMGlobals* g, PyrObject* ina, float inb) {
459 PyrObject* outc = newPyrSignal(g, ina->size);
460 float* a = (float*)(ina->slots) - 1;
461 float* c = (float*)(outc->slots) - 1;
462 UNROLL1_CODE(outc->size, c, ++a; *++c = *a < 0.f ? *a * inb : *a;)
463 return outc;
464 }
465
signal_clip2_xf(VMGlobals * g,PyrObject * ina,float inb)466 PyrObject* signal_clip2_xf(VMGlobals* g, PyrObject* ina, float inb) {
467 PyrObject* outc = newPyrSignal(g, ina->size);
468 float* a = (float*)(ina->slots) - 1;
469 float* c = (float*)(outc->slots) - 1;
470 UNROLL1_CODE(outc->size, c, ++a; *++c = *a > inb ? inb : (*a < -inb ? -inb : *a);)
471 return outc;
472 }
473
signal_fold2_xf(VMGlobals * g,PyrObject * ina,float inb)474 PyrObject* signal_fold2_xf(VMGlobals* g, PyrObject* ina, float inb) {
475 PyrObject* outc = newPyrSignal(g, ina->size);
476 float* a = (float*)(ina->slots) - 1;
477 float* c = (float*)(outc->slots) - 1;
478 UNROLL1_CODE(outc->size, c, ++a; *++c = sc_fold(*a, -inb, inb);)
479 return outc;
480 }
481
signal_wrap2_xf(VMGlobals * g,PyrObject * ina,float inb)482 PyrObject* signal_wrap2_xf(VMGlobals* g, PyrObject* ina, float inb) {
483 PyrObject* outc = newPyrSignal(g, ina->size);
484 float* a = (float*)(ina->slots) - 1;
485 float* c = (float*)(outc->slots) - 1;
486 UNROLL1_CODE(outc->size, c, ++a; *++c = sc_wrap(*a, -inb, inb);)
487 return outc;
488 }
489
signal_excess_xf(VMGlobals * g,PyrObject * ina,float inb)490 PyrObject* signal_excess_xf(VMGlobals* g, PyrObject* ina, float inb) {
491 PyrObject* outc = newPyrSignal(g, ina->size);
492 float* a = (float*)(ina->slots) - 1;
493 float* c = (float*)(outc->slots) - 1;
494 UNROLL1_CODE(outc->size, c, ++a; *++c = *a > inb ? *a - inb : (*a < -inb ? *a + inb : 0.f);)
495 return outc;
496 }
497
signal_scaleneg_fx(VMGlobals * g,float ina,PyrObject * inb)498 PyrObject* signal_scaleneg_fx(VMGlobals* g, float ina, PyrObject* inb) {
499 PyrObject* outc = newPyrSignal(g, inb->size);
500 float* b = (float*)(inb->slots) - 1;
501 float* c = (float*)(outc->slots) - 1;
502 if (ina < 0.f) {
503 UNROLL1_CODE(outc->size, c, *++c = ina * *++b;);
504 } else {
505 UNROLL1_CODE(outc->size, c, *++c = ina;);
506 }
507 return outc;
508 }
509
signal_clip2_fx(VMGlobals * g,float ina,PyrObject * inb)510 PyrObject* signal_clip2_fx(VMGlobals* g, float ina, PyrObject* inb) {
511 PyrObject* outc = newPyrSignal(g, inb->size);
512 float* b = (float*)(inb->slots) - 1;
513 float* c = (float*)(outc->slots) - 1;
514 UNROLL1_CODE(outc->size, c, ++b; *++c = ina > *b ? *b : (ina < -*b ? -*b : ina);)
515 return outc;
516 }
517
signal_fold2_fx(VMGlobals * g,float ina,PyrObject * inb)518 PyrObject* signal_fold2_fx(VMGlobals* g, float ina, PyrObject* inb) {
519 PyrObject* outc = newPyrSignal(g, inb->size);
520 float* b = (float*)(inb->slots) - 1;
521 float* c = (float*)(outc->slots) - 1;
522 UNROLL1_CODE(outc->size, c, ++b; *++c = sc_fold(ina, -*b, *b);)
523 return outc;
524 }
525
signal_wrap2_fx(VMGlobals * g,float ina,PyrObject * inb)526 PyrObject* signal_wrap2_fx(VMGlobals* g, float ina, PyrObject* inb) {
527 PyrObject* outc = newPyrSignal(g, inb->size);
528 float* b = (float*)(inb->slots) - 1;
529 float* c = (float*)(outc->slots) - 1;
530 UNROLL1_CODE(outc->size, c, ++b; *++c = sc_wrap(ina, -*b, *b);)
531 return outc;
532 }
533
signal_excess_fx(VMGlobals * g,float ina,PyrObject * inb)534 PyrObject* signal_excess_fx(VMGlobals* g, float ina, PyrObject* inb) {
535 PyrObject* outc = newPyrSignal(g, inb->size);
536 float* b = (float*)(inb->slots) - 1;
537 float* c = (float*)(outc->slots) - 1;
538 UNROLL1_CODE(outc->size, c, ++b; *++c = ina > *b ? ina - *b : (ina < -*b ? ina + *b : 0.f);)
539 return outc;
540 }
541
signal_invert(VMGlobals * g,PyrObject * inPyrSignal)542 PyrObject* signal_invert(VMGlobals* g, PyrObject* inPyrSignal) {
543 float* in = (float*)(inPyrSignal->slots) - 1;
544 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
545 float* out = (float*)(outc->slots) - 1;
546 UNROLL_CODE(inPyrSignal->size, out, *++out = -*++in;)
547 return outc;
548 }
549
signal_recip(VMGlobals * g,PyrObject * inPyrSignal)550 PyrObject* signal_recip(VMGlobals* g, PyrObject* inPyrSignal) {
551 float* in = (float*)(inPyrSignal->slots) - 1;
552 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
553 float* out = (float*)(outc->slots) - 1;
554 UNROLL_CODE(inPyrSignal->size, out, *++out = 1.f / *++in;)
555 return outc;
556 }
557
signal_squared(VMGlobals * g,PyrObject * inPyrSignal)558 PyrObject* signal_squared(VMGlobals* g, PyrObject* inPyrSignal) {
559 float* in = (float*)(inPyrSignal->slots) - 1;
560 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
561 float* out = (float*)(outc->slots) - 1;
562 UNROLL_CODE(inPyrSignal->size, out, ++in; *++out = *in * *in;)
563 return outc;
564 }
565
signal_cubed(VMGlobals * g,PyrObject * inPyrSignal)566 PyrObject* signal_cubed(VMGlobals* g, PyrObject* inPyrSignal) {
567 float* in = (float*)(inPyrSignal->slots) - 1;
568 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
569 float* out = (float*)(outc->slots) - 1;
570 UNROLL_CODE(inPyrSignal->size, out, ++in; *++out = *in * *in * *in;)
571 return outc;
572 }
573
574 // PowerPC has a fast fabs instruction
signal_abs(VMGlobals * g,PyrObject * inPyrSignal)575 PyrObject* signal_abs(VMGlobals* g, PyrObject* inPyrSignal) {
576 float* in = (float*)(inPyrSignal->slots) - 1;
577 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
578 float* out = (float*)(outc->slots) - 1;
579 UNROLL_CODE(inPyrSignal->size, out, *++out = fabs(*++in);)
580 return outc;
581 }
582
signal_findpeak(PyrObject * inPyrSignal)583 float signal_findpeak(PyrObject* inPyrSignal) {
584 float* out = (float*)(inPyrSignal->slots) - 1;
585 float peak = 0.f;
586 float z;
587 UNROLL1_CODE(inPyrSignal->size, out, ++out; z = fabs(*out); peak = z > peak ? z : peak;)
588 return peak;
589 }
590
signal_normalize_transfer_fn(PyrObject * inPyrSignal)591 PyrObject* signal_normalize_transfer_fn(PyrObject* inPyrSignal) {
592 float *out, scale, offset, x, maxval;
593 long length, halflength;
594
595 maxval = 0.0;
596 out = (float*)(inPyrSignal->slots) - 1;
597 length = inPyrSignal->size;
598 halflength = length >> 1;
599 offset = (out[halflength - 1] + out[halflength]) * 0.5;
600
601 UNROLL1_CODE(inPyrSignal->size, out, ++out; x = *out - offset; x = (x < 0.) ? -x : x; if (x > maxval) maxval = x;);
602 if (maxval) {
603 out = (float*)(inPyrSignal->slots) - 1;
604 scale = 1.0 / maxval;
605 UNROLL1_CODE(inPyrSignal->size, out, ++out; *out = (*out - offset) * scale;);
606 }
607 return inPyrSignal;
608 }
609
610
signal_integral(PyrObject * inPyrSignal)611 float signal_integral(PyrObject* inPyrSignal) {
612 float* out = (float*)(inPyrSignal->slots) - 1;
613 float sum = 0.f;
614 UNROLL1_CODE(inPyrSignal->size, out, sum += *++out;)
615 return sum;
616 }
617
signal_sign(VMGlobals * g,PyrObject * inPyrSignal)618 PyrObject* signal_sign(VMGlobals* g, PyrObject* inPyrSignal) {
619 float* in = (float*)(inPyrSignal->slots) - 1;
620 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
621 float* out = (float*)(outc->slots) - 1;
622 UNROLL1_CODE(inPyrSignal->size, out, ++in; *++out = *in < 0.f ? -1.f : (*in > 0.f ? 1.f : 0.f);)
623 return outc;
624 }
625
signal_negative(VMGlobals * g,PyrObject * inPyrSignal)626 PyrObject* signal_negative(VMGlobals* g, PyrObject* inPyrSignal) {
627 float* in = (float*)(inPyrSignal->slots) - 1;
628 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
629 float* out = (float*)(outc->slots) - 1;
630 UNROLL1_CODE(inPyrSignal->size, out, *++out = *++in < 0.f ? 1.f : 0.f;)
631 return outc;
632 }
633
signal_positive(VMGlobals * g,PyrObject * inPyrSignal)634 PyrObject* signal_positive(VMGlobals* g, PyrObject* inPyrSignal) {
635 float* in = (float*)(inPyrSignal->slots) - 1;
636 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
637 float* out = (float*)(outc->slots) - 1;
638 UNROLL1_CODE(inPyrSignal->size, out, *++out = *++in >= 0.f ? 1.f : 0.f;)
639 return outc;
640 }
641
signal_strictly_positive(VMGlobals * g,PyrObject * inPyrSignal)642 PyrObject* signal_strictly_positive(VMGlobals* g, PyrObject* inPyrSignal) {
643 float* in = (float*)(inPyrSignal->slots) - 1;
644 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
645 float* out = (float*)(outc->slots) - 1;
646 UNROLL1_CODE(inPyrSignal->size, out, *++out = *++in > 0.f ? 1.f : 0.f;)
647 return outc;
648 }
649
signal_nyqring(VMGlobals * g,PyrObject * inPyrSignal)650 PyrObject* signal_nyqring(VMGlobals* g, PyrObject* inPyrSignal) {
651 float* in = (float*)(inPyrSignal->slots) - 1;
652 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
653 float* out = (float*)(outc->slots) - 1;
654 float* endptr = out + inPyrSignal->size;
655 switch (inPyrSignal->size & 3) {
656 while (out < endptr) {
657 *++out = -*++in;
658 case 3:
659 *++out = *++in;
660 case 2:
661 *++out = -*++in;
662 case 1:
663 *++out = *++in;
664 case 0:;
665 }
666 }
667 return outc;
668 }
669
signal_clip_f(VMGlobals * g,PyrObject * inPyrSignal,float lo,float hi)670 PyrObject* signal_clip_f(VMGlobals* g, PyrObject* inPyrSignal, float lo, float hi) {
671 float* in = (float*)(inPyrSignal->slots) - 1;
672 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
673 float* out = (float*)(outc->slots) - 1;
674 float* endptr = out + inPyrSignal->size;
675 while (out < endptr) {
676 ++in;
677 *++out = *in < lo ? lo : (*in > hi ? hi : *in);
678 }
679 return outc;
680 }
681
signal_clip_x(VMGlobals * g,PyrObject * ina,PyrObject * inb,PyrObject * inc)682 PyrObject* signal_clip_x(VMGlobals* g, PyrObject* ina, PyrObject* inb, PyrObject* inc) {
683 PyrObject* outd;
684 float *a, *b, *c, *d, *endptr;
685 long minsize = sc_min(ina->size, inb->size);
686 minsize = sc_min(minsize, inc->size);
687 outd = newPyrSignal(g, minsize);
688 a = (float*)(ina->slots) - 1;
689 b = (float*)(inb->slots) - 1;
690 c = (float*)(inc->slots) - 1;
691 d = (float*)(outd->slots) - 1;
692 endptr = a + minsize;
693 UNROLL1_CODE(outd->size, d, ++a; ++b; ++c; *++d = *a < *b ? *b : (*a > *c ? *c : *a););
694 return outd;
695 }
696
697
698 /// WRAP AND FOLD ARE STILL INCORRECT !
699
signal_wrap_f(VMGlobals * g,PyrObject * inPyrSignal,float lo,float hi)700 PyrObject* signal_wrap_f(VMGlobals* g, PyrObject* inPyrSignal, float lo, float hi) {
701 float* out = (float*)(inPyrSignal->slots) - 1;
702 float* endptr = out + inPyrSignal->size;
703 while (out < endptr) {
704 ++out;
705 *out = sc_wrap(*out, lo, hi);
706 }
707 return inPyrSignal;
708 }
709
signal_wrap_x(VMGlobals * g,PyrObject * ina,PyrObject * inb,PyrObject * inc)710 PyrObject* signal_wrap_x(VMGlobals* g, PyrObject* ina, PyrObject* inb, PyrObject* inc) {
711 PyrObject* outd;
712 float *a, *b, *c, *d, *endptr;
713 long minsize = sc_min(ina->size, inb->size);
714 minsize = sc_min(minsize, inc->size);
715 outd = newPyrSignal(g, minsize);
716 a = (float*)(ina->slots) - 1;
717 b = (float*)(inb->slots) - 1;
718 c = (float*)(inc->slots) - 1;
719 d = (float*)(outd->slots) - 1;
720 endptr = d + outd->size;
721 while (d < endptr) {
722 a++;
723 b++;
724 c++;
725 d++;
726 ++d;
727 *d = sc_wrap(*a, *b, *c);
728 }
729 return outd;
730 }
731
signal_fold_f(VMGlobals * g,PyrObject * inPyrSignal,float lo,float hi)732 PyrObject* signal_fold_f(VMGlobals* g, PyrObject* inPyrSignal, float lo, float hi) {
733 float* out = (float*)(inPyrSignal->slots) - 1;
734 float* endptr = out + inPyrSignal->size;
735 while (out < endptr) {
736 ++out;
737 *out = sc_fold(*out, lo, hi);
738 }
739 return inPyrSignal;
740 }
741
signal_fold_x(VMGlobals * g,PyrObject * ina,PyrObject * inb,PyrObject * inc)742 PyrObject* signal_fold_x(VMGlobals* g, PyrObject* ina, PyrObject* inb, PyrObject* inc) {
743 PyrObject* outd;
744 float *a, *b, *c, *d, *endptr;
745 long minsize = sc_min(ina->size, inb->size);
746 minsize = sc_min(minsize, inc->size);
747 outd = newPyrSignal(g, minsize);
748 a = (float*)(ina->slots) - 1;
749 b = (float*)(inb->slots) - 1;
750 c = (float*)(inc->slots) - 1;
751 d = (float*)(outd->slots) - 1;
752 endptr = d + outd->size;
753 while (d < endptr) {
754 a++;
755 b++;
756 c++;
757 d++;
758 *d = sc_fold(*a, *b, *c);
759 }
760 return outd;
761 }
762
signal_log(VMGlobals * g,PyrObject * inPyrSignal)763 PyrObject* signal_log(VMGlobals* g, PyrObject* inPyrSignal) {
764 float* in = (float*)(inPyrSignal->slots) - 1;
765 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
766 float* out = (float*)(outc->slots) - 1;
767 UNROLL1_CODE(inPyrSignal->size, out, *++out = log(*++in);)
768 return outc;
769 }
770
signal_log2(VMGlobals * g,PyrObject * inPyrSignal)771 PyrObject* signal_log2(VMGlobals* g, PyrObject* inPyrSignal) {
772 float* in = (float*)(inPyrSignal->slots) - 1;
773 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
774 float* out = (float*)(outc->slots) - 1;
775 UNROLL1_CODE(inPyrSignal->size, out, *++out = sc_log2(*++in);)
776 return outc;
777 }
778
signal_log10(VMGlobals * g,PyrObject * inPyrSignal)779 PyrObject* signal_log10(VMGlobals* g, PyrObject* inPyrSignal) {
780 float* in = (float*)(inPyrSignal->slots) - 1;
781 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
782 float* out = (float*)(outc->slots) - 1;
783 UNROLL1_CODE(inPyrSignal->size, out, *++out = log10(*++in);)
784 return outc;
785 }
786
787
signal_sin(VMGlobals * g,PyrObject * inPyrSignal)788 PyrObject* signal_sin(VMGlobals* g, PyrObject* inPyrSignal) {
789 float* in = (float*)(inPyrSignal->slots) - 1;
790 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
791 float* out = (float*)(outc->slots) - 1;
792 UNROLL1_CODE(inPyrSignal->size, out, *++out = sin(*++in);)
793 return outc;
794 }
795
signal_cos(VMGlobals * g,PyrObject * inPyrSignal)796 PyrObject* signal_cos(VMGlobals* g, PyrObject* inPyrSignal) {
797 float* in = (float*)(inPyrSignal->slots) - 1;
798 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
799 float* out = (float*)(outc->slots) - 1;
800 UNROLL1_CODE(inPyrSignal->size, out, *++out = cos(*++in);)
801 return outc;
802 }
803
signal_tan(VMGlobals * g,PyrObject * inPyrSignal)804 PyrObject* signal_tan(VMGlobals* g, PyrObject* inPyrSignal) {
805 float* in = (float*)(inPyrSignal->slots) - 1;
806 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
807 float* out = (float*)(outc->slots) - 1;
808 UNROLL1_CODE(inPyrSignal->size, out, *++out = tan(*++in);)
809 return outc;
810 }
811
signal_sinh(VMGlobals * g,PyrObject * inPyrSignal)812 PyrObject* signal_sinh(VMGlobals* g, PyrObject* inPyrSignal) {
813 float* in = (float*)(inPyrSignal->slots) - 1;
814 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
815 float* out = (float*)(outc->slots) - 1;
816 UNROLL1_CODE(inPyrSignal->size, out, *++out = sinh(*++in);)
817 return outc;
818 }
819
signal_cosh(VMGlobals * g,PyrObject * inPyrSignal)820 PyrObject* signal_cosh(VMGlobals* g, PyrObject* inPyrSignal) {
821 float* in = (float*)(inPyrSignal->slots) - 1;
822 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
823 float* out = (float*)(outc->slots) - 1;
824 UNROLL1_CODE(inPyrSignal->size, out, *++out = cosh(*++in);)
825 return outc;
826 }
827
signal_tanh(VMGlobals * g,PyrObject * inPyrSignal)828 PyrObject* signal_tanh(VMGlobals* g, PyrObject* inPyrSignal) {
829 float* in = (float*)(inPyrSignal->slots) - 1;
830 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
831 float* out = (float*)(outc->slots) - 1;
832 UNROLL1_CODE(inPyrSignal->size, out, *++out = tanh(*++in);)
833 return outc;
834 }
835
signal_tanh_ds(PyrObject * inPyrSignal)836 PyrObject* signal_tanh_ds(PyrObject* inPyrSignal) {
837 float* out = (float*)(inPyrSignal->slots) - 1;
838 UNROLL1_CODE(inPyrSignal->size, out, ++out; *out = tanh(*out);)
839 return inPyrSignal;
840 }
841
signal_asin(VMGlobals * g,PyrObject * inPyrSignal)842 PyrObject* signal_asin(VMGlobals* g, PyrObject* inPyrSignal) {
843 float* in = (float*)(inPyrSignal->slots) - 1;
844 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
845 float* out = (float*)(outc->slots) - 1;
846 UNROLL1_CODE(inPyrSignal->size, out, *++out = asin(*++in);)
847 return outc;
848 }
849
signal_acos(VMGlobals * g,PyrObject * inPyrSignal)850 PyrObject* signal_acos(VMGlobals* g, PyrObject* inPyrSignal) {
851 float* in = (float*)(inPyrSignal->slots) - 1;
852 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
853 float* out = (float*)(outc->slots) - 1;
854 UNROLL1_CODE(inPyrSignal->size, out, *++out = acos(*++in);)
855 return outc;
856 }
857
signal_atan(VMGlobals * g,PyrObject * inPyrSignal)858 PyrObject* signal_atan(VMGlobals* g, PyrObject* inPyrSignal) {
859 float* in = (float*)(inPyrSignal->slots) - 1;
860 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
861 float* out = (float*)(outc->slots) - 1;
862 UNROLL1_CODE(inPyrSignal->size, out, *++out = atan(*++in);)
863 return outc;
864 }
865
signal_exp(VMGlobals * g,PyrObject * inPyrSignal)866 PyrObject* signal_exp(VMGlobals* g, PyrObject* inPyrSignal) {
867 float* in = (float*)(inPyrSignal->slots) - 1;
868 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
869 float* out = (float*)(outc->slots) - 1;
870 UNROLL1_CODE(inPyrSignal->size, out, *++out = exp(*++in);)
871 return outc;
872 }
873
signal_sqrt(VMGlobals * g,PyrObject * inPyrSignal)874 PyrObject* signal_sqrt(VMGlobals* g, PyrObject* inPyrSignal) {
875 float* in = (float*)(inPyrSignal->slots) - 1;
876 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
877 float* out = (float*)(outc->slots) - 1;
878 UNROLL1_CODE(inPyrSignal->size, out, *++out = sqrt(*++in);)
879 return outc;
880 }
881
signal_distort(VMGlobals * g,PyrObject * inPyrSignal)882 PyrObject* signal_distort(VMGlobals* g, PyrObject* inPyrSignal) {
883 float* in = (float*)(inPyrSignal->slots) - 1;
884 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
885 float* out = (float*)(outc->slots) - 1;
886 float* endptr = out + inPyrSignal->size;
887 while (out < endptr) {
888 float z = *++in;
889 if (z < 0.f)
890 *++out = z / (1.f - z);
891 else
892 *++out = z / (1.f + z);
893 }
894 return outc;
895 }
896
signal_softclip(VMGlobals * g,PyrObject * inPyrSignal)897 PyrObject* signal_softclip(VMGlobals* g, PyrObject* inPyrSignal) {
898 float* in = (float*)(inPyrSignal->slots) - 1;
899 PyrObject* outc = newPyrSignal(g, inPyrSignal->size);
900 float* out = (float*)(outc->slots) - 1;
901 float* endptr = out + inPyrSignal->size;
902 while (out < endptr) {
903 float z = *++in;
904 if (z < -0.5f)
905 *++out = (-z - .25f) / z;
906 else if (z > 0.5f)
907 *++out = (z - .25f) / z;
908 else
909 *++out = z;
910 }
911 return outc;
912 }
913
914
signal_rotate(VMGlobals * g,PyrObject * ina,int rot)915 PyrObject* signal_rotate(VMGlobals* g, PyrObject* ina, int rot) {
916 long i, j;
917 PyrObject* outc = newPyrSignal(g, ina->size);
918 float* a0 = (float*)(ina->slots) - 1;
919 // float *a = a0 + sc_mod(rot, ina->size);
920 float* a = a0 + sc_mod(0 - rot, ina->size);
921 float* aend = a0 + ina->size;
922 float* c = (float*)(outc->slots) - 1;
923 long nsmps = outc->size;
924 for (i = 0, j = rot; i < nsmps; i++, j++) {
925 *++c = *++a;
926 if (a >= aend)
927 a = a0;
928 }
929 return outc;
930 }
931
signal_reverse_range(PyrObject * ina,long start,long end)932 PyrObject* signal_reverse_range(PyrObject* ina, long start, long end) {
933 long size = ina->size;
934 long size2;
935 long i;
936 start = sc_max(0, start);
937 end = sc_min(end + 1, size);
938 size = end - start;
939 size2 = size >> 1;
940 float* a = (float*)(ina->slots) - 1 + start;
941 // float *b = (float*)(ina->slots) - 1 + end;
942 float* b = (float*)(ina->slots) + end;
943 float temp;
944 for (i = 0; i < size2; ++i) {
945 temp = *++a;
946 *a = *--b;
947 *b = temp;
948 }
949 return ina;
950 }
951
signal_normalize_range(PyrObject * ina,long start,long end)952 PyrObject* signal_normalize_range(PyrObject* ina, long start, long end) {
953 long size = ina->size;
954 long i;
955 float z, scale, maxlevel;
956 float *a0, *a;
957 start = sc_max(0, start);
958 end = sc_min(end + 1, size);
959 size = end - start;
960 a0 = (float*)(ina->slots) - 1 + start;
961 a = a0;
962 maxlevel = 0.f;
963 for (i = 0; i < size; ++i) {
964 z = fabs(*++a);
965 if (z > maxlevel)
966 maxlevel = z;
967 }
968 a = a0;
969 if (maxlevel != 0.f) {
970 scale = 1. / maxlevel;
971 for (i = 0; i < size; ++i) {
972 z = *++a;
973 *a = scale * z;
974 }
975 }
976 return ina;
977 }
978
signal_invert_range(PyrObject * ina,long start,long end)979 PyrObject* signal_invert_range(PyrObject* ina, long start, long end) {
980 long size = ina->size;
981 long i;
982 float z;
983 start = sc_max(0, start);
984 end = sc_min(end, size);
985 size = end - start + 1;
986 float* a = (float*)(ina->slots) - 1 + start;
987
988 for (i = 0; i < size; ++i) {
989 z = *++a;
990 *a = -z;
991 }
992 return ina;
993 }
994
995
signal_fade_range(PyrObject * ina,long start,long end,float lvl0,float lvl1)996 PyrObject* signal_fade_range(PyrObject* ina, long start, long end, float lvl0, float lvl1) {
997 long size = ina->size;
998 long i;
999 float z, level, slope;
1000 start = sc_max(0, start);
1001 end = sc_min(end + 1, size);
1002 size = end - start;
1003 float* a = (float*)(ina->slots) - 1 + start;
1004 slope = (lvl1 - lvl0) / size;
1005 level = lvl0;
1006 for (i = 0; i < size; ++i) {
1007 z = *++a;
1008 *a = z * level;
1009 level += slope;
1010 }
1011 return ina;
1012 }
1013
1014
signal_overdub(VMGlobals * g,PyrObject * ina,PyrObject * inb,long index)1015 PyrObject* signal_overdub(VMGlobals* g, PyrObject* ina, PyrObject* inb, long index) {
1016 float *a, *b;
1017 long len;
1018
1019 if (index > 0) {
1020 a = (float*)(ina->slots) + index - 1;
1021 b = (float*)(inb->slots) - 1;
1022 len = sc_min(inb->size, ina->size - index);
1023 } else {
1024 a = (float*)(ina->slots) - 1;
1025 b = (float*)(inb->slots) - index - 1;
1026 len = sc_min(ina->size, inb->size + index);
1027 }
1028
1029 UNROLL_CODE(len, a, *++a += *++b;);
1030
1031 return ina;
1032 }
1033
signal_overwrite(VMGlobals * g,PyrObject * ina,PyrObject * inb,long index)1034 PyrObject* signal_overwrite(VMGlobals* g, PyrObject* ina, PyrObject* inb, long index) {
1035 float *a, *b;
1036 long len;
1037 if (index > 0) {
1038 a = (float*)(ina->slots) + index - 1;
1039 b = (float*)(inb->slots) - 1;
1040 len = sc_min(inb->size, ina->size - index);
1041 } else {
1042 a = (float*)(ina->slots) - 1;
1043 b = (float*)(inb->slots) - index - 1;
1044 len = sc_min(ina->size, inb->size + index);
1045 }
1046
1047 UNROLL_CODE(len, a, *++a = *++b;);
1048
1049 return ina;
1050 }
1051