class library: SynthDef - replaceUGen fixes
[supercollider.git] / server / plugins / PanUGens.cpp
blob75bcad007d62143f7c21facac4384b7295cd5df2
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_binary_arithmetic.hpp"
26 #include "simd_pan.hpp"
27 #include "simd_mix.hpp"
28 using nova::slope_argument;
30 #if defined(__GNUC__) && !defined(__clang__)
31 #define inline_functions __attribute__ ((flatten))
32 #else
33 #define inline_functions
34 #endif
36 #endif
38 using namespace std; // for math functions
40 static InterfaceTable *ft;
42 struct LinPan2 : public Unit
44 float m_pos, m_level, m_leftamp, m_rightamp;
47 struct Balance2 : public Unit
49 float m_pos, m_level, m_leftamp, m_rightamp;
52 struct Rotate2 : public Unit
54 float m_pos, m_sint, m_cost;
57 struct XFade2 : public Unit
59 float m_pos, m_level, m_leftamp, m_rightamp;
62 struct LinXFade2 : public Unit
64 float m_pos, m_amp;
67 struct Pan2 : public Unit
69 float m_pos, m_level, m_leftamp, m_rightamp;
72 struct Pan4 : public Unit
74 float m_xpos, m_ypos, m_level, m_LF_amp, m_RF_amp, m_LB_amp, m_RB_amp;
77 struct PanB : public Unit
79 float m_azimuth, m_elevation, m_level, m_W_amp, m_X_amp, m_Y_amp, m_Z_amp;
82 struct PanB2 : public Unit
84 float m_azimuth, m_level, m_W_amp, m_X_amp, m_Y_amp;
87 struct BiPanB2 : public Unit
89 float m_azimuth, m_level, m_W_amp, m_X_amp, m_Y_amp;
92 struct PanAz : public Unit
94 float * m_chanamp;
97 struct DecodeB2 : public Unit
99 float m_cosa, m_sina;
100 float m_W_amp, m_X_amp, m_Y_amp;
103 //////////////////////////////////////////////////////////////////////////////////////////////////
105 extern "C"
107 void LinPan2_next_ak(LinPan2 *unit, int inNumSamples);
108 void LinPan2_next_aa(LinPan2 *unit, int inNumSamples);
109 void LinPan2_Ctor(LinPan2* unit);
111 void Balance2_next_ak(Balance2 *unit, int inNumSamples);
112 #ifdef NOVA_SIMD
113 inline_functions void Balance2_next_ak_nova(Balance2 *unit, int inNumSamples);
114 inline_functions void Balance2_next_ak_nova_64(Balance2 *unit, int inNumSamples);
115 #endif
116 void Balance2_next_aa(Balance2 *unit, int inNumSamples);
117 void Balance2_Ctor(Balance2* unit);
119 void XFade2_next_ak(XFade2 *unit, int inNumSamples);
120 void XFade2_next_aa(XFade2 *unit, int inNumSamples);
121 void XFade2_Ctor(XFade2* unit);
123 void LinXFade2_next_k(LinXFade2 *unit, int inNumSamples);
124 void LinXFade2_next_a(LinXFade2 *unit, int inNumSamples);
125 void LinXFade2_Ctor(LinXFade2* unit);
127 void Pan2_next_ak(Pan2 *unit, int inNumSamples);
128 void vPan2_next_ak(Pan2 *unit, int inNumSamples);
129 void Pan2_next_aa(Pan2 *unit, int inNumSamples);
130 void Pan2_Ctor(Pan2* unit);
132 void Pan4_next(Pan4 *unit, int inNumSamples);
133 void Pan4_Ctor(Pan4* unit);
135 void PanB_next(PanB *unit, int inNumSamples);
136 void PanB_Ctor(PanB* unit);
138 void PanB2_next(PanB2 *unit, int inNumSamples);
139 void PanB2_Ctor(PanB2* unit);
141 void BiPanB2_next(BiPanB2 *unit, int inNumSamples);
142 void BiPanB2_Ctor(BiPanB2* unit);
144 void DecodeB2_next(DecodeB2 *unit, int inNumSamples);
145 void DecodeB2_next_nova(DecodeB2 *unit, int inNumSamples);
146 void vDecodeB2_next(DecodeB2 *unit, int inNumSamples);
147 void DecodeB2_Ctor(DecodeB2* unit);
149 void PanAz_next_ak(PanAz *unit, int inNumSamples);
150 void PanAz_next_aa(PanAz *unit, int inNumSamples);
151 void PanAz_Ctor(PanAz* unit);
153 void Rotate2_next_ak(Rotate2 *unit, int inNumSamples);
154 void Rotate2_Ctor(Rotate2 *unit);
157 //////////////////////////////////////////////////////////////////////////////////////////////////
159 #ifdef NOVA_SIMD
160 inline_functions void LinPan2_next_ak_nova(LinPan2 *unit, int inNumSamples);
161 inline_functions void LinPan2_next_ak_nova_64(LinPan2 *unit, int inNumSamples);
162 #endif
164 void LinPan2_Ctor(LinPan2 *unit)
166 if (INRATE(1) == calc_FullRate) {
167 SETCALC(LinPan2_next_aa);
168 } else {
169 #ifdef NOVA_SIMD
170 if (BUFLENGTH == 64)
171 SETCALC(LinPan2_next_ak_nova_64);
172 if (!(BUFLENGTH & 15))
173 SETCALC(LinPan2_next_ak_nova);
174 else
175 #endif
176 SETCALC(LinPan2_next_ak);
178 // Now we need to initialise some values, which on the first _next run will be "previous"
179 float pan = ZIN0(1) * 0.5f + 0.5f;
180 unit->m_level = ZIN0(2);
181 unit->m_rightamp = unit->m_level * pan;
182 unit->m_leftamp = unit->m_level - unit->m_rightamp;
184 LinPan2_next_aa(unit, 1);
187 void LinPan2_next_ak(LinPan2 *unit, int inNumSamples)
189 float *leftout = ZOUT(0);
190 float *rightout = ZOUT(1);
191 float *in = ZIN(0);
192 float pos = ZIN0(1);
193 float level = ZIN0(2);
194 float leftamp = unit->m_leftamp;
195 float rightamp = unit->m_rightamp;
197 if (pos != unit->m_pos || unit->m_level != level) {
198 float pan = pos * 0.5f + 0.5f;
199 float nextrightamp = level * pan;
200 float nextleftamp = level - nextrightamp;
202 float slopeFactor = unit->mRate->mSlopeFactor;
203 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
204 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
206 LOOP1(inNumSamples,
207 float zin = ZXP(in);
208 ZXP(leftout) = zin * leftamp;
209 ZXP(rightout) = zin * rightamp;
210 leftamp += leftampslope;
211 rightamp += rightampslope;
213 unit->m_pos = pos;
214 unit->m_level = level;
215 unit->m_leftamp = nextleftamp;
216 unit->m_rightamp = nextrightamp;
217 } else {
218 LOOP1(inNumSamples,
219 float zin = ZXP(in);
220 ZXP(leftout) = zin * leftamp;
221 ZXP(rightout) = zin * rightamp;
226 #ifdef NOVA_SIMD
227 void LinPan2_next_ak_nova(LinPan2 *unit, int inNumSamples)
229 float pos = ZIN0(1);
230 float level = ZIN0(2);
231 float leftamp = unit->m_leftamp;
232 float rightamp = unit->m_rightamp;
234 if (pos != unit->m_pos || unit->m_level != level) {
235 float pan = pos * 0.5f + 0.5f;
236 float nextrightamp = level * pan;
237 float nextleftamp = level - nextrightamp;
239 float slopeFactor = unit->mRate->mSlopeFactor;
240 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
241 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
243 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
244 rightamp, rightampslope, inNumSamples);
245 unit->m_pos = pos;
246 unit->m_level = level;
247 unit->m_leftamp = nextleftamp;
248 unit->m_rightamp = nextrightamp;
249 } else
250 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, rightamp, inNumSamples);
253 void LinPan2_next_ak_nova_64(LinPan2 *unit, int inNumSamples)
255 float pos = ZIN0(1);
256 float level = ZIN0(2);
257 float leftamp = unit->m_leftamp;
258 float rightamp = unit->m_rightamp;
260 if (pos != unit->m_pos || unit->m_level != level) {
261 float pan = pos * 0.5f + 0.5f;
262 float nextrightamp = level * pan;
263 float nextleftamp = level - nextrightamp;
265 float slopeFactor = unit->mRate->mSlopeFactor;
266 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
267 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
269 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
270 rightamp, rightampslope);
271 unit->m_pos = pos;
272 unit->m_level = level;
273 unit->m_leftamp = nextleftamp;
274 unit->m_rightamp = nextrightamp;
275 } else
276 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, rightamp);
278 #endif
280 void LinPan2_next_aa(LinPan2 *unit, int inNumSamples)
282 float *leftout = ZOUT(0);
283 float *rightout = ZOUT(1);
284 float *in = ZIN(0);
285 float *pos = ZIN(1);
286 float nextlevel = ZIN0(2);
287 float level = unit->m_level;
288 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
290 LOOP1(inNumSamples,
291 float pan = ZXP(pos) * 0.5f + 0.5f;
292 float rightamp = level * pan;
293 float leftamp = level - rightamp;
294 float zin = ZXP(in);
295 ZXP(leftout) = zin * leftamp;
296 ZXP(rightout) = zin * rightamp;
297 level += levelSlope;
299 unit->m_level = level;
303 ////////////////////////////////////////////////////////////////////////////////////////////////////////
305 void Balance2_Ctor(Balance2 *unit)
307 if (INRATE(2) == calc_FullRate) {
308 SETCALC(Balance2_next_aa);
309 } else {
310 #ifdef NOVA_SIMD
311 if (BUFLENGTH == 64)
312 SETCALC(Balance2_next_ak_nova_64);
313 else if (!(BUFLENGTH & 15))
314 SETCALC(Balance2_next_ak_nova);
315 else
316 SETCALC(Balance2_next_ak);
317 #else
318 SETCALC(Balance2_next_ak);
319 #endif
321 unit->m_pos = ZIN0(2);
322 unit->m_level = ZIN0(3);
323 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f);
324 ipos = sc_clip(ipos, 0, 2048);
326 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
327 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
328 Balance2_next_aa(unit, 1);
331 void Balance2_next_ak(Balance2 *unit, int inNumSamples)
333 float *leftout = ZOUT(0);
334 float *rightout = ZOUT(1);
335 float *leftin = ZIN(0);
336 float *rightin = ZIN(1);
337 float pos = ZIN0(2);
338 float level = ZIN0(3);
339 float leftamp = unit->m_leftamp;
340 float rightamp = unit->m_rightamp;
342 if (pos != unit->m_pos || unit->m_level != level) {
343 int32 ipos = (int32)(1024.f * pos + 1024.f);
344 ipos = sc_clip(ipos, 0, 2048);
346 float nextleftamp = level * ft->mSine[2048 - ipos];
347 float nextrightamp = level * ft->mSine[ipos];
349 float slopeFactor = unit->mRate->mSlopeFactor;
350 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
351 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
353 LOOP1(inNumSamples,
354 ZXP(leftout) = ZXP(leftin) * leftamp;
355 ZXP(rightout) = ZXP(rightin) * rightamp;
356 leftamp += leftampslope;
357 rightamp += rightampslope;
359 unit->m_pos = pos;
360 unit->m_level = level;
361 unit->m_leftamp = nextleftamp;
362 unit->m_rightamp = nextrightamp;
363 } else {
364 LOOP1(inNumSamples,
365 ZXP(leftout) = ZXP(leftin) * leftamp;
366 ZXP(rightout) = ZXP(rightin) * rightamp;
371 #ifdef NOVA_SIMD
372 void Balance2_next_ak_nova(Balance2 *unit, int inNumSamples)
374 float pos = ZIN0(2);
375 float level = ZIN0(3);
376 float leftamp = unit->m_leftamp;
377 float rightamp = unit->m_rightamp;
379 if (pos != unit->m_pos || unit->m_level != level) {
380 int32 ipos = (int32)(1024.f * pos + 1024.f);
381 ipos = sc_clip(ipos, 0, 2048);
383 float nextleftamp = level * ft->mSine[2048 - ipos];
384 float nextrightamp = level * ft->mSine[ipos];
386 float slopeFactor = unit->mRate->mSlopeFactor;
387 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
388 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
390 unit->m_pos = pos;
391 unit->m_level = level;
392 unit->m_leftamp = nextleftamp;
393 unit->m_rightamp = nextrightamp;
395 //nova::times_vec2_ramp_simd(OUT(0), IN(0), leftamp, leftampslope, OUT(1), IN(1), rightamp, rightampslope, inNumSamples);
396 nova::times_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope), inNumSamples);
397 nova::times_vec_simd(OUT(1), IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
398 } else {
399 //nova::times_vec2_simd(OUT(0), IN(0), leftamp, OUT(1), IN(1), rightamp, inNumSamples);
400 nova::times_vec_simd(OUT(0), IN(0), leftamp, inNumSamples);
401 nova::times_vec_simd(OUT(1), IN(1), rightamp, inNumSamples);
405 void Balance2_next_ak_nova_64(Balance2 *unit, int inNumSamples)
407 float pos = ZIN0(2);
408 float level = ZIN0(3);
409 float leftamp = unit->m_leftamp;
410 float rightamp = unit->m_rightamp;
412 if (pos != unit->m_pos || unit->m_level != level) {
413 int32 ipos = (int32)(1024.f * pos + 1024.f);
414 ipos = sc_clip(ipos, 0, 2048);
416 float nextleftamp = level * ft->mSine[2048 - ipos];
417 float nextrightamp = level * ft->mSine[ipos];
419 float slopeFactor = unit->mRate->mSlopeFactor;
420 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
421 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
423 unit->m_pos = pos;
424 unit->m_level = level;
425 unit->m_leftamp = nextleftamp;
426 unit->m_rightamp = nextrightamp;
428 //nova::times_vec2_ramp_simd(OUT(0), IN(0), leftamp, leftampslope, OUT(1), IN(1), rightamp, rightampslope, inNumSamples);
429 nova::times_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope), inNumSamples);
430 nova::times_vec_simd(OUT(1), IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
431 } else {
432 //nova::times_vec2_simd(OUT(0), IN(0), leftamp, OUT(1), IN(1), rightamp, inNumSamples);
433 nova::times_vec_simd<64>(OUT(0), IN(0), leftamp);
434 nova::times_vec_simd<64>(OUT(1), IN(1), rightamp);
437 #endif
439 void Balance2_next_aa(Balance2 *unit, int inNumSamples)
441 float *leftout = ZOUT(0);
442 float *rightout = ZOUT(1);
443 float *leftin = ZIN(0);
444 float *rightin = ZIN(1);
445 float *pos = ZIN(2);
446 float nextlevel = ZIN0(3);
447 float level = unit->m_level;
449 float *sineTable = ft->mSine;
450 if (level != nextlevel) {
451 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
452 LOOP1(inNumSamples,
453 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f);
454 ipos = sc_clip(ipos, 0, 2048);
456 float leftamp = level * sineTable[2048 - ipos];
457 float rightamp = level * sineTable[ipos];
458 ZXP(leftout) = ZXP(leftin) * leftamp;
459 ZXP(rightout) = ZXP(rightin) * rightamp;
460 level += levelSlope;
462 unit->m_level = level;
463 } else {
464 LOOP1(inNumSamples,
465 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f);
466 ipos = sc_clip(ipos, 0, 2048);
468 float leftamp = level * sineTable[2048 - ipos];
469 float rightamp = level * sineTable[ipos];
470 ZXP(leftout) = ZXP(leftin) * leftamp;
471 ZXP(rightout) = ZXP(rightin) * rightamp;
476 ////////////////////////////////////////////////////////////////////////////////////////////////////////
478 #ifdef NOVA_SIMD
479 inline_functions void XFade2_next_ak_nova(XFade2 *unit, int inNumSamples);
480 inline_functions void XFade2_next_ak_nova_64(XFade2 *unit, int inNumSamples);
481 #endif
483 void XFade2_Ctor(XFade2 *unit)
485 if (INRATE(2) == calc_FullRate) {
486 SETCALC(XFade2_next_aa);
487 } else {
488 #ifdef NOVA_SIMD
489 if (BUFLENGTH == 64)
490 SETCALC(XFade2_next_ak_nova_64);
491 if (!(BUFLENGTH & 15))
492 SETCALC(XFade2_next_ak_nova);
493 else
494 #endif
495 SETCALC(XFade2_next_ak);
497 unit->m_pos = ZIN0(2);
498 unit->m_level = ZIN0(3);
499 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f);
500 ipos = sc_clip(ipos, 0, 2048);
502 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
503 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
504 XFade2_next_aa(unit, 1);
507 void XFade2_next_ak(XFade2 *unit, int inNumSamples)
509 float *out = ZOUT(0);
510 float *leftin = ZIN(0);
511 float *rightin = ZIN(1);
512 float pos = ZIN0(2);
513 float level = ZIN0(3);
514 float leftamp = unit->m_leftamp;
515 float rightamp = unit->m_rightamp;
517 if (pos != unit->m_pos || unit->m_level != level) {
518 int32 ipos = (int32)(1024.f * pos + 1024.f);
519 ipos = sc_clip(ipos, 0, 2048);
521 float nextleftamp = level * ft->mSine[2048 - ipos];
522 float nextrightamp = level * ft->mSine[ipos];
524 float slopeFactor = unit->mRate->mSlopeFactor;
525 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
526 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
528 LOOP1(inNumSamples,
529 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
530 leftamp += leftampslope;
531 rightamp += rightampslope;
533 unit->m_pos = pos;
534 unit->m_level = level;
535 unit->m_leftamp = nextleftamp;
536 unit->m_rightamp = nextrightamp;
537 } else {
538 LOOP1(inNumSamples,
539 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
544 #ifdef NOVA_SIMD
545 void XFade2_next_ak_nova(XFade2 *unit, int inNumSamples)
547 float pos = ZIN0(2);
548 float level = ZIN0(3);
549 float leftamp = unit->m_leftamp;
550 float rightamp = unit->m_rightamp;
552 if (pos != unit->m_pos || unit->m_level != level) {
553 int32 ipos = (int32)(1024.f * pos + 1024.f);
554 ipos = sc_clip(ipos, 0, 2048);
556 float nextleftamp = level * ft->mSine[2048 - ipos];
557 float nextrightamp = level * ft->mSine[ipos];
559 float slopeFactor = unit->mRate->mSlopeFactor;
560 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
561 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
563 nova::mix_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope),
564 IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
566 unit->m_pos = pos;
567 unit->m_level = level;
568 unit->m_leftamp = nextleftamp;
569 unit->m_rightamp = nextrightamp;
570 } else
571 nova::mix_vec_simd(OUT(0), IN(0), leftamp, IN(1), rightamp, inNumSamples);
574 void XFade2_next_ak_nova_64(XFade2 *unit, int inNumSamples)
576 float pos = ZIN0(2);
577 float level = ZIN0(3);
578 float leftamp = unit->m_leftamp;
579 float rightamp = unit->m_rightamp;
581 if (pos != unit->m_pos || unit->m_level != level) {
582 int32 ipos = (int32)(1024.f * pos + 1024.f);
583 ipos = sc_clip(ipos, 0, 2048);
585 float nextleftamp = level * ft->mSine[2048 - ipos];
586 float nextrightamp = level * ft->mSine[ipos];
588 float slopeFactor = unit->mRate->mSlopeFactor;
589 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
590 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
592 nova::mix_vec_simd<64>(OUT(0), IN(0), slope_argument(leftamp, leftampslope),
593 IN(1), slope_argument(rightamp, rightampslope));
595 unit->m_pos = pos;
596 unit->m_level = level;
597 unit->m_leftamp = nextleftamp;
598 unit->m_rightamp = nextrightamp;
599 } else
600 nova::mix_vec_simd<64>(OUT(0), IN(0), leftamp, IN(1), rightamp);
603 #endif
605 void XFade2_next_aa(XFade2 *unit, int inNumSamples)
607 float *out = ZOUT(0);
608 float *leftin = ZIN(0);
609 float *rightin = ZIN(1);
610 float *pos = ZIN(2);
611 float nextlevel = ZIN0(3);
612 float level = unit->m_level;
614 float *sineTable = ft->mSine;
615 if (level != nextlevel) {
616 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
617 LOOP1(inNumSamples,
618 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f);
619 ipos = sc_clip(ipos, 0, 2048);
621 float leftamp = level * sineTable[2048 - ipos];
622 float rightamp = level * sineTable[ipos];
623 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
624 level += levelSlope;
626 unit->m_level = level;
627 } else {
628 LOOP1(inNumSamples,
629 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f);
630 ipos = sc_clip(ipos, 0, 2048);
632 float leftamp = level * sineTable[2048 - ipos];
633 float rightamp = level * sineTable[ipos];
634 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
639 ////////////////////////////////////////////////////////////////////////////////////////////////////////
641 ////////////////////////////////////////////////////////////////////////////////////////////////////////
643 void LinXFade2_Ctor(LinXFade2 *unit)
645 if (INRATE(2) == calc_FullRate) {
646 SETCALC(LinXFade2_next_a);
647 } else {
648 SETCALC(LinXFade2_next_k);
650 unit->m_pos = ZIN0(2);
651 unit->m_pos = sc_clip(unit->m_pos, -1.f, 1.f);
652 unit->m_amp = unit->m_pos * 0.5f + 0.5f;
654 LinXFade2_next_a(unit, 1);
657 void LinXFade2_next_k(LinXFade2 *unit, int inNumSamples)
659 float *out = ZOUT(0);
660 float *leftin = ZIN(0);
661 float *rightin = ZIN(1);
662 float pos = ZIN0(2);
663 float amp = unit->m_amp;
665 if (pos != unit->m_pos) {
666 pos = sc_clip(pos, -1.f, 1.f);
668 float nextamp = pos * 0.5f + 0.5f;
669 float amp_slope = (nextamp - amp) * unit->mRate->mSlopeFactor;
671 LOOP1(inNumSamples,
672 float l = ZXP(leftin);
673 float r = ZXP(rightin);
674 ZXP(out) = l + amp * (r - l);
675 amp += amp_slope;
677 unit->m_pos = pos;
678 unit->m_amp = amp;
679 } else {
680 LOOP1(inNumSamples,
681 float l = ZXP(leftin);
682 float r = ZXP(rightin);
683 ZXP(out) = l + amp * (r - l);
688 void LinXFade2_next_a(LinXFade2 *unit, int inNumSamples)
690 float *out = ZOUT(0);
691 float *leftin = ZIN(0);
692 float *rightin = ZIN(1);
693 float *posp = ZIN(2);
695 LOOP1(inNumSamples,
696 float pos = ZXP(posp);
697 pos = sc_clip(pos, -1.f, 1.f);
698 float amp = pos * 0.5f + 0.5f;
699 float l = ZXP(leftin);
700 float r = ZXP(rightin);
701 ZXP(out) = l + amp * (r - l);
705 ////////////////////////////////////////////////////////////////////////////////////////////////////////
707 void Pan2_next_ak(Pan2 *unit, int inNumSamples)
709 float *leftout = ZOUT(0);
710 float *rightout = ZOUT(1);
711 float *in = ZIN(0);
712 float pos = ZIN0(1);
713 float level = ZIN0(2);
714 float leftamp = unit->m_leftamp;
715 float rightamp = unit->m_rightamp;
717 if (pos != unit->m_pos || unit->m_level != level) {
718 int32 ipos = (int32)(1024.f * pos + 1024.f);
719 ipos = sc_clip(ipos, 0, 2048);
721 float nextleftamp = level * ft->mSine[2048 - ipos];
722 float nextrightamp = level * ft->mSine[ipos];
724 float slopeFactor = unit->mRate->mSlopeFactor;
725 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
726 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
728 LOOP1(inNumSamples,
729 float zin = ZXP(in);
730 ZXP(leftout) = zin * leftamp;
731 ZXP(rightout) = zin * rightamp;
732 leftamp += leftampslope;
733 rightamp += rightampslope;
735 unit->m_pos = pos;
736 unit->m_level = level;
737 unit->m_leftamp = nextleftamp;
738 unit->m_rightamp = nextrightamp;
739 } else {
740 LOOP1(inNumSamples,
741 float zin = ZXP(in);
742 ZXP(leftout) = zin * leftamp;
743 ZXP(rightout) = zin * rightamp;
748 #ifdef NOVA_SIMD
749 void Pan2_next_ak_nova(Pan2 *unit, int inNumSamples)
751 float pos = ZIN0(1);
752 float level = ZIN0(2);
753 float leftamp = unit->m_leftamp;
754 float rightamp = unit->m_rightamp;
756 if (pos != unit->m_pos || unit->m_level != level) {
757 int32 ipos = (int32)(1024.f * pos + 1024.f);
758 ipos = sc_clip(ipos, 0, 2048);
760 float nextleftamp = level * ft->mSine[2048 - ipos];
761 float nextrightamp = level * ft->mSine[ipos];
763 float slopeFactor = unit->mRate->mSlopeFactor;
764 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
765 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
767 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
768 rightamp, rightampslope, inNumSamples);
770 unit->m_pos = pos;
771 unit->m_level = level;
772 unit->m_leftamp = nextleftamp;
773 unit->m_rightamp = nextrightamp;
774 } else
775 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, rightamp, inNumSamples);
778 void Pan2_next_ak_nova_64(Pan2 *unit, int inNumSamples)
780 float pos = ZIN0(1);
781 float level = ZIN0(2);
782 float leftamp = unit->m_leftamp;
783 float rightamp = unit->m_rightamp;
785 if (pos != unit->m_pos || unit->m_level != level) {
786 int32 ipos = (int32)(1024.f * pos + 1024.f);
787 ipos = sc_clip(ipos, 0, 2048);
789 float nextleftamp = level * ft->mSine[2048 - ipos];
790 float nextrightamp = level * ft->mSine[ipos];
792 float slopeFactor = unit->mRate->mSlopeFactor;
793 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
794 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
796 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
797 rightamp, rightampslope);
799 unit->m_pos = pos;
800 unit->m_level = level;
801 unit->m_leftamp = nextleftamp;
802 unit->m_rightamp = nextrightamp;
803 } else
804 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, rightamp);
807 #endif
810 void Pan2_next_aa(Pan2 *unit, int inNumSamples)
812 float *leftout = ZOUT(0);
813 float *rightout = ZOUT(1);
814 float *in = ZIN(0);
815 float *pos = ZIN(1);
816 float nextlevel = ZIN0(2);
817 float level = unit->m_level;
819 if (level != nextlevel) {
820 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
822 LOOP1(inNumSamples,
823 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f);
824 ipos = sc_clip(ipos, 0, 2048);
826 float leftamp = level * ft->mSine[2048 - ipos];
827 float rightamp = level * ft->mSine[ipos];
828 float zin = ZXP(in);
829 ZXP(leftout) = zin * leftamp;
830 ZXP(rightout) = zin * rightamp;
831 level += levelSlope;
833 unit->m_level = level;
834 } else {
835 LOOP1(inNumSamples,
836 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f);
837 ipos = sc_clip(ipos, 0, 2048);
839 float leftamp = level * ft->mSine[2048 - ipos];
840 float rightamp = level * ft->mSine[ipos];
841 float zin = ZXP(in);
842 ZXP(leftout) = zin * leftamp;
843 ZXP(rightout) = zin * rightamp;
848 void Pan2_Ctor(Pan2 *unit)
850 if (INRATE(1) == calc_FullRate) {
851 SETCALC(Pan2_next_aa);
852 } else {
853 #if defined(NOVA_SIMD)
854 if (BUFLENGTH == 64)
855 SETCALC(Pan2_next_ak_nova_64);
856 if (!(BUFLENGTH & 15))
857 SETCALC(Pan2_next_ak_nova);
858 else
859 SETCALC(Pan2_next_ak);
860 #else
861 SETCALC(Pan2_next_ak);
862 #endif
865 unit->m_pos = ZIN0(1);
866 unit->m_level = ZIN0(2);
867 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f);
868 ipos = sc_clip(ipos, 0, 2048);
870 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
871 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
872 Pan2_next_aa(unit, 1);
875 ////////////////////////////////////////////////////////////////////////////////////////////////////////
877 void Pan4_Ctor(Pan4 *unit)
879 SETCALC(Pan4_next);
880 //float *in = ZIN(0);
881 float xpos = ZIN0(1);
882 float ypos = ZIN0(2);
883 float level = ZIN0(3);
885 unit->m_xpos = xpos;
886 unit->m_ypos = ypos;
887 unit->m_level = level;
888 if (xpos < -1.f || xpos > 1.f || ypos < -1.f || ypos > 1.f) {
889 float xabs = fabs(xpos);
891 if (ypos > xabs) {
892 xpos = (xpos + ypos) / ypos - 1.f;
893 ypos = 1.f;
894 } else if (ypos < -xabs) {
895 xpos = (xpos - ypos) / -ypos - 1.f;
896 ypos = -1.f;
897 } else {
898 float yabs = fabs(ypos);
899 if (yabs < xpos) {
900 ypos = (ypos + xpos) / xpos - 1.f;
901 xpos = 1.f;
902 } else {
903 ypos = (ypos - xpos) / -xpos - 1.f;
904 xpos = -1.f;
909 int32 ixpos = (int32)(1024.f * xpos + 1024.f);
910 ixpos = sc_clip(ixpos, 0, 2048);
911 float leftamp = ft->mSine[2048 - ixpos];
912 float rightamp = ft->mSine[ixpos];
914 int32 iypos = (int32)(1024.f * ypos + 1024.f);
915 iypos = sc_clip(iypos, 0, 2048);
916 float frontamp = ft->mSine[iypos];
917 float backamp = ft->mSine[2048 - iypos];
919 frontamp *= level;
920 backamp *= level;
922 unit->m_LF_amp = leftamp * frontamp;
923 unit->m_RF_amp = rightamp * frontamp;
924 unit->m_LB_amp = leftamp * backamp;
925 unit->m_RB_amp = rightamp * backamp;
927 float z = ZIN0(0);
928 ZOUT0(0) = z * unit->m_LF_amp;
929 ZOUT0(1) = z * unit->m_RF_amp;
930 ZOUT0(2) = z * unit->m_LB_amp;
931 ZOUT0(3) = z * unit->m_RB_amp;
934 void Pan4_next(Pan4 *unit, int inNumSamples)
936 float *LFout = ZOUT(0);
937 float *RFout = ZOUT(1);
938 float *LBout = ZOUT(2);
939 float *RBout = ZOUT(3);
941 float *in = ZIN(0);
942 float xpos = ZIN0(1);
943 float ypos = ZIN0(2);
944 float level = ZIN0(3);
946 float LF_amp = unit->m_LF_amp;
947 float RF_amp = unit->m_RF_amp;
948 float LB_amp = unit->m_LB_amp;
949 float RB_amp = unit->m_RB_amp;
951 if (xpos != unit->m_xpos || ypos != unit->m_ypos || level != unit->m_level) {
952 unit->m_xpos = xpos;
953 unit->m_ypos = ypos;
954 unit->m_level = level;
955 if (xpos < -1.f || xpos > 1.f || ypos < -1.f || ypos > 1.f) {
956 float xabs = fabs(xpos);
958 if (ypos > xabs) {
959 xpos = (xpos + ypos) / ypos - 1.f;
960 ypos = 1.f;
961 } else if (ypos < -xabs) {
962 xpos = (xpos - ypos) / -ypos - 1.f;
963 ypos = -1.f;
964 } else {
965 float yabs = fabs(ypos);
966 if (yabs < xpos) {
967 ypos = (ypos + xpos) / xpos - 1.f;
968 xpos = 1.f;
969 } else {
970 ypos = (ypos - xpos) / -xpos - 1.f;
971 xpos = -1.f;
976 int32 ixpos = (int32)(1024.f * xpos + 1024.f);
977 ixpos = sc_clip(ixpos, 0, 2048);
978 float leftamp = ft->mSine[2048 - ixpos];
979 float rightamp = ft->mSine[ixpos];
981 int32 iypos = (int32)(1024.f * ypos + 1024.f);
982 iypos = sc_clip(iypos, 0, 2048);
983 float frontamp = ft->mSine[iypos];
984 float backamp = ft->mSine[2048 - iypos];
986 frontamp *= level;
987 backamp *= level;
989 float next_LF_amp = leftamp * frontamp;
990 float next_RF_amp = rightamp * frontamp;
991 float next_LB_amp = leftamp * backamp;
992 float next_RB_amp = rightamp * backamp;
994 float LF_slope = CALCSLOPE(next_LF_amp, LF_amp);
995 float RF_slope = CALCSLOPE(next_RF_amp, RF_amp);
996 float LB_slope = CALCSLOPE(next_LB_amp, LB_amp);
997 float RB_slope = CALCSLOPE(next_RB_amp, RB_amp);
999 LOOP1(inNumSamples,
1000 float z = ZXP(in);
1001 ZXP(LFout) = z * LF_amp;
1002 ZXP(RFout) = z * RF_amp;
1003 ZXP(LBout) = z * LB_amp;
1004 ZXP(RBout) = z * RB_amp;
1005 LF_amp += LF_slope;
1006 RF_amp += RF_slope;
1007 LB_amp += LB_slope;
1008 RB_amp += RB_slope;
1010 unit->m_LF_amp = LF_amp;
1011 unit->m_RF_amp = RF_amp;
1012 unit->m_LB_amp = LB_amp;
1013 unit->m_RB_amp = RB_amp;
1014 } else {
1015 LOOP1(inNumSamples,
1016 float z = ZXP(in);
1017 ZXP(LFout) = z * LF_amp;
1018 ZXP(RFout) = z * RF_amp;
1019 ZXP(LBout) = z * LB_amp;
1020 ZXP(RBout) = z * RB_amp;
1025 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1027 void PanB_Ctor(PanB *unit)
1029 SETCALC(PanB_next);
1030 float azimuth = unit->m_azimuth = ZIN0(1);
1031 float elevation = unit->m_elevation = ZIN0(2);
1032 float level = unit->m_level = ZIN0(3);
1034 int kSineSize = ft->mSineSize;
1035 int kSineMask = kSineSize - 1;
1037 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1038 long ielevation = kSineMask & (long)(elevation * (float)(kSineSize >> 2));
1039 float sina = -ft->mSine[iazimuth];
1040 float sinb = ft->mSine[ielevation];
1042 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1043 ielevation = kSineMask & (ielevation + (kSineSize>>2));
1044 float cosa = ft->mSine[iazimuth];
1045 float cosb = ft->mSine[ielevation];
1047 unit->m_W_amp = rsqrt2_f * level;
1048 unit->m_X_amp = cosa * cosb * level;
1049 unit->m_Y_amp = sina * cosb * level;
1050 unit->m_Z_amp = sinb * level;
1052 PanB_next(unit, 1);
1055 void PanB_next(PanB *unit, int inNumSamples)
1057 float *Wout = ZOUT(0);
1058 float *Xout = ZOUT(1);
1059 float *Yout = ZOUT(2);
1060 float *Zout = ZOUT(3);
1062 float *in = ZIN(0);
1063 float azimuth = ZIN0(1);
1064 float elevation = ZIN0(2);
1065 float level = ZIN0(3);
1067 float W_amp = unit->m_W_amp;
1068 float X_amp = unit->m_X_amp;
1069 float Y_amp = unit->m_Y_amp;
1070 float Z_amp = unit->m_Z_amp;
1072 int kSineSize = ft->mSineSize;
1073 int kSineMask = kSineSize - 1;
1074 if (azimuth != unit->m_azimuth || elevation != unit->m_elevation || level != unit->m_level) {
1075 unit->m_azimuth = azimuth;
1076 unit->m_elevation = elevation;
1077 unit->m_level = level;
1079 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1080 long ielevation = kSineMask & (long)(elevation * (float)(kSineSize >> 2));
1081 float sina = -ft->mSine[iazimuth];
1082 float sinb = ft->mSine[ielevation];
1084 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1085 ielevation = kSineMask & (ielevation + (kSineSize>>2));
1086 float cosa = ft->mSine[iazimuth];
1087 float cosb = ft->mSine[ielevation];
1089 float next_W_amp = rsqrt2_f * level;
1090 float next_X_amp = cosa * cosb * level;
1091 float next_Y_amp = sina * cosb * level;
1092 float next_Z_amp = sinb * level;
1094 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1095 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1096 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1097 float Z_slope = CALCSLOPE(next_Z_amp, Z_amp);
1099 LOOP1(inNumSamples,
1100 float z = ZXP(in);
1101 ZXP(Wout) = z * W_amp;
1102 ZXP(Xout) = z * X_amp;
1103 ZXP(Yout) = z * Y_amp;
1104 ZXP(Zout) = z * Z_amp;
1105 W_amp += W_slope;
1106 X_amp += X_slope;
1107 Y_amp += Y_slope;
1108 Z_amp += Z_slope;
1110 unit->m_W_amp = W_amp;
1111 unit->m_X_amp = X_amp;
1112 unit->m_Y_amp = Y_amp;
1113 unit->m_Z_amp = Z_amp;
1114 } else {
1115 LOOP1(inNumSamples,
1116 float z = ZXP(in);
1117 ZXP(Wout) = z * W_amp;
1118 ZXP(Xout) = z * X_amp;
1119 ZXP(Yout) = z * Y_amp;
1120 ZXP(Zout) = z * Z_amp;
1125 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1127 void PanB2_next(PanB2 *unit, int inNumSamples)
1129 float *Wout = ZOUT(0);
1130 float *Xout = ZOUT(1);
1131 float *Yout = ZOUT(2);
1133 float *in = ZIN(0);
1134 float azimuth = ZIN0(1);
1135 float level = ZIN0(2);
1137 float W_amp = unit->m_W_amp;
1138 float X_amp = unit->m_X_amp;
1139 float Y_amp = unit->m_Y_amp;
1141 int kSineSize = ft->mSineSize;
1142 int kSineMask = kSineSize - 1;
1143 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1144 unit->m_azimuth = azimuth;
1145 unit->m_level = level;
1147 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1148 float sina = -ft->mSine[isinpos];
1150 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1151 float cosa = ft->mSine[icospos];
1153 float next_W_amp = rsqrt2_f * level;
1154 float next_X_amp = cosa * level;
1155 float next_Y_amp = sina * level;
1157 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1158 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1159 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1161 LOOP1(inNumSamples,
1162 float z = ZXP(in);
1163 ZXP(Wout) = z * W_amp;
1164 ZXP(Xout) = z * X_amp;
1165 ZXP(Yout) = z * Y_amp;
1166 W_amp += W_slope;
1167 X_amp += X_slope;
1168 Y_amp += Y_slope;
1170 unit->m_W_amp = W_amp;
1171 unit->m_X_amp = X_amp;
1172 unit->m_Y_amp = Y_amp;
1173 } else {
1174 LOOP1(inNumSamples,
1175 float z = ZXP(in);
1176 ZXP(Wout) = z * W_amp;
1177 ZXP(Xout) = z * X_amp;
1178 ZXP(Yout) = z * Y_amp;
1183 #ifdef NOVA_SIMD
1185 void PanB2_next_nova(PanB2 *unit, int inNumSamples)
1187 float *Wout = OUT(0);
1188 float *Xout = OUT(1);
1189 float *Yout = OUT(2);
1191 float *in = IN(0);
1192 float azimuth = ZIN0(1);
1193 float level = ZIN0(2);
1195 float W_amp = unit->m_W_amp;
1196 float X_amp = unit->m_X_amp;
1197 float Y_amp = unit->m_Y_amp;
1199 int kSineSize = ft->mSineSize;
1200 int kSineMask = kSineSize - 1;
1201 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1202 unit->m_azimuth = azimuth;
1203 unit->m_level = level;
1205 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1206 float sina = -ft->mSine[isinpos];
1208 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1209 float cosa = ft->mSine[icospos];
1211 float next_W_amp = rsqrt2_f * level;
1212 float next_X_amp = cosa * level;
1213 float next_Y_amp = sina * level;
1215 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1216 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1217 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1219 nova::times_vec_simd(Wout, in, slope_argument(W_amp, W_slope), inNumSamples);
1220 nova::times_vec_simd(Xout, in, slope_argument(X_amp, X_slope), inNumSamples);
1221 nova::times_vec_simd(Yout, in, slope_argument(Y_amp, Y_slope), inNumSamples);
1223 unit->m_W_amp = next_W_amp;
1224 unit->m_X_amp = next_X_amp;
1225 unit->m_Y_amp = next_Y_amp;
1226 } else {
1227 // TODO: can be further optimized by joining the loops
1228 nova::times_vec_simd(Wout, in, W_amp, inNumSamples);
1229 nova::times_vec_simd(Xout, in, X_amp, inNumSamples);
1230 nova::times_vec_simd(Yout, in, Y_amp, inNumSamples);
1233 #endif
1235 void PanB2_Ctor(PanB2 *unit)
1237 #if defined(NOVA_SIMD)
1238 if (!(BUFLENGTH & 15))
1239 SETCALC(PanB2_next_nova);
1240 else
1241 #endif
1242 SETCALC(PanB2_next);
1244 float azimuth = unit->m_azimuth = ZIN0(1);
1245 float level = unit->m_level = ZIN0(2);
1247 int kSineSize = ft->mSineSize;
1248 int kSineMask = kSineSize - 1;
1250 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1251 float sina = -ft->mSine[isinpos];
1253 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1254 float cosa = ft->mSine[icospos];
1256 unit->m_W_amp = rsqrt2_f * level;
1257 unit->m_X_amp = cosa * level;
1258 unit->m_Y_amp = sina * level;
1260 PanB2_next(unit, 1);
1263 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1265 void BiPanB2_next(BiPanB2 *unit, int inNumSamples)
1267 float *Wout = ZOUT(0);
1268 float *Xout = ZOUT(1);
1269 float *Yout = ZOUT(2);
1271 float *inA = ZIN(0);
1272 float *inB = ZIN(1);
1273 float azimuth = ZIN0(2);
1274 float level = ZIN0(3);
1276 float W_amp = unit->m_W_amp;
1277 float X_amp = unit->m_X_amp;
1278 float Y_amp = unit->m_Y_amp;
1280 int kSineSize = ft->mSineSize;
1281 int kSineMask = kSineSize - 1;
1282 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1283 unit->m_azimuth = azimuth;
1284 unit->m_level = level;
1286 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1287 float sina = -ft->mSine[isinpos];
1289 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1290 float cosa = ft->mSine[icospos];
1292 float next_W_amp = rsqrt2_f * level;
1293 float next_X_amp = cosa * level;
1294 float next_Y_amp = sina * level;
1296 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1297 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1298 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1300 if (W_slope == 0.f) {
1301 LOOP1(inNumSamples,
1302 float a = ZXP(inA);
1303 float b = ZXP(inB);
1304 float abdiff = a - b;
1305 ZXP(Wout) = (a + b) * W_amp;
1306 ZXP(Xout) = abdiff * X_amp;
1307 ZXP(Yout) = abdiff * Y_amp;
1308 X_amp += X_slope;
1309 Y_amp += Y_slope;
1311 } else {
1312 LOOP1(inNumSamples,
1313 float a = ZXP(inA);
1314 float b = ZXP(inB);
1315 float abdiff = a - b;
1316 ZXP(Wout) = (a + b) * W_amp;
1317 ZXP(Xout) = abdiff * X_amp;
1318 ZXP(Yout) = abdiff * Y_amp;
1319 W_amp += W_slope;
1320 X_amp += X_slope;
1321 Y_amp += Y_slope;
1323 unit->m_W_amp = W_amp;
1325 unit->m_X_amp = X_amp;
1326 unit->m_Y_amp = Y_amp;
1327 } else {
1328 LOOP1(inNumSamples,
1329 float a = ZXP(inA);
1330 float b = ZXP(inB);
1331 float abdiff = a - b;
1332 ZXP(Wout) = (a + b) * W_amp;
1333 ZXP(Xout) = abdiff * X_amp;
1334 ZXP(Yout) = abdiff * Y_amp;
1339 void BiPanB2_Ctor(BiPanB2 *unit)
1341 SETCALC(BiPanB2_next);
1343 float azimuth = unit->m_azimuth = ZIN0(2);
1344 float level = unit->m_level = ZIN0(3);
1346 int kSineSize = ft->mSineSize;
1347 int kSineMask = kSineSize - 1;
1349 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1350 float sina = -ft->mSine[iazimuth];
1352 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1353 float cosa = ft->mSine[iazimuth];
1355 unit->m_W_amp = rsqrt2_f * level;
1356 unit->m_X_amp = cosa * level;
1357 unit->m_Y_amp = sina * level;
1359 BiPanB2_next(unit, 1);
1362 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1363 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1367 void calcPos(float pos, int numOutputs, float width, float orientation)
1369 float rwidth = 1.f / width;
1370 float range = numOutputs * rwidth;
1371 float rrange = 1.f / range;
1373 float zpos = pos * 0.5 * numOutputs + width * 0.5 + orientation;
1374 Print("pos %6.2g rwidth %6.3g range %6.3g rrange %6.3g zpos %6.3g\n",
1375 pos, rwidth, range, rrange, zpos);
1376 for (int i=0; i<numOutputs; ++i) {
1377 float amp;
1378 float chanpos = zpos - i;
1379 chanpos *= rwidth;
1380 float zchanpos = chanpos - range * floor(rrange * chanpos);
1381 if (zchanpos > 1.f) {
1382 amp = 0.f;
1383 } else {
1384 amp = ft->mSine[(long)(4096.f * zchanpos)];
1386 Print(" %d chanpos %6.3g zchanpos %6.3g amp %g\n",
1387 i, chanpos, zchanpos, amp);
1392 void PanAz_Ctor(PanAz *unit)
1394 if (INRATE(1) == calc_FullRate) {
1395 unit->m_chanamp = NULL;
1396 SETCALC(PanAz_next_aa);
1397 } else {
1398 int numOutputs = unit->mNumOutputs;
1399 unit->m_chanamp = (float*)RTAlloc(unit->mWorld, numOutputs*sizeof(float));
1400 for (int i=0; i<numOutputs; ++i) {
1401 unit->m_chanamp[i] = 0;
1402 ZOUT0(i) = 0.f;
1404 SETCALC(PanAz_next_ak);
1408 void PanAz_Dtor(PanAz *unit)
1410 if (unit->m_chanamp)
1411 RTFree(unit->mWorld, unit->m_chanamp);
1414 void PanAz_next_ak(PanAz *unit, int inNumSamples)
1416 float pos = ZIN0(1);
1417 float level = ZIN0(2);
1418 float width = ZIN0(3);
1419 float orientation = ZIN0(4);
1421 int numOutputs = unit->mNumOutputs;
1422 float rwidth = 1.f / width;
1423 float range = numOutputs * rwidth;
1424 float rrange = 1.f / range;
1426 pos = pos * 0.5f * numOutputs + width * 0.5f + orientation;
1428 float *zin0 = ZIN(0);
1430 for (int i=0; i<numOutputs; ++i) {
1431 float *out = ZOUT(i);
1432 float nextchanamp;
1433 float chanpos = pos - i;
1434 chanpos *= rwidth;
1435 chanpos = chanpos - range * std::floor(rrange * chanpos);
1436 if (chanpos > 1.f) {
1437 nextchanamp = 0.f;
1438 } else {
1439 nextchanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1441 float chanamp = unit->m_chanamp[i];
1443 if (nextchanamp == chanamp) {
1444 if (nextchanamp == 0.f) {
1445 ZClear(inNumSamples, out);
1446 } else {
1447 float *in = zin0;
1448 LOOP1(inNumSamples,
1449 ZXP(out) = ZXP(in) * chanamp;
1452 } else {
1453 float chanampslope = CALCSLOPE(nextchanamp, chanamp);
1454 float *in = zin0;
1455 LOOP1(inNumSamples,
1456 ZXP(out) = ZXP(in) * chanamp;
1457 chanamp += chanampslope;
1459 unit->m_chanamp[i] = nextchanamp;
1464 void PanAz_next_aa(PanAz *unit, int inNumSamples)
1466 float level = ZIN0(2);
1467 float width = ZIN0(3);
1468 float orientation = ZIN0(4);
1470 int numOutputs = unit->mNumOutputs;
1471 float rwidth = 1.f / width;
1472 float range = numOutputs * rwidth;
1473 float rrange = 1.f / range;
1476 // compute constant parts with which the pos has to be multiplied/added to respect numOutputs, width and orientation
1477 // see PanAz_next_ak for details
1478 float alignedPosFac = 0.5f * numOutputs;
1479 float alignedPosConst = width * 0.5f + orientation;
1482 float *zin0 = ZIN(0);
1483 float *pos = ZIN(1);
1485 for (int i=0; i<numOutputs; ++i) {
1486 float *out = ZOUT(i);
1488 float *in = zin0;
1489 float *thePos = pos;
1491 LOOP1(inNumSamples,
1492 float chanpos = (ZXP(thePos) * alignedPosFac + alignedPosConst) - i * rwidth;
1493 chanpos = chanpos - range * std::floor(rrange * chanpos);
1495 float chanamp;
1496 if (chanpos > 1.f) {
1497 chanamp = 0.f;
1498 } else {
1499 chanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1502 ZXP(out) = ZXP(in) * chanamp;
1508 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1509 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1511 void Rotate2_next_ak(Rotate2 *unit, int inNumSamples)
1513 float *xout = ZOUT(0);
1514 float *yout = ZOUT(1);
1515 float *xin = ZIN(0);
1516 float *yin = ZIN(1);
1517 float pos = ZIN0(2);
1518 float sint = unit->m_sint;
1519 float cost = unit->m_cost;
1521 if (pos != unit->m_pos) {
1522 int kSineSize = ft->mSineSize;
1523 int kSineMask = kSineSize - 1;
1525 int32 isinpos = kSineMask & (int32)(pos * (float)(kSineSize >> 1));
1526 int32 icospos = kSineMask & ((kSineSize>>2) + isinpos);
1528 float nextsint = unit->m_sint = ft->mSine[isinpos];
1529 float nextcost = unit->m_cost = ft->mSine[icospos];
1531 float slopeFactor = unit->mRate->mSlopeFactor;
1532 float sinslope = (nextsint - sint) * slopeFactor;
1533 float cosslope = (nextcost - cost) * slopeFactor;
1535 LOOP1(inNumSamples,
1536 float x = ZXP(xin);
1537 float y = ZXP(yin);
1538 ZXP(xout) = cost * x + sint * y;
1539 ZXP(yout) = cost * y - sint * x;
1540 sint += sinslope;
1541 cost += cosslope;
1543 unit->m_pos = pos;
1544 } else {
1545 LOOP1(inNumSamples,
1546 float x = ZXP(xin);
1547 float y = ZXP(yin);
1548 ZXP(xout) = cost * x + sint * y;
1549 ZXP(yout) = cost * y - sint * x;
1554 void Rotate2_Ctor(Rotate2 *unit)
1556 SETCALC(Rotate2_next_ak);
1558 unit->m_pos = ZIN0(2);
1559 int32 isinpos = 8191 & (int32)(4096.f * unit->m_pos);
1560 int32 icospos = 8191 & (2048 + isinpos);
1562 unit->m_sint = ft->mSine[isinpos];
1563 unit->m_cost = ft->mSine[icospos];
1565 Rotate2_next_ak(unit, 1);
1568 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1570 void DecodeB2_Ctor(DecodeB2 *unit)
1572 #if defined(NOVA_SIMD)
1573 if (!(BUFLENGTH & 15))
1574 SETCALC(DecodeB2_next_nova);
1575 else
1576 #endif
1577 SETCALC(DecodeB2_next);
1579 DecodeB2_next(unit, 1);
1581 float orientation = ZIN0(3);
1583 int numOutputs = unit->mNumOutputs;
1584 float angle = twopi_f / numOutputs;
1585 unit->m_cosa = cos(angle);
1586 unit->m_sina = sin(angle);
1587 unit->m_W_amp = 0.7071067811865476f;
1588 unit->m_X_amp = 0.5f * (float)cos(orientation * angle);
1589 unit->m_Y_amp = 0.5f * (float)sin(orientation * angle);
1592 void DecodeB2_next(DecodeB2 *unit, int inNumSamples)
1594 float *Win0 = ZIN(0);
1595 float *Xin0 = ZIN(1);
1596 float *Yin0 = ZIN(2);
1598 float W_amp = unit->m_W_amp;
1599 float X_amp = unit->m_X_amp;
1600 float Y_amp = unit->m_Y_amp;
1601 float X_tmp;
1602 float cosa = unit->m_cosa;
1603 float sina = unit->m_sina;
1605 int numOutputs = unit->mNumOutputs;
1606 for (int i=0; i<numOutputs; ++i) {
1607 float *out = ZOUT(i);
1608 float *Win = Win0;
1609 float *Xin = Xin0;
1610 float *Yin = Yin0;
1611 LOOP1(inNumSamples,
1612 ZXP(out) = ZXP(Win) * W_amp + ZXP(Xin) * X_amp + ZXP(Yin) * Y_amp;
1614 X_tmp = X_amp * cosa + Y_amp * sina;
1615 Y_amp = Y_amp * cosa - X_amp * sina;
1616 X_amp = X_tmp;
1620 #ifdef NOVA_SIMD
1621 void DecodeB2_next_nova(DecodeB2 *unit, int inNumSamples)
1623 float *Win0 = IN(0);
1624 float *Xin0 = IN(1);
1625 float *Yin0 = IN(2);
1627 using namespace nova;
1628 vec<float> W_amp = unit->m_W_amp;
1629 vec<float> X_amp = unit->m_X_amp;
1630 vec<float> Y_amp = unit->m_Y_amp;
1631 vec<float> X_tmp;
1632 vec<float> cosa = unit->m_cosa;
1633 vec<float> sina = unit->m_sina;
1635 int numOutputs = unit->mNumOutputs;
1636 int vs = vec<float>::size;
1637 int loops = inNumSamples / vs;
1638 for (int i=0; i<numOutputs; ++i) {
1639 float *out = OUT(i);
1640 float *Win = Win0;
1641 float *Xin = Xin0;
1642 float *Yin = Yin0;
1644 for (int j = 0; j != loops; ++j) {
1645 vec<float> result, w, x, y;
1646 w.load_aligned(Win); x.load_aligned(Xin); y.load_aligned(Yin);
1647 result = w * W_amp + x * X_amp + y * Y_amp;
1648 result.store_aligned(out);
1649 out += vs; Win += vs; Xin += vs; Yin += vs;
1652 X_tmp = X_amp * cosa + Y_amp * sina;
1653 Y_amp = Y_amp * cosa - X_amp * sina;
1654 X_amp = X_tmp;
1657 #endif
1660 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1661 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1663 PluginLoad(Pan)
1665 ft = inTable;
1667 DefineSimpleUnit(Pan2);
1668 DefineSimpleUnit(Pan4);
1669 DefineSimpleUnit(LinPan2);
1670 DefineSimpleUnit(Balance2);
1671 DefineSimpleUnit(Rotate2);
1672 DefineSimpleUnit(XFade2);
1673 DefineSimpleUnit(LinXFade2);
1674 DefineSimpleUnit(PanB);
1675 DefineSimpleUnit(PanB2);
1676 DefineSimpleUnit(BiPanB2);
1677 DefineDtorCantAliasUnit(PanAz);
1678 DefineSimpleCantAliasUnit(DecodeB2);
1681 //////////////////////////////////////////////////////////////////////////////////////////////////