Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / plugins / PanUGens.cpp
blobc146cc7a0f5eec89552b1bf4aba913b49634ee8a
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
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.
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.
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
22 #include "SC_PlugIn.h"
24 #ifdef NOVA_SIMD
25 #include "simd_memory.hpp"
26 #include "simd_binary_arithmetic.hpp"
27 #include "simd_pan.hpp"
28 #include "simd_mix.hpp"
29 using nova::slope_argument;
31 #include "function_attributes.h"
33 #endif
35 using namespace std; // for math functions
37 static InterfaceTable *ft;
39 struct LinPan2 : public Unit
41 float m_pos, m_level, m_leftamp, m_rightamp;
44 struct Balance2 : public Unit
46 float m_pos, m_level, m_leftamp, m_rightamp;
49 struct Rotate2 : public Unit
51 float m_pos, m_sint, m_cost;
54 struct XFade2 : public Unit
56 float m_pos, m_level, m_leftamp, m_rightamp;
59 struct LinXFade2 : public Unit
61 float m_pos, m_amp;
64 struct Pan2 : public Unit
66 float m_pos, m_level, m_leftamp, m_rightamp;
69 struct Pan4 : public Unit
71 float m_xpos, m_ypos, m_level, m_LF_amp, m_RF_amp, m_LB_amp, m_RB_amp;
74 struct PanB : public Unit
76 float m_azimuth, m_elevation, m_level, m_W_amp, m_X_amp, m_Y_amp, m_Z_amp;
79 struct PanB2 : public Unit
81 float m_azimuth, m_level, m_W_amp, m_X_amp, m_Y_amp;
84 struct BiPanB2 : public Unit
86 float m_azimuth, m_level, m_W_amp, m_X_amp, m_Y_amp;
89 struct PanAz : public Unit
91 float * m_chanamp;
94 struct DecodeB2 : public Unit
96 float m_cosa, m_sina;
97 float m_W_amp, m_X_amp, m_Y_amp;
100 //////////////////////////////////////////////////////////////////////////////////////////////////
102 extern "C"
104 void LinPan2_next_ak(LinPan2 *unit, int inNumSamples);
105 void LinPan2_next_aa(LinPan2 *unit, int inNumSamples);
106 void LinPan2_Ctor(LinPan2* unit);
108 void Balance2_next_ak(Balance2 *unit, int inNumSamples);
109 #ifdef NOVA_SIMD
110 FLATTEN void Balance2_next_ak_nova(Balance2 *unit, int inNumSamples);
111 FLATTEN void Balance2_next_ak_nova_64(Balance2 *unit, int inNumSamples);
112 #endif
113 void Balance2_next_aa(Balance2 *unit, int inNumSamples);
114 void Balance2_Ctor(Balance2* unit);
116 void XFade2_next_ak(XFade2 *unit, int inNumSamples);
117 void XFade2_next_aa(XFade2 *unit, int inNumSamples);
118 void XFade2_Ctor(XFade2* unit);
120 void LinXFade2_next_k(LinXFade2 *unit, int inNumSamples);
121 void LinXFade2_next_a(LinXFade2 *unit, int inNumSamples);
122 void LinXFade2_Ctor(LinXFade2* unit);
124 void Pan2_next_ak(Pan2 *unit, int inNumSamples);
125 void vPan2_next_ak(Pan2 *unit, int inNumSamples);
126 void Pan2_next_aa(Pan2 *unit, int inNumSamples);
127 void Pan2_Ctor(Pan2* unit);
129 void Pan4_next(Pan4 *unit, int inNumSamples);
130 void Pan4_Ctor(Pan4* unit);
132 void PanB_next(PanB *unit, int inNumSamples);
133 void PanB_Ctor(PanB* unit);
135 void PanB2_next(PanB2 *unit, int inNumSamples);
136 void PanB2_Ctor(PanB2* unit);
138 void BiPanB2_next(BiPanB2 *unit, int inNumSamples);
139 void BiPanB2_Ctor(BiPanB2* unit);
141 void DecodeB2_next(DecodeB2 *unit, int inNumSamples);
142 void DecodeB2_next_nova(DecodeB2 *unit, int inNumSamples);
143 void vDecodeB2_next(DecodeB2 *unit, int inNumSamples);
144 void DecodeB2_Ctor(DecodeB2* unit);
146 void PanAz_next_ak(PanAz *unit, int inNumSamples);
147 void PanAz_next_aa(PanAz *unit, int inNumSamples);
148 void PanAz_Ctor(PanAz* unit);
150 void Rotate2_next_ak(Rotate2 *unit, int inNumSamples);
151 void Rotate2_Ctor(Rotate2 *unit);
154 //////////////////////////////////////////////////////////////////////////////////////////////////
156 #ifdef NOVA_SIMD
157 FLATTEN void LinPan2_next_ak_nova(LinPan2 *unit, int inNumSamples);
158 FLATTEN void LinPan2_next_ak_nova_64(LinPan2 *unit, int inNumSamples);
159 #endif
161 void LinPan2_Ctor(LinPan2 *unit)
163 if (INRATE(1) == calc_FullRate) {
164 SETCALC(LinPan2_next_aa);
165 } else {
166 #ifdef NOVA_SIMD
167 if (BUFLENGTH == 64)
168 SETCALC(LinPan2_next_ak_nova_64);
169 if (!(BUFLENGTH & 15))
170 SETCALC(LinPan2_next_ak_nova);
171 else
172 #endif
173 SETCALC(LinPan2_next_ak);
175 // Now we need to initialise some values, which on the first _next run will be "previous"
176 float pan = ZIN0(1) * 0.5f + 0.5f;
177 unit->m_level = ZIN0(2);
178 unit->m_rightamp = unit->m_level * pan;
179 unit->m_leftamp = unit->m_level - unit->m_rightamp;
181 LinPan2_next_aa(unit, 1);
184 void LinPan2_next_ak(LinPan2 *unit, int inNumSamples)
186 float *leftout = ZOUT(0);
187 float *rightout = ZOUT(1);
188 float *in = ZIN(0);
189 float pos = ZIN0(1);
190 float level = ZIN0(2);
191 float leftamp = unit->m_leftamp;
192 float rightamp = unit->m_rightamp;
194 if (pos != unit->m_pos || unit->m_level != level) {
195 float pan = pos * 0.5f + 0.5f;
196 float nextrightamp = level * pan;
197 float nextleftamp = level - nextrightamp;
199 float slopeFactor = unit->mRate->mSlopeFactor;
200 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
201 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
203 LOOP1(inNumSamples,
204 float zin = ZXP(in);
205 ZXP(leftout) = zin * leftamp;
206 ZXP(rightout) = zin * rightamp;
207 leftamp += leftampslope;
208 rightamp += rightampslope;
210 unit->m_pos = pos;
211 unit->m_level = level;
212 unit->m_leftamp = nextleftamp;
213 unit->m_rightamp = nextrightamp;
214 } else {
215 LOOP1(inNumSamples,
216 float zin = ZXP(in);
217 ZXP(leftout) = zin * leftamp;
218 ZXP(rightout) = zin * rightamp;
223 #ifdef NOVA_SIMD
224 void LinPan2_next_ak_nova(LinPan2 *unit, int inNumSamples)
226 float pos = ZIN0(1);
227 float level = ZIN0(2);
228 float leftamp = unit->m_leftamp;
229 float rightamp = unit->m_rightamp;
231 if (pos != unit->m_pos || unit->m_level != level) {
232 float pan = pos * 0.5f + 0.5f;
233 float nextrightamp = level * pan;
234 float nextleftamp = level - nextrightamp;
236 float slopeFactor = unit->mRate->mSlopeFactor;
237 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
238 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
240 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
241 rightamp, rightampslope, inNumSamples);
242 unit->m_pos = pos;
243 unit->m_level = level;
244 unit->m_leftamp = nextleftamp;
245 unit->m_rightamp = nextrightamp;
246 } else
247 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, rightamp, inNumSamples);
250 void LinPan2_next_ak_nova_64(LinPan2 *unit, int inNumSamples)
252 float pos = ZIN0(1);
253 float level = ZIN0(2);
254 float leftamp = unit->m_leftamp;
255 float rightamp = unit->m_rightamp;
257 if (pos != unit->m_pos || unit->m_level != level) {
258 float pan = pos * 0.5f + 0.5f;
259 float nextrightamp = level * pan;
260 float nextleftamp = level - nextrightamp;
262 float slopeFactor = unit->mRate->mSlopeFactor;
263 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
264 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
266 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
267 rightamp, rightampslope);
268 unit->m_pos = pos;
269 unit->m_level = level;
270 unit->m_leftamp = nextleftamp;
271 unit->m_rightamp = nextrightamp;
272 } else
273 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, rightamp);
275 #endif
277 void LinPan2_next_aa(LinPan2 *unit, int inNumSamples)
279 float *leftout = ZOUT(0);
280 float *rightout = ZOUT(1);
281 float *in = ZIN(0);
282 float *pos = ZIN(1);
283 float nextlevel = ZIN0(2);
284 float level = unit->m_level;
285 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
287 LOOP1(inNumSamples,
288 float pan = ZXP(pos) * 0.5f + 0.5f;
289 float rightamp = level * pan;
290 float leftamp = level - rightamp;
291 float zin = ZXP(in);
292 ZXP(leftout) = zin * leftamp;
293 ZXP(rightout) = zin * rightamp;
294 level += levelSlope;
296 unit->m_level = level;
300 ////////////////////////////////////////////////////////////////////////////////////////////////////////
302 void Balance2_Ctor(Balance2 *unit)
304 if (INRATE(2) == calc_FullRate) {
305 SETCALC(Balance2_next_aa);
306 } else {
307 #ifdef NOVA_SIMD
308 if (BUFLENGTH == 64)
309 SETCALC(Balance2_next_ak_nova_64);
310 else if (!(BUFLENGTH & 15))
311 SETCALC(Balance2_next_ak_nova);
312 else
313 SETCALC(Balance2_next_ak);
314 #else
315 SETCALC(Balance2_next_ak);
316 #endif
318 unit->m_pos = ZIN0(2);
319 unit->m_level = ZIN0(3);
320 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f + 0.5f);
321 ipos = sc_clip(ipos, 0, 2048);
323 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
324 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
325 Balance2_next_aa(unit, 1);
328 void Balance2_next_ak(Balance2 *unit, int inNumSamples)
330 float *leftout = ZOUT(0);
331 float *rightout = ZOUT(1);
332 float *leftin = ZIN(0);
333 float *rightin = ZIN(1);
334 float pos = ZIN0(2);
335 float level = ZIN0(3);
336 float leftamp = unit->m_leftamp;
337 float rightamp = unit->m_rightamp;
339 if (pos != unit->m_pos || unit->m_level != level) {
340 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
341 ipos = sc_clip(ipos, 0, 2048);
343 float nextleftamp = level * ft->mSine[2048 - ipos];
344 float nextrightamp = level * ft->mSine[ipos];
346 float slopeFactor = unit->mRate->mSlopeFactor;
347 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
348 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
350 LOOP1(inNumSamples,
351 ZXP(leftout) = ZXP(leftin) * leftamp;
352 ZXP(rightout) = ZXP(rightin) * rightamp;
353 leftamp += leftampslope;
354 rightamp += rightampslope;
356 unit->m_pos = pos;
357 unit->m_level = level;
358 unit->m_leftamp = nextleftamp;
359 unit->m_rightamp = nextrightamp;
360 } else {
361 LOOP1(inNumSamples,
362 ZXP(leftout) = ZXP(leftin) * leftamp;
363 ZXP(rightout) = ZXP(rightin) * rightamp;
368 #ifdef NOVA_SIMD
369 void Balance2_next_ak_nova(Balance2 *unit, int inNumSamples)
371 float pos = ZIN0(2);
372 float level = ZIN0(3);
373 float leftamp = unit->m_leftamp;
374 float rightamp = unit->m_rightamp;
376 if (pos != unit->m_pos || unit->m_level != level) {
377 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
378 ipos = sc_clip(ipos, 0, 2048);
380 float nextleftamp = level * ft->mSine[2048 - ipos];
381 float nextrightamp = level * ft->mSine[ipos];
383 float slopeFactor = unit->mRate->mSlopeFactor;
384 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
385 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
387 unit->m_pos = pos;
388 unit->m_level = level;
389 unit->m_leftamp = nextleftamp;
390 unit->m_rightamp = nextrightamp;
392 //nova::times_vec2_ramp_simd(OUT(0), IN(0), leftamp, leftampslope, OUT(1), IN(1), rightamp, rightampslope, inNumSamples);
393 nova::times_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope), inNumSamples);
394 nova::times_vec_simd(OUT(1), IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
395 } else {
396 //nova::times_vec2_simd(OUT(0), IN(0), leftamp, OUT(1), IN(1), rightamp, inNumSamples);
397 nova::times_vec_simd(OUT(0), IN(0), leftamp, inNumSamples);
398 nova::times_vec_simd(OUT(1), IN(1), rightamp, inNumSamples);
402 void Balance2_next_ak_nova_64(Balance2 *unit, int inNumSamples)
404 float pos = ZIN0(2);
405 float level = ZIN0(3);
406 float leftamp = unit->m_leftamp;
407 float rightamp = unit->m_rightamp;
409 if (pos != unit->m_pos || unit->m_level != level) {
410 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
411 ipos = sc_clip(ipos, 0, 2048);
413 float nextleftamp = level * ft->mSine[2048 - ipos];
414 float nextrightamp = level * ft->mSine[ipos];
416 float slopeFactor = unit->mRate->mSlopeFactor;
417 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
418 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
420 unit->m_pos = pos;
421 unit->m_level = level;
422 unit->m_leftamp = nextleftamp;
423 unit->m_rightamp = nextrightamp;
425 //nova::times_vec2_ramp_simd(OUT(0), IN(0), leftamp, leftampslope, OUT(1), IN(1), rightamp, rightampslope, inNumSamples);
426 nova::times_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope), inNumSamples);
427 nova::times_vec_simd(OUT(1), IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
428 } else {
429 //nova::times_vec2_simd(OUT(0), IN(0), leftamp, OUT(1), IN(1), rightamp, inNumSamples);
430 nova::times_vec_simd<64>(OUT(0), IN(0), leftamp);
431 nova::times_vec_simd<64>(OUT(1), IN(1), rightamp);
434 #endif
436 void Balance2_next_aa(Balance2 *unit, int inNumSamples)
438 float *leftout = ZOUT(0);
439 float *rightout = ZOUT(1);
440 float *leftin = ZIN(0);
441 float *rightin = ZIN(1);
442 float *pos = ZIN(2);
443 float nextlevel = ZIN0(3);
444 float level = unit->m_level;
446 float *sineTable = ft->mSine;
447 if (level != nextlevel) {
448 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
449 LOOP1(inNumSamples,
450 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
451 ipos = sc_clip(ipos, 0, 2048);
453 float leftamp = level * sineTable[2048 - ipos];
454 float rightamp = level * sineTable[ipos];
455 ZXP(leftout) = ZXP(leftin) * leftamp;
456 ZXP(rightout) = ZXP(rightin) * rightamp;
457 level += levelSlope;
459 unit->m_level = level;
460 } else {
461 LOOP1(inNumSamples,
462 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
463 ipos = sc_clip(ipos, 0, 2048);
465 float leftamp = level * sineTable[2048 - ipos];
466 float rightamp = level * sineTable[ipos];
467 ZXP(leftout) = ZXP(leftin) * leftamp;
468 ZXP(rightout) = ZXP(rightin) * rightamp;
473 ////////////////////////////////////////////////////////////////////////////////////////////////////////
475 #ifdef NOVA_SIMD
476 FLATTEN void XFade2_next_ak_nova(XFade2 *unit, int inNumSamples);
477 FLATTEN void XFade2_next_ak_nova_64(XFade2 *unit, int inNumSamples);
478 #endif
480 void XFade2_Ctor(XFade2 *unit)
482 if (INRATE(2) == calc_FullRate) {
483 SETCALC(XFade2_next_aa);
484 } else {
485 #ifdef NOVA_SIMD
486 if (BUFLENGTH == 64)
487 SETCALC(XFade2_next_ak_nova_64);
488 if (!(BUFLENGTH & 15))
489 SETCALC(XFade2_next_ak_nova);
490 else
491 #endif
492 SETCALC(XFade2_next_ak);
494 unit->m_pos = ZIN0(2);
495 unit->m_level = ZIN0(3);
496 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f + 0.5f);
497 ipos = sc_clip(ipos, 0, 2048);
499 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
500 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
501 XFade2_next_aa(unit, 1);
504 void XFade2_next_ak(XFade2 *unit, int inNumSamples)
506 float *out = ZOUT(0);
507 float *leftin = ZIN(0);
508 float *rightin = ZIN(1);
509 float pos = ZIN0(2);
510 float level = ZIN0(3);
511 float leftamp = unit->m_leftamp;
512 float rightamp = unit->m_rightamp;
514 if (pos != unit->m_pos || unit->m_level != level) {
515 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
516 ipos = sc_clip(ipos, 0, 2048);
518 float nextleftamp = level * ft->mSine[2048 - ipos];
519 float nextrightamp = level * ft->mSine[ipos];
521 float slopeFactor = unit->mRate->mSlopeFactor;
522 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
523 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
525 LOOP1(inNumSamples,
526 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
527 leftamp += leftampslope;
528 rightamp += rightampslope;
530 unit->m_pos = pos;
531 unit->m_level = level;
532 unit->m_leftamp = nextleftamp;
533 unit->m_rightamp = nextrightamp;
534 } else {
535 LOOP1(inNumSamples,
536 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
541 #ifdef NOVA_SIMD
542 void XFade2_next_ak_nova(XFade2 *unit, int inNumSamples)
544 float pos = ZIN0(2);
545 float level = ZIN0(3);
546 float leftamp = unit->m_leftamp;
547 float rightamp = unit->m_rightamp;
549 if (pos != unit->m_pos || unit->m_level != level) {
550 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
551 ipos = sc_clip(ipos, 0, 2048);
553 float nextleftamp = level * ft->mSine[2048 - ipos];
554 float nextrightamp = level * ft->mSine[ipos];
556 float slopeFactor = unit->mRate->mSlopeFactor;
557 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
558 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
560 nova::mix_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope),
561 IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
563 unit->m_pos = pos;
564 unit->m_level = level;
565 unit->m_leftamp = nextleftamp;
566 unit->m_rightamp = nextrightamp;
567 } else
568 nova::mix_vec_simd(OUT(0), IN(0), leftamp, IN(1), rightamp, inNumSamples);
571 void XFade2_next_ak_nova_64(XFade2 *unit, int inNumSamples)
573 float pos = ZIN0(2);
574 float level = ZIN0(3);
575 float leftamp = unit->m_leftamp;
576 float rightamp = unit->m_rightamp;
578 if (pos != unit->m_pos || unit->m_level != level) {
579 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
580 ipos = sc_clip(ipos, 0, 2048);
582 float nextleftamp = level * ft->mSine[2048 - ipos];
583 float nextrightamp = level * ft->mSine[ipos];
585 float slopeFactor = unit->mRate->mSlopeFactor;
586 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
587 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
589 nova::mix_vec_simd<64>(OUT(0), IN(0), slope_argument(leftamp, leftampslope),
590 IN(1), slope_argument(rightamp, rightampslope));
592 unit->m_pos = pos;
593 unit->m_level = level;
594 unit->m_leftamp = nextleftamp;
595 unit->m_rightamp = nextrightamp;
596 } else
597 nova::mix_vec_simd<64>(OUT(0), IN(0), leftamp, IN(1), rightamp);
600 #endif
602 void XFade2_next_aa(XFade2 *unit, int inNumSamples)
604 float *out = ZOUT(0);
605 float *leftin = ZIN(0);
606 float *rightin = ZIN(1);
607 float *pos = ZIN(2);
608 float nextlevel = ZIN0(3);
609 float level = unit->m_level;
611 float *sineTable = ft->mSine;
612 if (level != nextlevel) {
613 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
614 LOOP1(inNumSamples,
615 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
616 ipos = sc_clip(ipos, 0, 2048);
618 float leftamp = level * sineTable[2048 - ipos];
619 float rightamp = level * sineTable[ipos];
620 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
621 level += levelSlope;
623 unit->m_level = level;
624 } else {
625 LOOP1(inNumSamples,
626 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
627 ipos = sc_clip(ipos, 0, 2048);
629 float leftamp = level * sineTable[2048 - ipos];
630 float rightamp = level * sineTable[ipos];
631 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
636 ////////////////////////////////////////////////////////////////////////////////////////////////////////
638 ////////////////////////////////////////////////////////////////////////////////////////////////////////
640 void LinXFade2_Ctor(LinXFade2 *unit)
642 if (INRATE(2) == calc_FullRate) {
643 SETCALC(LinXFade2_next_a);
644 } else {
645 SETCALC(LinXFade2_next_k);
647 unit->m_pos = ZIN0(2);
648 unit->m_pos = sc_clip(unit->m_pos, -1.f, 1.f);
649 unit->m_amp = unit->m_pos * 0.5f + 0.5f;
651 LinXFade2_next_a(unit, 1);
654 void LinXFade2_next_k(LinXFade2 *unit, int inNumSamples)
656 float *out = ZOUT(0);
657 float *leftin = ZIN(0);
658 float *rightin = ZIN(1);
659 float pos = ZIN0(2);
660 float amp = unit->m_amp;
662 if (pos != unit->m_pos) {
663 pos = sc_clip(pos, -1.f, 1.f);
665 float nextamp = pos * 0.5f + 0.5f;
666 float amp_slope = (nextamp - amp) * unit->mRate->mSlopeFactor;
668 LOOP1(inNumSamples,
669 float l = ZXP(leftin);
670 float r = ZXP(rightin);
671 ZXP(out) = l + amp * (r - l);
672 amp += amp_slope;
674 unit->m_pos = pos;
675 unit->m_amp = amp;
676 } else {
677 LOOP1(inNumSamples,
678 float l = ZXP(leftin);
679 float r = ZXP(rightin);
680 ZXP(out) = l + amp * (r - l);
685 void LinXFade2_next_a(LinXFade2 *unit, int inNumSamples)
687 float *out = ZOUT(0);
688 float *leftin = ZIN(0);
689 float *rightin = ZIN(1);
690 float *posp = ZIN(2);
692 LOOP1(inNumSamples,
693 float pos = ZXP(posp);
694 pos = sc_clip(pos, -1.f, 1.f);
695 float amp = pos * 0.5f + 0.5f;
696 float l = ZXP(leftin);
697 float r = ZXP(rightin);
698 ZXP(out) = l + amp * (r - l);
702 ////////////////////////////////////////////////////////////////////////////////////////////////////////
704 void Pan2_next_ak(Pan2 *unit, int inNumSamples)
706 float *leftout = ZOUT(0);
707 float *rightout = ZOUT(1);
708 float *in = ZIN(0);
709 float pos = ZIN0(1);
710 float level = ZIN0(2);
711 float leftamp = unit->m_leftamp;
712 float rightamp = unit->m_rightamp;
714 if (pos != unit->m_pos || unit->m_level != level) {
715 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
716 ipos = sc_clip(ipos, 0, 2048);
718 float nextleftamp = level * ft->mSine[2048 - ipos];
719 float nextrightamp = level * ft->mSine[ipos];
721 float slopeFactor = unit->mRate->mSlopeFactor;
722 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
723 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
725 LOOP1(inNumSamples,
726 float zin = ZXP(in);
727 ZXP(leftout) = zin * leftamp;
728 ZXP(rightout) = zin * rightamp;
729 leftamp += leftampslope;
730 rightamp += rightampslope;
732 unit->m_pos = pos;
733 unit->m_level = level;
734 unit->m_leftamp = nextleftamp;
735 unit->m_rightamp = nextrightamp;
736 } else {
737 LOOP1(inNumSamples,
738 float zin = ZXP(in);
739 ZXP(leftout) = zin * leftamp;
740 ZXP(rightout) = zin * rightamp;
745 #ifdef NOVA_SIMD
746 void Pan2_next_ak_nova(Pan2 *unit, int inNumSamples)
748 float pos = ZIN0(1);
749 float level = ZIN0(2);
750 float leftamp = unit->m_leftamp;
751 float rightamp = unit->m_rightamp;
753 if (pos != unit->m_pos || unit->m_level != level) {
754 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
755 ipos = sc_clip(ipos, 0, 2048);
757 float nextleftamp = level * ft->mSine[2048 - ipos];
758 float nextrightamp = level * ft->mSine[ipos];
760 float slopeFactor = unit->mRate->mSlopeFactor;
761 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
762 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
764 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
765 rightamp, rightampslope, inNumSamples);
767 unit->m_pos = pos;
768 unit->m_level = level;
769 unit->m_leftamp = nextleftamp;
770 unit->m_rightamp = nextrightamp;
771 } else
772 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, rightamp, inNumSamples);
775 void Pan2_next_ak_nova_64(Pan2 *unit, int inNumSamples)
777 float pos = ZIN0(1);
778 float level = ZIN0(2);
779 float leftamp = unit->m_leftamp;
780 float rightamp = unit->m_rightamp;
782 if (pos != unit->m_pos || unit->m_level != level) {
783 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
784 ipos = sc_clip(ipos, 0, 2048);
786 float nextleftamp = level * ft->mSine[2048 - ipos];
787 float nextrightamp = level * ft->mSine[ipos];
789 float slopeFactor = unit->mRate->mSlopeFactor;
790 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
791 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
793 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
794 rightamp, rightampslope);
796 unit->m_pos = pos;
797 unit->m_level = level;
798 unit->m_leftamp = nextleftamp;
799 unit->m_rightamp = nextrightamp;
800 } else
801 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, rightamp);
804 #endif
807 void Pan2_next_aa(Pan2 *unit, int inNumSamples)
809 float *leftout = ZOUT(0);
810 float *rightout = ZOUT(1);
811 float *in = ZIN(0);
812 float *pos = ZIN(1);
813 float nextlevel = ZIN0(2);
814 float level = unit->m_level;
816 if (level != nextlevel) {
817 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
819 LOOP1(inNumSamples,
820 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
821 ipos = sc_clip(ipos, 0, 2048);
823 float leftamp = level * ft->mSine[2048 - ipos];
824 float rightamp = level * ft->mSine[ipos];
825 float zin = ZXP(in);
826 ZXP(leftout) = zin * leftamp;
827 ZXP(rightout) = zin * rightamp;
828 level += levelSlope;
830 unit->m_level = level;
831 } else {
832 LOOP1(inNumSamples,
833 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
834 ipos = sc_clip(ipos, 0, 2048);
836 float leftamp = level * ft->mSine[2048 - ipos];
837 float rightamp = level * ft->mSine[ipos];
838 float zin = ZXP(in);
839 ZXP(leftout) = zin * leftamp;
840 ZXP(rightout) = zin * rightamp;
845 void Pan2_Ctor(Pan2 *unit)
847 if (INRATE(1) == calc_FullRate) {
848 SETCALC(Pan2_next_aa);
849 } else {
850 #if defined(NOVA_SIMD)
851 if (BUFLENGTH == 64)
852 SETCALC(Pan2_next_ak_nova_64);
853 if (!(BUFLENGTH & 15))
854 SETCALC(Pan2_next_ak_nova);
855 else
856 SETCALC(Pan2_next_ak);
857 #else
858 SETCALC(Pan2_next_ak);
859 #endif
862 unit->m_pos = ZIN0(1);
863 unit->m_level = ZIN0(2);
864 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f + 0.5f);
865 ipos = sc_clip(ipos, 0, 2048);
867 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
868 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
869 Pan2_next_aa(unit, 1);
872 ////////////////////////////////////////////////////////////////////////////////////////////////////////
874 void Pan4_Ctor(Pan4 *unit)
876 SETCALC(Pan4_next);
877 //float *in = ZIN(0);
878 float xpos = ZIN0(1);
879 float ypos = ZIN0(2);
880 float level = ZIN0(3);
882 unit->m_xpos = xpos;
883 unit->m_ypos = ypos;
884 unit->m_level = level;
885 if (xpos < -1.f || xpos > 1.f || ypos < -1.f || ypos > 1.f) {
886 float xabs = fabs(xpos);
888 if (ypos > xabs) {
889 xpos = (xpos + ypos) / ypos - 1.f;
890 ypos = 1.f;
891 } else if (ypos < -xabs) {
892 xpos = (xpos - ypos) / -ypos - 1.f;
893 ypos = -1.f;
894 } else {
895 float yabs = fabs(ypos);
896 if (yabs < xpos) {
897 ypos = (ypos + xpos) / xpos - 1.f;
898 xpos = 1.f;
899 } else {
900 ypos = (ypos - xpos) / -xpos - 1.f;
901 xpos = -1.f;
906 int32 ixpos = (int32)(1024.f * xpos + 1024.f + 0.5f);
907 ixpos = sc_clip(ixpos, 0, 2048);
908 float leftamp = ft->mSine[2048 - ixpos];
909 float rightamp = ft->mSine[ixpos];
911 int32 iypos = (int32)(1024.f * ypos + 1024.f + 0.5f);
912 iypos = sc_clip(iypos, 0, 2048);
913 float frontamp = ft->mSine[iypos];
914 float backamp = ft->mSine[2048 - iypos];
916 frontamp *= level;
917 backamp *= level;
919 unit->m_LF_amp = leftamp * frontamp;
920 unit->m_RF_amp = rightamp * frontamp;
921 unit->m_LB_amp = leftamp * backamp;
922 unit->m_RB_amp = rightamp * backamp;
924 float z = ZIN0(0);
925 ZOUT0(0) = z * unit->m_LF_amp;
926 ZOUT0(1) = z * unit->m_RF_amp;
927 ZOUT0(2) = z * unit->m_LB_amp;
928 ZOUT0(3) = z * unit->m_RB_amp;
931 void Pan4_next(Pan4 *unit, int inNumSamples)
933 float *LFout = ZOUT(0);
934 float *RFout = ZOUT(1);
935 float *LBout = ZOUT(2);
936 float *RBout = ZOUT(3);
938 float *in = ZIN(0);
939 float xpos = ZIN0(1);
940 float ypos = ZIN0(2);
941 float level = ZIN0(3);
943 float LF_amp = unit->m_LF_amp;
944 float RF_amp = unit->m_RF_amp;
945 float LB_amp = unit->m_LB_amp;
946 float RB_amp = unit->m_RB_amp;
948 if (xpos != unit->m_xpos || ypos != unit->m_ypos || level != unit->m_level) {
949 unit->m_xpos = xpos;
950 unit->m_ypos = ypos;
951 unit->m_level = level;
952 if (xpos < -1.f || xpos > 1.f || ypos < -1.f || ypos > 1.f) {
953 float xabs = fabs(xpos);
955 if (ypos > xabs) {
956 xpos = (xpos + ypos) / ypos - 1.f;
957 ypos = 1.f;
958 } else if (ypos < -xabs) {
959 xpos = (xpos - ypos) / -ypos - 1.f;
960 ypos = -1.f;
961 } else {
962 float yabs = fabs(ypos);
963 if (yabs < xpos) {
964 ypos = (ypos + xpos) / xpos - 1.f;
965 xpos = 1.f;
966 } else {
967 ypos = (ypos - xpos) / -xpos - 1.f;
968 xpos = -1.f;
973 int32 ixpos = (int32)(1024.f * xpos + 1024.f + 0.5f);
974 ixpos = sc_clip(ixpos, 0, 2048);
975 float leftamp = ft->mSine[2048 - ixpos];
976 float rightamp = ft->mSine[ixpos];
978 int32 iypos = (int32)(1024.f * ypos + 1024.f + 0.5f);
979 iypos = sc_clip(iypos, 0, 2048);
980 float frontamp = ft->mSine[iypos];
981 float backamp = ft->mSine[2048 - iypos];
983 frontamp *= level;
984 backamp *= level;
986 float next_LF_amp = leftamp * frontamp;
987 float next_RF_amp = rightamp * frontamp;
988 float next_LB_amp = leftamp * backamp;
989 float next_RB_amp = rightamp * backamp;
991 float LF_slope = CALCSLOPE(next_LF_amp, LF_amp);
992 float RF_slope = CALCSLOPE(next_RF_amp, RF_amp);
993 float LB_slope = CALCSLOPE(next_LB_amp, LB_amp);
994 float RB_slope = CALCSLOPE(next_RB_amp, RB_amp);
996 LOOP1(inNumSamples,
997 float z = ZXP(in);
998 ZXP(LFout) = z * LF_amp;
999 ZXP(RFout) = z * RF_amp;
1000 ZXP(LBout) = z * LB_amp;
1001 ZXP(RBout) = z * RB_amp;
1002 LF_amp += LF_slope;
1003 RF_amp += RF_slope;
1004 LB_amp += LB_slope;
1005 RB_amp += RB_slope;
1007 unit->m_LF_amp = LF_amp;
1008 unit->m_RF_amp = RF_amp;
1009 unit->m_LB_amp = LB_amp;
1010 unit->m_RB_amp = RB_amp;
1011 } else {
1012 LOOP1(inNumSamples,
1013 float z = ZXP(in);
1014 ZXP(LFout) = z * LF_amp;
1015 ZXP(RFout) = z * RF_amp;
1016 ZXP(LBout) = z * LB_amp;
1017 ZXP(RBout) = z * RB_amp;
1022 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1024 void PanB_Ctor(PanB *unit)
1026 SETCALC(PanB_next);
1027 float azimuth = unit->m_azimuth = ZIN0(1);
1028 float elevation = unit->m_elevation = ZIN0(2);
1029 float level = unit->m_level = ZIN0(3);
1031 int kSineSize = ft->mSineSize;
1032 int kSineMask = kSineSize - 1;
1034 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1035 long ielevation = kSineMask & (long)(elevation * (float)(kSineSize >> 2));
1036 float sina = -ft->mSine[iazimuth];
1037 float sinb = ft->mSine[ielevation];
1039 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1040 ielevation = kSineMask & (ielevation + (kSineSize>>2));
1041 float cosa = ft->mSine[iazimuth];
1042 float cosb = ft->mSine[ielevation];
1044 unit->m_W_amp = rsqrt2_f * level;
1045 unit->m_X_amp = cosa * cosb * level;
1046 unit->m_Y_amp = sina * cosb * level;
1047 unit->m_Z_amp = sinb * level;
1049 PanB_next(unit, 1);
1052 void PanB_next(PanB *unit, int inNumSamples)
1054 float *Wout = ZOUT(0);
1055 float *Xout = ZOUT(1);
1056 float *Yout = ZOUT(2);
1057 float *Zout = ZOUT(3);
1059 float *in = ZIN(0);
1060 float azimuth = ZIN0(1);
1061 float elevation = ZIN0(2);
1062 float level = ZIN0(3);
1064 float W_amp = unit->m_W_amp;
1065 float X_amp = unit->m_X_amp;
1066 float Y_amp = unit->m_Y_amp;
1067 float Z_amp = unit->m_Z_amp;
1069 int kSineSize = ft->mSineSize;
1070 int kSineMask = kSineSize - 1;
1071 if (azimuth != unit->m_azimuth || elevation != unit->m_elevation || level != unit->m_level) {
1072 unit->m_azimuth = azimuth;
1073 unit->m_elevation = elevation;
1074 unit->m_level = level;
1076 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1077 long ielevation = kSineMask & (long)(elevation * (float)(kSineSize >> 2));
1078 float sina = -ft->mSine[iazimuth];
1079 float sinb = ft->mSine[ielevation];
1081 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1082 ielevation = kSineMask & (ielevation + (kSineSize>>2));
1083 float cosa = ft->mSine[iazimuth];
1084 float cosb = ft->mSine[ielevation];
1086 float next_W_amp = rsqrt2_f * level;
1087 float next_X_amp = cosa * cosb * level;
1088 float next_Y_amp = sina * cosb * level;
1089 float next_Z_amp = sinb * level;
1091 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1092 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1093 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1094 float Z_slope = CALCSLOPE(next_Z_amp, Z_amp);
1096 LOOP1(inNumSamples,
1097 float z = ZXP(in);
1098 ZXP(Wout) = z * W_amp;
1099 ZXP(Xout) = z * X_amp;
1100 ZXP(Yout) = z * Y_amp;
1101 ZXP(Zout) = z * Z_amp;
1102 W_amp += W_slope;
1103 X_amp += X_slope;
1104 Y_amp += Y_slope;
1105 Z_amp += Z_slope;
1107 unit->m_W_amp = W_amp;
1108 unit->m_X_amp = X_amp;
1109 unit->m_Y_amp = Y_amp;
1110 unit->m_Z_amp = Z_amp;
1111 } else {
1112 LOOP1(inNumSamples,
1113 float z = ZXP(in);
1114 ZXP(Wout) = z * W_amp;
1115 ZXP(Xout) = z * X_amp;
1116 ZXP(Yout) = z * Y_amp;
1117 ZXP(Zout) = z * Z_amp;
1122 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1124 void PanB2_next(PanB2 *unit, int inNumSamples)
1126 float *Wout = ZOUT(0);
1127 float *Xout = ZOUT(1);
1128 float *Yout = ZOUT(2);
1130 float *in = ZIN(0);
1131 float azimuth = ZIN0(1);
1132 float level = ZIN0(2);
1134 float W_amp = unit->m_W_amp;
1135 float X_amp = unit->m_X_amp;
1136 float Y_amp = unit->m_Y_amp;
1138 int kSineSize = ft->mSineSize;
1139 int kSineMask = kSineSize - 1;
1140 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1141 unit->m_azimuth = azimuth;
1142 unit->m_level = level;
1144 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1145 float sina = -ft->mSine[isinpos];
1147 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1148 float cosa = ft->mSine[icospos];
1150 float next_W_amp = rsqrt2_f * level;
1151 float next_X_amp = cosa * level;
1152 float next_Y_amp = sina * level;
1154 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1155 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1156 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1158 LOOP1(inNumSamples,
1159 float z = ZXP(in);
1160 ZXP(Wout) = z * W_amp;
1161 ZXP(Xout) = z * X_amp;
1162 ZXP(Yout) = z * Y_amp;
1163 W_amp += W_slope;
1164 X_amp += X_slope;
1165 Y_amp += Y_slope;
1167 unit->m_W_amp = W_amp;
1168 unit->m_X_amp = X_amp;
1169 unit->m_Y_amp = Y_amp;
1170 } else {
1171 LOOP1(inNumSamples,
1172 float z = ZXP(in);
1173 ZXP(Wout) = z * W_amp;
1174 ZXP(Xout) = z * X_amp;
1175 ZXP(Yout) = z * Y_amp;
1180 #ifdef NOVA_SIMD
1182 void PanB2_next_nova(PanB2 *unit, int inNumSamples)
1184 float *Wout = OUT(0);
1185 float *Xout = OUT(1);
1186 float *Yout = OUT(2);
1188 float *in = IN(0);
1189 float azimuth = ZIN0(1);
1190 float level = ZIN0(2);
1192 float W_amp = unit->m_W_amp;
1193 float X_amp = unit->m_X_amp;
1194 float Y_amp = unit->m_Y_amp;
1196 int kSineSize = ft->mSineSize;
1197 int kSineMask = kSineSize - 1;
1198 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1199 unit->m_azimuth = azimuth;
1200 unit->m_level = level;
1202 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1203 float sina = -ft->mSine[isinpos];
1205 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1206 float cosa = ft->mSine[icospos];
1208 float next_W_amp = rsqrt2_f * level;
1209 float next_X_amp = cosa * level;
1210 float next_Y_amp = sina * level;
1212 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1213 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1214 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1216 nova::times_vec_simd(Wout, in, slope_argument(W_amp, W_slope), inNumSamples);
1217 nova::times_vec_simd(Xout, in, slope_argument(X_amp, X_slope), inNumSamples);
1218 nova::times_vec_simd(Yout, in, slope_argument(Y_amp, Y_slope), inNumSamples);
1220 unit->m_W_amp = next_W_amp;
1221 unit->m_X_amp = next_X_amp;
1222 unit->m_Y_amp = next_Y_amp;
1223 } else {
1224 // TODO: can be further optimized by joining the loops
1225 nova::times_vec_simd(Wout, in, W_amp, inNumSamples);
1226 nova::times_vec_simd(Xout, in, X_amp, inNumSamples);
1227 nova::times_vec_simd(Yout, in, Y_amp, inNumSamples);
1230 #endif
1232 void PanB2_Ctor(PanB2 *unit)
1234 #if defined(NOVA_SIMD)
1235 if (!(BUFLENGTH & 15))
1236 SETCALC(PanB2_next_nova);
1237 else
1238 #endif
1239 SETCALC(PanB2_next);
1241 float azimuth = unit->m_azimuth = ZIN0(1);
1242 float level = unit->m_level = ZIN0(2);
1244 int kSineSize = ft->mSineSize;
1245 int kSineMask = kSineSize - 1;
1247 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1248 float sina = -ft->mSine[isinpos];
1250 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1251 float cosa = ft->mSine[icospos];
1253 unit->m_W_amp = rsqrt2_f * level;
1254 unit->m_X_amp = cosa * level;
1255 unit->m_Y_amp = sina * level;
1257 PanB2_next(unit, 1);
1260 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1262 void BiPanB2_next(BiPanB2 *unit, int inNumSamples)
1264 float *Wout = ZOUT(0);
1265 float *Xout = ZOUT(1);
1266 float *Yout = ZOUT(2);
1268 float *inA = ZIN(0);
1269 float *inB = ZIN(1);
1270 float azimuth = ZIN0(2);
1271 float level = ZIN0(3);
1273 float W_amp = unit->m_W_amp;
1274 float X_amp = unit->m_X_amp;
1275 float Y_amp = unit->m_Y_amp;
1277 int kSineSize = ft->mSineSize;
1278 int kSineMask = kSineSize - 1;
1279 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1280 unit->m_azimuth = azimuth;
1281 unit->m_level = level;
1283 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1284 float sina = -ft->mSine[isinpos];
1286 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1287 float cosa = ft->mSine[icospos];
1289 float next_W_amp = rsqrt2_f * level;
1290 float next_X_amp = cosa * level;
1291 float next_Y_amp = sina * level;
1293 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1294 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1295 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1297 if (W_slope == 0.f) {
1298 LOOP1(inNumSamples,
1299 float a = ZXP(inA);
1300 float b = ZXP(inB);
1301 float abdiff = a - b;
1302 ZXP(Wout) = (a + b) * W_amp;
1303 ZXP(Xout) = abdiff * X_amp;
1304 ZXP(Yout) = abdiff * Y_amp;
1305 X_amp += X_slope;
1306 Y_amp += Y_slope;
1308 } else {
1309 LOOP1(inNumSamples,
1310 float a = ZXP(inA);
1311 float b = ZXP(inB);
1312 float abdiff = a - b;
1313 ZXP(Wout) = (a + b) * W_amp;
1314 ZXP(Xout) = abdiff * X_amp;
1315 ZXP(Yout) = abdiff * Y_amp;
1316 W_amp += W_slope;
1317 X_amp += X_slope;
1318 Y_amp += Y_slope;
1320 unit->m_W_amp = W_amp;
1322 unit->m_X_amp = X_amp;
1323 unit->m_Y_amp = Y_amp;
1324 } else {
1325 LOOP1(inNumSamples,
1326 float a = ZXP(inA);
1327 float b = ZXP(inB);
1328 float abdiff = a - b;
1329 ZXP(Wout) = (a + b) * W_amp;
1330 ZXP(Xout) = abdiff * X_amp;
1331 ZXP(Yout) = abdiff * Y_amp;
1336 void BiPanB2_Ctor(BiPanB2 *unit)
1338 SETCALC(BiPanB2_next);
1340 float azimuth = unit->m_azimuth = ZIN0(2);
1341 float level = unit->m_level = ZIN0(3);
1343 int kSineSize = ft->mSineSize;
1344 int kSineMask = kSineSize - 1;
1346 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1347 float sina = -ft->mSine[iazimuth];
1349 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1350 float cosa = ft->mSine[iazimuth];
1352 unit->m_W_amp = rsqrt2_f * level;
1353 unit->m_X_amp = cosa * level;
1354 unit->m_Y_amp = sina * level;
1356 BiPanB2_next(unit, 1);
1359 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1360 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1364 void calcPos(float pos, int numOutputs, float width, float orientation)
1366 float rwidth = 1.f / width;
1367 float range = numOutputs * rwidth;
1368 float rrange = 1.f / range;
1370 float zpos = pos * 0.5 * numOutputs + width * 0.5 + orientation;
1371 Print("pos %6.2g rwidth %6.3g range %6.3g rrange %6.3g zpos %6.3g\n",
1372 pos, rwidth, range, rrange, zpos);
1373 for (int i=0; i<numOutputs; ++i) {
1374 float amp;
1375 float chanpos = zpos - i;
1376 chanpos *= rwidth;
1377 float zchanpos = chanpos - range * floor(rrange * chanpos);
1378 if (zchanpos > 1.f) {
1379 amp = 0.f;
1380 } else {
1381 amp = ft->mSine[(long)(4096.f * zchanpos)];
1383 Print(" %d chanpos %6.3g zchanpos %6.3g amp %g\n",
1384 i, chanpos, zchanpos, amp);
1389 #ifdef NOVA_SIMD
1390 void PanAz_next_ak_nova(PanAz *unit, int inNumSamples);
1391 #endif
1393 void PanAz_Ctor(PanAz *unit)
1395 if (INRATE(1) == calc_FullRate) {
1396 unit->m_chanamp = NULL;
1397 SETCALC(PanAz_next_aa);
1398 } else {
1399 int numOutputs = unit->mNumOutputs;
1400 unit->m_chanamp = (float*)RTAlloc(unit->mWorld, numOutputs*sizeof(float));
1401 for (int i=0; i<numOutputs; ++i) {
1402 unit->m_chanamp[i] = 0;
1403 ZOUT0(i) = 0.f;
1405 #ifdef NOVA_SIMD
1406 if (!(BUFLENGTH & 15))
1407 SETCALC(PanAz_next_ak_nova);
1408 else
1409 SETCALC(PanAz_next_ak);
1410 #else
1411 SETCALC(PanAz_next_ak);
1412 #endif
1416 void PanAz_Dtor(PanAz *unit)
1418 if (unit->m_chanamp)
1419 RTFree(unit->mWorld, unit->m_chanamp);
1422 void PanAz_next_ak(PanAz *unit, int inNumSamples)
1424 float pos = ZIN0(1);
1425 float level = ZIN0(2);
1426 float width = ZIN0(3);
1427 float orientation = ZIN0(4);
1429 int numOutputs = unit->mNumOutputs;
1430 float rwidth = sc_reciprocal( width );
1431 float range = numOutputs * rwidth;
1432 float rrange = sc_reciprocal( range );
1434 pos = pos * 0.5f * numOutputs + width * 0.5f + orientation;
1436 float *zin0 = ZIN(0);
1438 for (int i=0; i<numOutputs; ++i) {
1439 float *out = ZOUT(i);
1440 float nextchanamp;
1441 float chanpos = pos - i;
1442 chanpos *= rwidth;
1443 chanpos = chanpos - range * sc_floor(rrange * chanpos);
1444 if (chanpos > 1.f) {
1445 nextchanamp = 0.f;
1446 } else {
1447 nextchanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1449 float chanamp = unit->m_chanamp[i];
1451 if (nextchanamp == chanamp) {
1452 if (nextchanamp == 0.f) {
1453 ZClear(inNumSamples, out);
1454 } else {
1455 float *in = zin0;
1456 LOOP1(inNumSamples,
1457 ZXP(out) = ZXP(in) * chanamp;
1460 } else {
1461 float chanampslope = CALCSLOPE(nextchanamp, chanamp);
1462 float *in = zin0;
1463 LOOP1(inNumSamples,
1464 ZXP(out) = ZXP(in) * chanamp;
1465 chanamp += chanampslope;
1467 unit->m_chanamp[i] = nextchanamp;
1472 #ifdef NOVA_SIMD
1473 FLATTEN void PanAz_next_ak_nova(PanAz *unit, int inNumSamples)
1475 float pos = ZIN0(1);
1476 float level = ZIN0(2);
1477 float width = ZIN0(3);
1478 float orientation = ZIN0(4);
1480 int numOutputs = unit->mNumOutputs;
1481 float rwidth = sc_reciprocal( width );
1482 float range = numOutputs * rwidth;
1483 float rrange = sc_reciprocal( range );
1485 pos = pos * 0.5f * numOutputs + width * 0.5f + orientation;
1487 float * in = IN(0);
1488 float * __restrict__ chanamps = unit->m_chanamp;
1490 for (int i=0; i<numOutputs; ++i) {
1491 float chanamp = chanamps[i];
1492 float nextchanamp;
1493 float chanpos = pos - i;
1494 chanpos *= rwidth;
1495 chanpos = chanpos - range * sc_floor(rrange * chanpos);
1496 if (chanpos > 1.f) {
1497 nextchanamp = 0.f;
1498 } else {
1499 nextchanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1502 float *out = OUT(i);
1503 if (nextchanamp == chanamp) {
1504 // if (nextchanamp == 0.f)
1505 // nova::zerovec_simd(out, inNumSamples);
1506 // else
1507 nova::times_vec_simd(out, in, chanamp, inNumSamples);
1508 } else {
1509 float chanampslope = CALCSLOPE(nextchanamp, chanamp);
1510 nova::times_vec_simd(out, in, slope_argument(chanamp, chanampslope), inNumSamples);
1511 chanamps[i] = nextchanamp;
1515 #endif
1517 void PanAz_next_aa(PanAz *unit, int inNumSamples)
1519 float level = ZIN0(2);
1520 float width = ZIN0(3);
1521 float orientation = ZIN0(4);
1523 int numOutputs = unit->mNumOutputs;
1524 float rwidth = sc_reciprocal( width );
1525 float range = numOutputs * rwidth;
1526 float rrange = sc_reciprocal( range );
1529 // compute constant parts with which the pos has to be multiplied/added to respect numOutputs, width and orientation
1530 // see PanAz_next_ak for details
1531 float alignedPosFac = 0.5f * numOutputs;
1532 float alignedPosConst = width * 0.5f + orientation;
1535 float *zin0 = ZIN(0);
1536 float *pos = ZIN(1);
1538 for (int i=0; i<numOutputs; ++i) {
1539 float *out = ZOUT(i);
1541 float *in = zin0;
1542 float *thePos = pos;
1544 LOOP1(inNumSamples,
1545 float chanpos = (ZXP(thePos) * alignedPosFac + alignedPosConst) - i * rwidth;
1546 chanpos = chanpos - range * std::floor(rrange * chanpos);
1548 float chanamp;
1549 if (chanpos > 1.f) {
1550 chanamp = 0.f;
1551 } else {
1552 chanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1555 ZXP(out) = ZXP(in) * chanamp;
1561 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1562 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1564 void Rotate2_next_ak(Rotate2 *unit, int inNumSamples)
1566 float *xout = ZOUT(0);
1567 float *yout = ZOUT(1);
1568 float *xin = ZIN(0);
1569 float *yin = ZIN(1);
1570 float pos = ZIN0(2);
1571 float sint = unit->m_sint;
1572 float cost = unit->m_cost;
1574 if (pos != unit->m_pos) {
1575 int kSineSize = ft->mSineSize;
1576 int kSineMask = kSineSize - 1;
1578 int32 isinpos = kSineMask & (int32)(pos * (float)(kSineSize >> 1));
1579 int32 icospos = kSineMask & ((kSineSize>>2) + isinpos);
1581 float nextsint = unit->m_sint = ft->mSine[isinpos];
1582 float nextcost = unit->m_cost = ft->mSine[icospos];
1584 float slopeFactor = unit->mRate->mSlopeFactor;
1585 float sinslope = (nextsint - sint) * slopeFactor;
1586 float cosslope = (nextcost - cost) * slopeFactor;
1588 LOOP1(inNumSamples,
1589 float x = ZXP(xin);
1590 float y = ZXP(yin);
1591 ZXP(xout) = cost * x + sint * y;
1592 ZXP(yout) = cost * y - sint * x;
1593 sint += sinslope;
1594 cost += cosslope;
1596 unit->m_pos = pos;
1597 } else {
1598 LOOP1(inNumSamples,
1599 float x = ZXP(xin);
1600 float y = ZXP(yin);
1601 ZXP(xout) = cost * x + sint * y;
1602 ZXP(yout) = cost * y - sint * x;
1607 void Rotate2_Ctor(Rotate2 *unit)
1609 SETCALC(Rotate2_next_ak);
1611 unit->m_pos = ZIN0(2);
1612 int32 isinpos = 8191 & (int32)(4096.f * unit->m_pos);
1613 int32 icospos = 8191 & (2048 + isinpos);
1615 unit->m_sint = ft->mSine[isinpos];
1616 unit->m_cost = ft->mSine[icospos];
1618 Rotate2_next_ak(unit, 1);
1621 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1623 void DecodeB2_Ctor(DecodeB2 *unit)
1625 #if defined(NOVA_SIMD)
1626 if (!(BUFLENGTH & 15))
1627 SETCALC(DecodeB2_next_nova);
1628 else
1629 #endif
1630 SETCALC(DecodeB2_next);
1632 DecodeB2_next(unit, 1);
1634 float orientation = ZIN0(3);
1636 int numOutputs = unit->mNumOutputs;
1637 float angle = twopi_f / numOutputs;
1638 unit->m_cosa = cos(angle);
1639 unit->m_sina = sin(angle);
1640 unit->m_W_amp = 0.7071067811865476f;
1641 unit->m_X_amp = 0.5f * (float)cos(orientation * angle);
1642 unit->m_Y_amp = 0.5f * (float)sin(orientation * angle);
1645 void DecodeB2_next(DecodeB2 *unit, int inNumSamples)
1647 float *Win0 = ZIN(0);
1648 float *Xin0 = ZIN(1);
1649 float *Yin0 = ZIN(2);
1651 float W_amp = unit->m_W_amp;
1652 float X_amp = unit->m_X_amp;
1653 float Y_amp = unit->m_Y_amp;
1654 float X_tmp;
1655 float cosa = unit->m_cosa;
1656 float sina = unit->m_sina;
1658 int numOutputs = unit->mNumOutputs;
1659 for (int i=0; i<numOutputs; ++i) {
1660 float *out = ZOUT(i);
1661 float *Win = Win0;
1662 float *Xin = Xin0;
1663 float *Yin = Yin0;
1664 LOOP1(inNumSamples,
1665 ZXP(out) = ZXP(Win) * W_amp + ZXP(Xin) * X_amp + ZXP(Yin) * Y_amp;
1667 X_tmp = X_amp * cosa + Y_amp * sina;
1668 Y_amp = Y_amp * cosa - X_amp * sina;
1669 X_amp = X_tmp;
1673 #ifdef NOVA_SIMD
1674 void DecodeB2_next_nova(DecodeB2 *unit, int inNumSamples)
1676 float *Win0 = IN(0);
1677 float *Xin0 = IN(1);
1678 float *Yin0 = IN(2);
1680 using namespace nova;
1681 vec<float> W_amp = unit->m_W_amp;
1682 vec<float> X_amp = unit->m_X_amp;
1683 vec<float> Y_amp = unit->m_Y_amp;
1684 vec<float> X_tmp;
1685 vec<float> cosa = unit->m_cosa;
1686 vec<float> sina = unit->m_sina;
1688 int numOutputs = unit->mNumOutputs;
1689 int vs = vec<float>::size;
1690 int loops = inNumSamples / vs;
1691 for (int i=0; i<numOutputs; ++i) {
1692 float *out = OUT(i);
1693 float *Win = Win0;
1694 float *Xin = Xin0;
1695 float *Yin = Yin0;
1697 for (int j = 0; j != loops; ++j) {
1698 vec<float> result, w, x, y;
1699 w.load_aligned(Win); x.load_aligned(Xin); y.load_aligned(Yin);
1700 result = w * W_amp + x * X_amp + y * Y_amp;
1701 result.store_aligned(out);
1702 out += vs; Win += vs; Xin += vs; Yin += vs;
1705 X_tmp = X_amp * cosa + Y_amp * sina;
1706 Y_amp = Y_amp * cosa - X_amp * sina;
1707 X_amp = X_tmp;
1710 #endif
1713 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1714 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1716 PluginLoad(Pan)
1718 ft = inTable;
1720 DefineSimpleUnit(Pan2);
1721 DefineSimpleUnit(Pan4);
1722 DefineSimpleUnit(LinPan2);
1723 DefineSimpleCantAliasUnit(Balance2);
1724 DefineSimpleUnit(Rotate2);
1725 DefineSimpleUnit(XFade2);
1726 DefineSimpleUnit(LinXFade2);
1727 DefineSimpleUnit(PanB);
1728 DefineSimpleCantAliasUnit(PanB2);
1729 DefineSimpleUnit(BiPanB2);
1730 DefineDtorCantAliasUnit(PanAz);
1731 DefineSimpleCantAliasUnit(DecodeB2);
1734 //////////////////////////////////////////////////////////////////////////////////////////////////