FFT: Prevent user from attempting hops smaller than SC's block size
[supercollider.git] / server / plugins / PanUGens.cpp
blob54425e4622b3f89d68a852e3231794c48b453aa1
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 #include "function_attributes.h"
32 #endif
34 using namespace std; // for math functions
36 static InterfaceTable *ft;
38 struct LinPan2 : public Unit
40 float m_pos, m_level, m_leftamp, m_rightamp;
43 struct Balance2 : public Unit
45 float m_pos, m_level, m_leftamp, m_rightamp;
48 struct Rotate2 : public Unit
50 float m_pos, m_sint, m_cost;
53 struct XFade2 : public Unit
55 float m_pos, m_level, m_leftamp, m_rightamp;
58 struct LinXFade2 : public Unit
60 float m_pos, m_amp;
63 struct Pan2 : public Unit
65 float m_pos, m_level, m_leftamp, m_rightamp;
68 struct Pan4 : public Unit
70 float m_xpos, m_ypos, m_level, m_LF_amp, m_RF_amp, m_LB_amp, m_RB_amp;
73 struct PanB : public Unit
75 float m_azimuth, m_elevation, m_level, m_W_amp, m_X_amp, m_Y_amp, m_Z_amp;
78 struct PanB2 : public Unit
80 float m_azimuth, m_level, m_W_amp, m_X_amp, m_Y_amp;
83 struct BiPanB2 : public Unit
85 float m_azimuth, m_level, m_W_amp, m_X_amp, m_Y_amp;
88 struct PanAz : public Unit
90 float * m_chanamp;
93 struct DecodeB2 : public Unit
95 float m_cosa, m_sina;
96 float m_W_amp, m_X_amp, m_Y_amp;
99 //////////////////////////////////////////////////////////////////////////////////////////////////
101 extern "C"
103 void LinPan2_next_ak(LinPan2 *unit, int inNumSamples);
104 void LinPan2_next_aa(LinPan2 *unit, int inNumSamples);
105 void LinPan2_Ctor(LinPan2* unit);
107 void Balance2_next_ak(Balance2 *unit, int inNumSamples);
108 #ifdef NOVA_SIMD
109 FLATTEN void Balance2_next_ak_nova(Balance2 *unit, int inNumSamples);
110 FLATTEN void Balance2_next_ak_nova_64(Balance2 *unit, int inNumSamples);
111 #endif
112 void Balance2_next_aa(Balance2 *unit, int inNumSamples);
113 void Balance2_Ctor(Balance2* unit);
115 void XFade2_next_ak(XFade2 *unit, int inNumSamples);
116 void XFade2_next_aa(XFade2 *unit, int inNumSamples);
117 void XFade2_Ctor(XFade2* unit);
119 void LinXFade2_next_k(LinXFade2 *unit, int inNumSamples);
120 void LinXFade2_next_a(LinXFade2 *unit, int inNumSamples);
121 void LinXFade2_Ctor(LinXFade2* unit);
123 void Pan2_next_ak(Pan2 *unit, int inNumSamples);
124 void vPan2_next_ak(Pan2 *unit, int inNumSamples);
125 void Pan2_next_aa(Pan2 *unit, int inNumSamples);
126 void Pan2_Ctor(Pan2* unit);
128 void Pan4_next(Pan4 *unit, int inNumSamples);
129 void Pan4_Ctor(Pan4* unit);
131 void PanB_next(PanB *unit, int inNumSamples);
132 void PanB_Ctor(PanB* unit);
134 void PanB2_next(PanB2 *unit, int inNumSamples);
135 void PanB2_Ctor(PanB2* unit);
137 void BiPanB2_next(BiPanB2 *unit, int inNumSamples);
138 void BiPanB2_Ctor(BiPanB2* unit);
140 void DecodeB2_next(DecodeB2 *unit, int inNumSamples);
141 void DecodeB2_next_nova(DecodeB2 *unit, int inNumSamples);
142 void vDecodeB2_next(DecodeB2 *unit, int inNumSamples);
143 void DecodeB2_Ctor(DecodeB2* unit);
145 void PanAz_next_ak(PanAz *unit, int inNumSamples);
146 void PanAz_next_aa(PanAz *unit, int inNumSamples);
147 void PanAz_Ctor(PanAz* unit);
149 void Rotate2_next_ak(Rotate2 *unit, int inNumSamples);
150 void Rotate2_Ctor(Rotate2 *unit);
153 //////////////////////////////////////////////////////////////////////////////////////////////////
155 #ifdef NOVA_SIMD
156 FLATTEN void LinPan2_next_ak_nova(LinPan2 *unit, int inNumSamples);
157 FLATTEN void LinPan2_next_ak_nova_64(LinPan2 *unit, int inNumSamples);
158 #endif
160 void LinPan2_Ctor(LinPan2 *unit)
162 if (INRATE(1) == calc_FullRate) {
163 SETCALC(LinPan2_next_aa);
164 } else {
165 #ifdef NOVA_SIMD
166 if (BUFLENGTH == 64)
167 SETCALC(LinPan2_next_ak_nova_64);
168 if (!(BUFLENGTH & 15))
169 SETCALC(LinPan2_next_ak_nova);
170 else
171 #endif
172 SETCALC(LinPan2_next_ak);
174 // Now we need to initialise some values, which on the first _next run will be "previous"
175 float pan = ZIN0(1) * 0.5f + 0.5f;
176 unit->m_level = ZIN0(2);
177 unit->m_rightamp = unit->m_level * pan;
178 unit->m_leftamp = unit->m_level - unit->m_rightamp;
180 LinPan2_next_aa(unit, 1);
183 void LinPan2_next_ak(LinPan2 *unit, int inNumSamples)
185 float *leftout = ZOUT(0);
186 float *rightout = ZOUT(1);
187 float *in = ZIN(0);
188 float pos = ZIN0(1);
189 float level = ZIN0(2);
190 float leftamp = unit->m_leftamp;
191 float rightamp = unit->m_rightamp;
193 if (pos != unit->m_pos || unit->m_level != level) {
194 float pan = pos * 0.5f + 0.5f;
195 float nextrightamp = level * pan;
196 float nextleftamp = level - nextrightamp;
198 float slopeFactor = unit->mRate->mSlopeFactor;
199 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
200 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
202 LOOP1(inNumSamples,
203 float zin = ZXP(in);
204 ZXP(leftout) = zin * leftamp;
205 ZXP(rightout) = zin * rightamp;
206 leftamp += leftampslope;
207 rightamp += rightampslope;
209 unit->m_pos = pos;
210 unit->m_level = level;
211 unit->m_leftamp = nextleftamp;
212 unit->m_rightamp = nextrightamp;
213 } else {
214 LOOP1(inNumSamples,
215 float zin = ZXP(in);
216 ZXP(leftout) = zin * leftamp;
217 ZXP(rightout) = zin * rightamp;
222 #ifdef NOVA_SIMD
223 void LinPan2_next_ak_nova(LinPan2 *unit, int inNumSamples)
225 float pos = ZIN0(1);
226 float level = ZIN0(2);
227 float leftamp = unit->m_leftamp;
228 float rightamp = unit->m_rightamp;
230 if (pos != unit->m_pos || unit->m_level != level) {
231 float pan = pos * 0.5f + 0.5f;
232 float nextrightamp = level * pan;
233 float nextleftamp = level - nextrightamp;
235 float slopeFactor = unit->mRate->mSlopeFactor;
236 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
237 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
239 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
240 rightamp, rightampslope, inNumSamples);
241 unit->m_pos = pos;
242 unit->m_level = level;
243 unit->m_leftamp = nextleftamp;
244 unit->m_rightamp = nextrightamp;
245 } else
246 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, rightamp, inNumSamples);
249 void LinPan2_next_ak_nova_64(LinPan2 *unit, int inNumSamples)
251 float pos = ZIN0(1);
252 float level = ZIN0(2);
253 float leftamp = unit->m_leftamp;
254 float rightamp = unit->m_rightamp;
256 if (pos != unit->m_pos || unit->m_level != level) {
257 float pan = pos * 0.5f + 0.5f;
258 float nextrightamp = level * pan;
259 float nextleftamp = level - nextrightamp;
261 float slopeFactor = unit->mRate->mSlopeFactor;
262 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
263 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
265 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
266 rightamp, rightampslope);
267 unit->m_pos = pos;
268 unit->m_level = level;
269 unit->m_leftamp = nextleftamp;
270 unit->m_rightamp = nextrightamp;
271 } else
272 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, rightamp);
274 #endif
276 void LinPan2_next_aa(LinPan2 *unit, int inNumSamples)
278 float *leftout = ZOUT(0);
279 float *rightout = ZOUT(1);
280 float *in = ZIN(0);
281 float *pos = ZIN(1);
282 float nextlevel = ZIN0(2);
283 float level = unit->m_level;
284 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
286 LOOP1(inNumSamples,
287 float pan = ZXP(pos) * 0.5f + 0.5f;
288 float rightamp = level * pan;
289 float leftamp = level - rightamp;
290 float zin = ZXP(in);
291 ZXP(leftout) = zin * leftamp;
292 ZXP(rightout) = zin * rightamp;
293 level += levelSlope;
295 unit->m_level = level;
299 ////////////////////////////////////////////////////////////////////////////////////////////////////////
301 void Balance2_Ctor(Balance2 *unit)
303 if (INRATE(2) == calc_FullRate) {
304 SETCALC(Balance2_next_aa);
305 } else {
306 #ifdef NOVA_SIMD
307 if (BUFLENGTH == 64)
308 SETCALC(Balance2_next_ak_nova_64);
309 else if (!(BUFLENGTH & 15))
310 SETCALC(Balance2_next_ak_nova);
311 else
312 SETCALC(Balance2_next_ak);
313 #else
314 SETCALC(Balance2_next_ak);
315 #endif
317 unit->m_pos = ZIN0(2);
318 unit->m_level = ZIN0(3);
319 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f + 0.5f);
320 ipos = sc_clip(ipos, 0, 2048);
322 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
323 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
324 Balance2_next_aa(unit, 1);
327 void Balance2_next_ak(Balance2 *unit, int inNumSamples)
329 float *leftout = ZOUT(0);
330 float *rightout = ZOUT(1);
331 float *leftin = ZIN(0);
332 float *rightin = ZIN(1);
333 float pos = ZIN0(2);
334 float level = ZIN0(3);
335 float leftamp = unit->m_leftamp;
336 float rightamp = unit->m_rightamp;
338 if (pos != unit->m_pos || unit->m_level != level) {
339 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
340 ipos = sc_clip(ipos, 0, 2048);
342 float nextleftamp = level * ft->mSine[2048 - ipos];
343 float nextrightamp = level * ft->mSine[ipos];
345 float slopeFactor = unit->mRate->mSlopeFactor;
346 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
347 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
349 LOOP1(inNumSamples,
350 ZXP(leftout) = ZXP(leftin) * leftamp;
351 ZXP(rightout) = ZXP(rightin) * rightamp;
352 leftamp += leftampslope;
353 rightamp += rightampslope;
355 unit->m_pos = pos;
356 unit->m_level = level;
357 unit->m_leftamp = nextleftamp;
358 unit->m_rightamp = nextrightamp;
359 } else {
360 LOOP1(inNumSamples,
361 ZXP(leftout) = ZXP(leftin) * leftamp;
362 ZXP(rightout) = ZXP(rightin) * rightamp;
367 #ifdef NOVA_SIMD
368 void Balance2_next_ak_nova(Balance2 *unit, int inNumSamples)
370 float pos = ZIN0(2);
371 float level = ZIN0(3);
372 float leftamp = unit->m_leftamp;
373 float rightamp = unit->m_rightamp;
375 if (pos != unit->m_pos || unit->m_level != level) {
376 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
377 ipos = sc_clip(ipos, 0, 2048);
379 float nextleftamp = level * ft->mSine[2048 - ipos];
380 float nextrightamp = level * ft->mSine[ipos];
382 float slopeFactor = unit->mRate->mSlopeFactor;
383 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
384 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
386 unit->m_pos = pos;
387 unit->m_level = level;
388 unit->m_leftamp = nextleftamp;
389 unit->m_rightamp = nextrightamp;
391 //nova::times_vec2_ramp_simd(OUT(0), IN(0), leftamp, leftampslope, OUT(1), IN(1), rightamp, rightampslope, inNumSamples);
392 nova::times_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope), inNumSamples);
393 nova::times_vec_simd(OUT(1), IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
394 } else {
395 //nova::times_vec2_simd(OUT(0), IN(0), leftamp, OUT(1), IN(1), rightamp, inNumSamples);
396 nova::times_vec_simd(OUT(0), IN(0), leftamp, inNumSamples);
397 nova::times_vec_simd(OUT(1), IN(1), rightamp, inNumSamples);
401 void Balance2_next_ak_nova_64(Balance2 *unit, int inNumSamples)
403 float pos = ZIN0(2);
404 float level = ZIN0(3);
405 float leftamp = unit->m_leftamp;
406 float rightamp = unit->m_rightamp;
408 if (pos != unit->m_pos || unit->m_level != level) {
409 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
410 ipos = sc_clip(ipos, 0, 2048);
412 float nextleftamp = level * ft->mSine[2048 - ipos];
413 float nextrightamp = level * ft->mSine[ipos];
415 float slopeFactor = unit->mRate->mSlopeFactor;
416 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
417 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
419 unit->m_pos = pos;
420 unit->m_level = level;
421 unit->m_leftamp = nextleftamp;
422 unit->m_rightamp = nextrightamp;
424 //nova::times_vec2_ramp_simd(OUT(0), IN(0), leftamp, leftampslope, OUT(1), IN(1), rightamp, rightampslope, inNumSamples);
425 nova::times_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope), inNumSamples);
426 nova::times_vec_simd(OUT(1), IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
427 } else {
428 //nova::times_vec2_simd(OUT(0), IN(0), leftamp, OUT(1), IN(1), rightamp, inNumSamples);
429 nova::times_vec_simd<64>(OUT(0), IN(0), leftamp);
430 nova::times_vec_simd<64>(OUT(1), IN(1), rightamp);
433 #endif
435 void Balance2_next_aa(Balance2 *unit, int inNumSamples)
437 float *leftout = ZOUT(0);
438 float *rightout = ZOUT(1);
439 float *leftin = ZIN(0);
440 float *rightin = ZIN(1);
441 float *pos = ZIN(2);
442 float nextlevel = ZIN0(3);
443 float level = unit->m_level;
445 float *sineTable = ft->mSine;
446 if (level != nextlevel) {
447 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
448 LOOP1(inNumSamples,
449 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
450 ipos = sc_clip(ipos, 0, 2048);
452 float leftamp = level * sineTable[2048 - ipos];
453 float rightamp = level * sineTable[ipos];
454 ZXP(leftout) = ZXP(leftin) * leftamp;
455 ZXP(rightout) = ZXP(rightin) * rightamp;
456 level += levelSlope;
458 unit->m_level = level;
459 } else {
460 LOOP1(inNumSamples,
461 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
462 ipos = sc_clip(ipos, 0, 2048);
464 float leftamp = level * sineTable[2048 - ipos];
465 float rightamp = level * sineTable[ipos];
466 ZXP(leftout) = ZXP(leftin) * leftamp;
467 ZXP(rightout) = ZXP(rightin) * rightamp;
472 ////////////////////////////////////////////////////////////////////////////////////////////////////////
474 #ifdef NOVA_SIMD
475 FLATTEN void XFade2_next_ak_nova(XFade2 *unit, int inNumSamples);
476 FLATTEN void XFade2_next_ak_nova_64(XFade2 *unit, int inNumSamples);
477 #endif
479 void XFade2_Ctor(XFade2 *unit)
481 if (INRATE(2) == calc_FullRate) {
482 SETCALC(XFade2_next_aa);
483 } else {
484 #ifdef NOVA_SIMD
485 if (BUFLENGTH == 64)
486 SETCALC(XFade2_next_ak_nova_64);
487 if (!(BUFLENGTH & 15))
488 SETCALC(XFade2_next_ak_nova);
489 else
490 #endif
491 SETCALC(XFade2_next_ak);
493 unit->m_pos = ZIN0(2);
494 unit->m_level = ZIN0(3);
495 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f + 0.5f);
496 ipos = sc_clip(ipos, 0, 2048);
498 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
499 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
500 XFade2_next_aa(unit, 1);
503 void XFade2_next_ak(XFade2 *unit, int inNumSamples)
505 float *out = ZOUT(0);
506 float *leftin = ZIN(0);
507 float *rightin = ZIN(1);
508 float pos = ZIN0(2);
509 float level = ZIN0(3);
510 float leftamp = unit->m_leftamp;
511 float rightamp = unit->m_rightamp;
513 if (pos != unit->m_pos || unit->m_level != level) {
514 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
515 ipos = sc_clip(ipos, 0, 2048);
517 float nextleftamp = level * ft->mSine[2048 - ipos];
518 float nextrightamp = level * ft->mSine[ipos];
520 float slopeFactor = unit->mRate->mSlopeFactor;
521 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
522 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
524 LOOP1(inNumSamples,
525 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
526 leftamp += leftampslope;
527 rightamp += rightampslope;
529 unit->m_pos = pos;
530 unit->m_level = level;
531 unit->m_leftamp = nextleftamp;
532 unit->m_rightamp = nextrightamp;
533 } else {
534 LOOP1(inNumSamples,
535 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
540 #ifdef NOVA_SIMD
541 void XFade2_next_ak_nova(XFade2 *unit, int inNumSamples)
543 float pos = ZIN0(2);
544 float level = ZIN0(3);
545 float leftamp = unit->m_leftamp;
546 float rightamp = unit->m_rightamp;
548 if (pos != unit->m_pos || unit->m_level != level) {
549 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
550 ipos = sc_clip(ipos, 0, 2048);
552 float nextleftamp = level * ft->mSine[2048 - ipos];
553 float nextrightamp = level * ft->mSine[ipos];
555 float slopeFactor = unit->mRate->mSlopeFactor;
556 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
557 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
559 nova::mix_vec_simd(OUT(0), IN(0), slope_argument(leftamp, leftampslope),
560 IN(1), slope_argument(rightamp, rightampslope), inNumSamples);
562 unit->m_pos = pos;
563 unit->m_level = level;
564 unit->m_leftamp = nextleftamp;
565 unit->m_rightamp = nextrightamp;
566 } else
567 nova::mix_vec_simd(OUT(0), IN(0), leftamp, IN(1), rightamp, inNumSamples);
570 void XFade2_next_ak_nova_64(XFade2 *unit, int inNumSamples)
572 float pos = ZIN0(2);
573 float level = ZIN0(3);
574 float leftamp = unit->m_leftamp;
575 float rightamp = unit->m_rightamp;
577 if (pos != unit->m_pos || unit->m_level != level) {
578 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
579 ipos = sc_clip(ipos, 0, 2048);
581 float nextleftamp = level * ft->mSine[2048 - ipos];
582 float nextrightamp = level * ft->mSine[ipos];
584 float slopeFactor = unit->mRate->mSlopeFactor;
585 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
586 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
588 nova::mix_vec_simd<64>(OUT(0), IN(0), slope_argument(leftamp, leftampslope),
589 IN(1), slope_argument(rightamp, rightampslope));
591 unit->m_pos = pos;
592 unit->m_level = level;
593 unit->m_leftamp = nextleftamp;
594 unit->m_rightamp = nextrightamp;
595 } else
596 nova::mix_vec_simd<64>(OUT(0), IN(0), leftamp, IN(1), rightamp);
599 #endif
601 void XFade2_next_aa(XFade2 *unit, int inNumSamples)
603 float *out = ZOUT(0);
604 float *leftin = ZIN(0);
605 float *rightin = ZIN(1);
606 float *pos = ZIN(2);
607 float nextlevel = ZIN0(3);
608 float level = unit->m_level;
610 float *sineTable = ft->mSine;
611 if (level != nextlevel) {
612 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
613 LOOP1(inNumSamples,
614 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
615 ipos = sc_clip(ipos, 0, 2048);
617 float leftamp = level * sineTable[2048 - ipos];
618 float rightamp = level * sineTable[ipos];
619 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
620 level += levelSlope;
622 unit->m_level = level;
623 } else {
624 LOOP1(inNumSamples,
625 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
626 ipos = sc_clip(ipos, 0, 2048);
628 float leftamp = level * sineTable[2048 - ipos];
629 float rightamp = level * sineTable[ipos];
630 ZXP(out) = ZXP(leftin) * leftamp + ZXP(rightin) * rightamp;
635 ////////////////////////////////////////////////////////////////////////////////////////////////////////
637 ////////////////////////////////////////////////////////////////////////////////////////////////////////
639 void LinXFade2_Ctor(LinXFade2 *unit)
641 if (INRATE(2) == calc_FullRate) {
642 SETCALC(LinXFade2_next_a);
643 } else {
644 SETCALC(LinXFade2_next_k);
646 unit->m_pos = ZIN0(2);
647 unit->m_pos = sc_clip(unit->m_pos, -1.f, 1.f);
648 unit->m_amp = unit->m_pos * 0.5f + 0.5f;
650 LinXFade2_next_a(unit, 1);
653 void LinXFade2_next_k(LinXFade2 *unit, int inNumSamples)
655 float *out = ZOUT(0);
656 float *leftin = ZIN(0);
657 float *rightin = ZIN(1);
658 float pos = ZIN0(2);
659 float amp = unit->m_amp;
661 if (pos != unit->m_pos) {
662 pos = sc_clip(pos, -1.f, 1.f);
664 float nextamp = pos * 0.5f + 0.5f;
665 float amp_slope = (nextamp - amp) * unit->mRate->mSlopeFactor;
667 LOOP1(inNumSamples,
668 float l = ZXP(leftin);
669 float r = ZXP(rightin);
670 ZXP(out) = l + amp * (r - l);
671 amp += amp_slope;
673 unit->m_pos = pos;
674 unit->m_amp = amp;
675 } else {
676 LOOP1(inNumSamples,
677 float l = ZXP(leftin);
678 float r = ZXP(rightin);
679 ZXP(out) = l + amp * (r - l);
684 void LinXFade2_next_a(LinXFade2 *unit, int inNumSamples)
686 float *out = ZOUT(0);
687 float *leftin = ZIN(0);
688 float *rightin = ZIN(1);
689 float *posp = ZIN(2);
691 LOOP1(inNumSamples,
692 float pos = ZXP(posp);
693 pos = sc_clip(pos, -1.f, 1.f);
694 float amp = pos * 0.5f + 0.5f;
695 float l = ZXP(leftin);
696 float r = ZXP(rightin);
697 ZXP(out) = l + amp * (r - l);
701 ////////////////////////////////////////////////////////////////////////////////////////////////////////
703 void Pan2_next_ak(Pan2 *unit, int inNumSamples)
705 float *leftout = ZOUT(0);
706 float *rightout = ZOUT(1);
707 float *in = ZIN(0);
708 float pos = ZIN0(1);
709 float level = ZIN0(2);
710 float leftamp = unit->m_leftamp;
711 float rightamp = unit->m_rightamp;
713 if (pos != unit->m_pos || unit->m_level != level) {
714 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
715 ipos = sc_clip(ipos, 0, 2048);
717 float nextleftamp = level * ft->mSine[2048 - ipos];
718 float nextrightamp = level * ft->mSine[ipos];
720 float slopeFactor = unit->mRate->mSlopeFactor;
721 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
722 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
724 LOOP1(inNumSamples,
725 float zin = ZXP(in);
726 ZXP(leftout) = zin * leftamp;
727 ZXP(rightout) = zin * rightamp;
728 leftamp += leftampslope;
729 rightamp += rightampslope;
731 unit->m_pos = pos;
732 unit->m_level = level;
733 unit->m_leftamp = nextleftamp;
734 unit->m_rightamp = nextrightamp;
735 } else {
736 LOOP1(inNumSamples,
737 float zin = ZXP(in);
738 ZXP(leftout) = zin * leftamp;
739 ZXP(rightout) = zin * rightamp;
744 #ifdef NOVA_SIMD
745 void Pan2_next_ak_nova(Pan2 *unit, int inNumSamples)
747 float pos = ZIN0(1);
748 float level = ZIN0(2);
749 float leftamp = unit->m_leftamp;
750 float rightamp = unit->m_rightamp;
752 if (pos != unit->m_pos || unit->m_level != level) {
753 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
754 ipos = sc_clip(ipos, 0, 2048);
756 float nextleftamp = level * ft->mSine[2048 - ipos];
757 float nextrightamp = level * ft->mSine[ipos];
759 float slopeFactor = unit->mRate->mSlopeFactor;
760 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
761 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
763 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
764 rightamp, rightampslope, inNumSamples);
766 unit->m_pos = pos;
767 unit->m_level = level;
768 unit->m_leftamp = nextleftamp;
769 unit->m_rightamp = nextrightamp;
770 } else
771 nova::pan2_vec_simd(OUT(0), OUT(1), IN(0), leftamp, rightamp, inNumSamples);
774 void Pan2_next_ak_nova_64(Pan2 *unit, int inNumSamples)
776 float pos = ZIN0(1);
777 float level = ZIN0(2);
778 float leftamp = unit->m_leftamp;
779 float rightamp = unit->m_rightamp;
781 if (pos != unit->m_pos || unit->m_level != level) {
782 int32 ipos = (int32)(1024.f * pos + 1024.f + 0.5f);
783 ipos = sc_clip(ipos, 0, 2048);
785 float nextleftamp = level * ft->mSine[2048 - ipos];
786 float nextrightamp = level * ft->mSine[ipos];
788 float slopeFactor = unit->mRate->mSlopeFactor;
789 float leftampslope = (nextleftamp - leftamp) * slopeFactor;
790 float rightampslope = (nextrightamp - rightamp) * slopeFactor;
792 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, leftampslope,
793 rightamp, rightampslope);
795 unit->m_pos = pos;
796 unit->m_level = level;
797 unit->m_leftamp = nextleftamp;
798 unit->m_rightamp = nextrightamp;
799 } else
800 nova::pan2_vec_simd<64>(OUT(0), OUT(1), IN(0), leftamp, rightamp);
803 #endif
806 void Pan2_next_aa(Pan2 *unit, int inNumSamples)
808 float *leftout = ZOUT(0);
809 float *rightout = ZOUT(1);
810 float *in = ZIN(0);
811 float *pos = ZIN(1);
812 float nextlevel = ZIN0(2);
813 float level = unit->m_level;
815 if (level != nextlevel) {
816 float levelSlope = (nextlevel - level) * unit->mRate->mSlopeFactor;
818 LOOP1(inNumSamples,
819 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
820 ipos = sc_clip(ipos, 0, 2048);
822 float leftamp = level * ft->mSine[2048 - ipos];
823 float rightamp = level * ft->mSine[ipos];
824 float zin = ZXP(in);
825 ZXP(leftout) = zin * leftamp;
826 ZXP(rightout) = zin * rightamp;
827 level += levelSlope;
829 unit->m_level = level;
830 } else {
831 LOOP1(inNumSamples,
832 int32 ipos = (int32)(1024.f * ZXP(pos) + 1024.f + 0.5f);
833 ipos = sc_clip(ipos, 0, 2048);
835 float leftamp = level * ft->mSine[2048 - ipos];
836 float rightamp = level * ft->mSine[ipos];
837 float zin = ZXP(in);
838 ZXP(leftout) = zin * leftamp;
839 ZXP(rightout) = zin * rightamp;
844 void Pan2_Ctor(Pan2 *unit)
846 if (INRATE(1) == calc_FullRate) {
847 SETCALC(Pan2_next_aa);
848 } else {
849 #if defined(NOVA_SIMD)
850 if (BUFLENGTH == 64)
851 SETCALC(Pan2_next_ak_nova_64);
852 if (!(BUFLENGTH & 15))
853 SETCALC(Pan2_next_ak_nova);
854 else
855 SETCALC(Pan2_next_ak);
856 #else
857 SETCALC(Pan2_next_ak);
858 #endif
861 unit->m_pos = ZIN0(1);
862 unit->m_level = ZIN0(2);
863 int32 ipos = (int32)(1024.f * unit->m_pos + 1024.f + 0.5f);
864 ipos = sc_clip(ipos, 0, 2048);
866 unit->m_leftamp = unit->m_level * ft->mSine[2048 - ipos];
867 unit->m_rightamp = unit->m_level * ft->mSine[ipos];
868 Pan2_next_aa(unit, 1);
871 ////////////////////////////////////////////////////////////////////////////////////////////////////////
873 void Pan4_Ctor(Pan4 *unit)
875 SETCALC(Pan4_next);
876 //float *in = ZIN(0);
877 float xpos = ZIN0(1);
878 float ypos = ZIN0(2);
879 float level = ZIN0(3);
881 unit->m_xpos = xpos;
882 unit->m_ypos = ypos;
883 unit->m_level = level;
884 if (xpos < -1.f || xpos > 1.f || ypos < -1.f || ypos > 1.f) {
885 float xabs = fabs(xpos);
887 if (ypos > xabs) {
888 xpos = (xpos + ypos) / ypos - 1.f;
889 ypos = 1.f;
890 } else if (ypos < -xabs) {
891 xpos = (xpos - ypos) / -ypos - 1.f;
892 ypos = -1.f;
893 } else {
894 float yabs = fabs(ypos);
895 if (yabs < xpos) {
896 ypos = (ypos + xpos) / xpos - 1.f;
897 xpos = 1.f;
898 } else {
899 ypos = (ypos - xpos) / -xpos - 1.f;
900 xpos = -1.f;
905 int32 ixpos = (int32)(1024.f * xpos + 1024.f + 0.5f);
906 ixpos = sc_clip(ixpos, 0, 2048);
907 float leftamp = ft->mSine[2048 - ixpos];
908 float rightamp = ft->mSine[ixpos];
910 int32 iypos = (int32)(1024.f * ypos + 1024.f + 0.5f);
911 iypos = sc_clip(iypos, 0, 2048);
912 float frontamp = ft->mSine[iypos];
913 float backamp = ft->mSine[2048 - iypos];
915 frontamp *= level;
916 backamp *= level;
918 unit->m_LF_amp = leftamp * frontamp;
919 unit->m_RF_amp = rightamp * frontamp;
920 unit->m_LB_amp = leftamp * backamp;
921 unit->m_RB_amp = rightamp * backamp;
923 float z = ZIN0(0);
924 ZOUT0(0) = z * unit->m_LF_amp;
925 ZOUT0(1) = z * unit->m_RF_amp;
926 ZOUT0(2) = z * unit->m_LB_amp;
927 ZOUT0(3) = z * unit->m_RB_amp;
930 void Pan4_next(Pan4 *unit, int inNumSamples)
932 float *LFout = ZOUT(0);
933 float *RFout = ZOUT(1);
934 float *LBout = ZOUT(2);
935 float *RBout = ZOUT(3);
937 float *in = ZIN(0);
938 float xpos = ZIN0(1);
939 float ypos = ZIN0(2);
940 float level = ZIN0(3);
942 float LF_amp = unit->m_LF_amp;
943 float RF_amp = unit->m_RF_amp;
944 float LB_amp = unit->m_LB_amp;
945 float RB_amp = unit->m_RB_amp;
947 if (xpos != unit->m_xpos || ypos != unit->m_ypos || level != unit->m_level) {
948 unit->m_xpos = xpos;
949 unit->m_ypos = ypos;
950 unit->m_level = level;
951 if (xpos < -1.f || xpos > 1.f || ypos < -1.f || ypos > 1.f) {
952 float xabs = fabs(xpos);
954 if (ypos > xabs) {
955 xpos = (xpos + ypos) / ypos - 1.f;
956 ypos = 1.f;
957 } else if (ypos < -xabs) {
958 xpos = (xpos - ypos) / -ypos - 1.f;
959 ypos = -1.f;
960 } else {
961 float yabs = fabs(ypos);
962 if (yabs < xpos) {
963 ypos = (ypos + xpos) / xpos - 1.f;
964 xpos = 1.f;
965 } else {
966 ypos = (ypos - xpos) / -xpos - 1.f;
967 xpos = -1.f;
972 int32 ixpos = (int32)(1024.f * xpos + 1024.f + 0.5f);
973 ixpos = sc_clip(ixpos, 0, 2048);
974 float leftamp = ft->mSine[2048 - ixpos];
975 float rightamp = ft->mSine[ixpos];
977 int32 iypos = (int32)(1024.f * ypos + 1024.f + 0.5f);
978 iypos = sc_clip(iypos, 0, 2048);
979 float frontamp = ft->mSine[iypos];
980 float backamp = ft->mSine[2048 - iypos];
982 frontamp *= level;
983 backamp *= level;
985 float next_LF_amp = leftamp * frontamp;
986 float next_RF_amp = rightamp * frontamp;
987 float next_LB_amp = leftamp * backamp;
988 float next_RB_amp = rightamp * backamp;
990 float LF_slope = CALCSLOPE(next_LF_amp, LF_amp);
991 float RF_slope = CALCSLOPE(next_RF_amp, RF_amp);
992 float LB_slope = CALCSLOPE(next_LB_amp, LB_amp);
993 float RB_slope = CALCSLOPE(next_RB_amp, RB_amp);
995 LOOP1(inNumSamples,
996 float z = ZXP(in);
997 ZXP(LFout) = z * LF_amp;
998 ZXP(RFout) = z * RF_amp;
999 ZXP(LBout) = z * LB_amp;
1000 ZXP(RBout) = z * RB_amp;
1001 LF_amp += LF_slope;
1002 RF_amp += RF_slope;
1003 LB_amp += LB_slope;
1004 RB_amp += RB_slope;
1006 unit->m_LF_amp = LF_amp;
1007 unit->m_RF_amp = RF_amp;
1008 unit->m_LB_amp = LB_amp;
1009 unit->m_RB_amp = RB_amp;
1010 } else {
1011 LOOP1(inNumSamples,
1012 float z = ZXP(in);
1013 ZXP(LFout) = z * LF_amp;
1014 ZXP(RFout) = z * RF_amp;
1015 ZXP(LBout) = z * LB_amp;
1016 ZXP(RBout) = z * RB_amp;
1021 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1023 void PanB_Ctor(PanB *unit)
1025 SETCALC(PanB_next);
1026 float azimuth = unit->m_azimuth = ZIN0(1);
1027 float elevation = unit->m_elevation = ZIN0(2);
1028 float level = unit->m_level = ZIN0(3);
1030 int kSineSize = ft->mSineSize;
1031 int kSineMask = kSineSize - 1;
1033 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1034 long ielevation = kSineMask & (long)(elevation * (float)(kSineSize >> 2));
1035 float sina = -ft->mSine[iazimuth];
1036 float sinb = ft->mSine[ielevation];
1038 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1039 ielevation = kSineMask & (ielevation + (kSineSize>>2));
1040 float cosa = ft->mSine[iazimuth];
1041 float cosb = ft->mSine[ielevation];
1043 unit->m_W_amp = rsqrt2_f * level;
1044 unit->m_X_amp = cosa * cosb * level;
1045 unit->m_Y_amp = sina * cosb * level;
1046 unit->m_Z_amp = sinb * level;
1048 PanB_next(unit, 1);
1051 void PanB_next(PanB *unit, int inNumSamples)
1053 float *Wout = ZOUT(0);
1054 float *Xout = ZOUT(1);
1055 float *Yout = ZOUT(2);
1056 float *Zout = ZOUT(3);
1058 float *in = ZIN(0);
1059 float azimuth = ZIN0(1);
1060 float elevation = ZIN0(2);
1061 float level = ZIN0(3);
1063 float W_amp = unit->m_W_amp;
1064 float X_amp = unit->m_X_amp;
1065 float Y_amp = unit->m_Y_amp;
1066 float Z_amp = unit->m_Z_amp;
1068 int kSineSize = ft->mSineSize;
1069 int kSineMask = kSineSize - 1;
1070 if (azimuth != unit->m_azimuth || elevation != unit->m_elevation || level != unit->m_level) {
1071 unit->m_azimuth = azimuth;
1072 unit->m_elevation = elevation;
1073 unit->m_level = level;
1075 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1076 long ielevation = kSineMask & (long)(elevation * (float)(kSineSize >> 2));
1077 float sina = -ft->mSine[iazimuth];
1078 float sinb = ft->mSine[ielevation];
1080 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1081 ielevation = kSineMask & (ielevation + (kSineSize>>2));
1082 float cosa = ft->mSine[iazimuth];
1083 float cosb = ft->mSine[ielevation];
1085 float next_W_amp = rsqrt2_f * level;
1086 float next_X_amp = cosa * cosb * level;
1087 float next_Y_amp = sina * cosb * level;
1088 float next_Z_amp = sinb * level;
1090 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1091 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1092 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1093 float Z_slope = CALCSLOPE(next_Z_amp, Z_amp);
1095 LOOP1(inNumSamples,
1096 float z = ZXP(in);
1097 ZXP(Wout) = z * W_amp;
1098 ZXP(Xout) = z * X_amp;
1099 ZXP(Yout) = z * Y_amp;
1100 ZXP(Zout) = z * Z_amp;
1101 W_amp += W_slope;
1102 X_amp += X_slope;
1103 Y_amp += Y_slope;
1104 Z_amp += Z_slope;
1106 unit->m_W_amp = W_amp;
1107 unit->m_X_amp = X_amp;
1108 unit->m_Y_amp = Y_amp;
1109 unit->m_Z_amp = Z_amp;
1110 } else {
1111 LOOP1(inNumSamples,
1112 float z = ZXP(in);
1113 ZXP(Wout) = z * W_amp;
1114 ZXP(Xout) = z * X_amp;
1115 ZXP(Yout) = z * Y_amp;
1116 ZXP(Zout) = z * Z_amp;
1121 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1123 void PanB2_next(PanB2 *unit, int inNumSamples)
1125 float *Wout = ZOUT(0);
1126 float *Xout = ZOUT(1);
1127 float *Yout = ZOUT(2);
1129 float *in = ZIN(0);
1130 float azimuth = ZIN0(1);
1131 float level = ZIN0(2);
1133 float W_amp = unit->m_W_amp;
1134 float X_amp = unit->m_X_amp;
1135 float Y_amp = unit->m_Y_amp;
1137 int kSineSize = ft->mSineSize;
1138 int kSineMask = kSineSize - 1;
1139 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1140 unit->m_azimuth = azimuth;
1141 unit->m_level = level;
1143 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1144 float sina = -ft->mSine[isinpos];
1146 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1147 float cosa = ft->mSine[icospos];
1149 float next_W_amp = rsqrt2_f * level;
1150 float next_X_amp = cosa * level;
1151 float next_Y_amp = sina * level;
1153 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1154 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1155 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1157 LOOP1(inNumSamples,
1158 float z = ZXP(in);
1159 ZXP(Wout) = z * W_amp;
1160 ZXP(Xout) = z * X_amp;
1161 ZXP(Yout) = z * Y_amp;
1162 W_amp += W_slope;
1163 X_amp += X_slope;
1164 Y_amp += Y_slope;
1166 unit->m_W_amp = W_amp;
1167 unit->m_X_amp = X_amp;
1168 unit->m_Y_amp = Y_amp;
1169 } else {
1170 LOOP1(inNumSamples,
1171 float z = ZXP(in);
1172 ZXP(Wout) = z * W_amp;
1173 ZXP(Xout) = z * X_amp;
1174 ZXP(Yout) = z * Y_amp;
1179 #ifdef NOVA_SIMD
1181 void PanB2_next_nova(PanB2 *unit, int inNumSamples)
1183 float *Wout = OUT(0);
1184 float *Xout = OUT(1);
1185 float *Yout = OUT(2);
1187 float *in = IN(0);
1188 float azimuth = ZIN0(1);
1189 float level = ZIN0(2);
1191 float W_amp = unit->m_W_amp;
1192 float X_amp = unit->m_X_amp;
1193 float Y_amp = unit->m_Y_amp;
1195 int kSineSize = ft->mSineSize;
1196 int kSineMask = kSineSize - 1;
1197 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1198 unit->m_azimuth = azimuth;
1199 unit->m_level = level;
1201 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1202 float sina = -ft->mSine[isinpos];
1204 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1205 float cosa = ft->mSine[icospos];
1207 float next_W_amp = rsqrt2_f * level;
1208 float next_X_amp = cosa * level;
1209 float next_Y_amp = sina * level;
1211 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1212 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1213 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1215 nova::times_vec_simd(Wout, in, slope_argument(W_amp, W_slope), inNumSamples);
1216 nova::times_vec_simd(Xout, in, slope_argument(X_amp, X_slope), inNumSamples);
1217 nova::times_vec_simd(Yout, in, slope_argument(Y_amp, Y_slope), inNumSamples);
1219 unit->m_W_amp = next_W_amp;
1220 unit->m_X_amp = next_X_amp;
1221 unit->m_Y_amp = next_Y_amp;
1222 } else {
1223 // TODO: can be further optimized by joining the loops
1224 nova::times_vec_simd(Wout, in, W_amp, inNumSamples);
1225 nova::times_vec_simd(Xout, in, X_amp, inNumSamples);
1226 nova::times_vec_simd(Yout, in, Y_amp, inNumSamples);
1229 #endif
1231 void PanB2_Ctor(PanB2 *unit)
1233 #if defined(NOVA_SIMD)
1234 if (!(BUFLENGTH & 15))
1235 SETCALC(PanB2_next_nova);
1236 else
1237 #endif
1238 SETCALC(PanB2_next);
1240 float azimuth = unit->m_azimuth = ZIN0(1);
1241 float level = unit->m_level = ZIN0(2);
1243 int kSineSize = ft->mSineSize;
1244 int kSineMask = kSineSize - 1;
1246 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1247 float sina = -ft->mSine[isinpos];
1249 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1250 float cosa = ft->mSine[icospos];
1252 unit->m_W_amp = rsqrt2_f * level;
1253 unit->m_X_amp = cosa * level;
1254 unit->m_Y_amp = sina * level;
1256 PanB2_next(unit, 1);
1259 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1261 void BiPanB2_next(BiPanB2 *unit, int inNumSamples)
1263 float *Wout = ZOUT(0);
1264 float *Xout = ZOUT(1);
1265 float *Yout = ZOUT(2);
1267 float *inA = ZIN(0);
1268 float *inB = ZIN(1);
1269 float azimuth = ZIN0(2);
1270 float level = ZIN0(3);
1272 float W_amp = unit->m_W_amp;
1273 float X_amp = unit->m_X_amp;
1274 float Y_amp = unit->m_Y_amp;
1276 int kSineSize = ft->mSineSize;
1277 int kSineMask = kSineSize - 1;
1278 if (azimuth != unit->m_azimuth || level != unit->m_level) {
1279 unit->m_azimuth = azimuth;
1280 unit->m_level = level;
1282 long isinpos = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1283 float sina = -ft->mSine[isinpos];
1285 long icospos = kSineMask & (isinpos + (kSineSize>>2));
1286 float cosa = ft->mSine[icospos];
1288 float next_W_amp = rsqrt2_f * level;
1289 float next_X_amp = cosa * level;
1290 float next_Y_amp = sina * level;
1292 float W_slope = CALCSLOPE(next_W_amp, W_amp);
1293 float X_slope = CALCSLOPE(next_X_amp, X_amp);
1294 float Y_slope = CALCSLOPE(next_Y_amp, Y_amp);
1296 if (W_slope == 0.f) {
1297 LOOP1(inNumSamples,
1298 float a = ZXP(inA);
1299 float b = ZXP(inB);
1300 float abdiff = a - b;
1301 ZXP(Wout) = (a + b) * W_amp;
1302 ZXP(Xout) = abdiff * X_amp;
1303 ZXP(Yout) = abdiff * Y_amp;
1304 X_amp += X_slope;
1305 Y_amp += Y_slope;
1307 } else {
1308 LOOP1(inNumSamples,
1309 float a = ZXP(inA);
1310 float b = ZXP(inB);
1311 float abdiff = a - b;
1312 ZXP(Wout) = (a + b) * W_amp;
1313 ZXP(Xout) = abdiff * X_amp;
1314 ZXP(Yout) = abdiff * Y_amp;
1315 W_amp += W_slope;
1316 X_amp += X_slope;
1317 Y_amp += Y_slope;
1319 unit->m_W_amp = W_amp;
1321 unit->m_X_amp = X_amp;
1322 unit->m_Y_amp = Y_amp;
1323 } else {
1324 LOOP1(inNumSamples,
1325 float a = ZXP(inA);
1326 float b = ZXP(inB);
1327 float abdiff = a - b;
1328 ZXP(Wout) = (a + b) * W_amp;
1329 ZXP(Xout) = abdiff * X_amp;
1330 ZXP(Yout) = abdiff * Y_amp;
1335 void BiPanB2_Ctor(BiPanB2 *unit)
1337 SETCALC(BiPanB2_next);
1339 float azimuth = unit->m_azimuth = ZIN0(2);
1340 float level = unit->m_level = ZIN0(3);
1342 int kSineSize = ft->mSineSize;
1343 int kSineMask = kSineSize - 1;
1345 long iazimuth = kSineMask & (long)(azimuth * (float)(kSineSize >> 1));
1346 float sina = -ft->mSine[iazimuth];
1348 iazimuth = kSineMask & (iazimuth + (kSineSize>>2));
1349 float cosa = ft->mSine[iazimuth];
1351 unit->m_W_amp = rsqrt2_f * level;
1352 unit->m_X_amp = cosa * level;
1353 unit->m_Y_amp = sina * level;
1355 BiPanB2_next(unit, 1);
1358 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1359 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1363 void calcPos(float pos, int numOutputs, float width, float orientation)
1365 float rwidth = 1.f / width;
1366 float range = numOutputs * rwidth;
1367 float rrange = 1.f / range;
1369 float zpos = pos * 0.5 * numOutputs + width * 0.5 + orientation;
1370 Print("pos %6.2g rwidth %6.3g range %6.3g rrange %6.3g zpos %6.3g\n",
1371 pos, rwidth, range, rrange, zpos);
1372 for (int i=0; i<numOutputs; ++i) {
1373 float amp;
1374 float chanpos = zpos - i;
1375 chanpos *= rwidth;
1376 float zchanpos = chanpos - range * floor(rrange * chanpos);
1377 if (zchanpos > 1.f) {
1378 amp = 0.f;
1379 } else {
1380 amp = ft->mSine[(long)(4096.f * zchanpos)];
1382 Print(" %d chanpos %6.3g zchanpos %6.3g amp %g\n",
1383 i, chanpos, zchanpos, amp);
1388 void PanAz_Ctor(PanAz *unit)
1390 if (INRATE(1) == calc_FullRate) {
1391 unit->m_chanamp = NULL;
1392 SETCALC(PanAz_next_aa);
1393 } else {
1394 int numOutputs = unit->mNumOutputs;
1395 unit->m_chanamp = (float*)RTAlloc(unit->mWorld, numOutputs*sizeof(float));
1396 for (int i=0; i<numOutputs; ++i) {
1397 unit->m_chanamp[i] = 0;
1398 ZOUT0(i) = 0.f;
1400 SETCALC(PanAz_next_ak);
1404 void PanAz_Dtor(PanAz *unit)
1406 if (unit->m_chanamp)
1407 RTFree(unit->mWorld, unit->m_chanamp);
1410 void PanAz_next_ak(PanAz *unit, int inNumSamples)
1412 float pos = ZIN0(1);
1413 float level = ZIN0(2);
1414 float width = ZIN0(3);
1415 float orientation = ZIN0(4);
1417 int numOutputs = unit->mNumOutputs;
1418 float rwidth = 1.f / width;
1419 float range = numOutputs * rwidth;
1420 float rrange = 1.f / range;
1422 pos = pos * 0.5f * numOutputs + width * 0.5f + orientation;
1424 float *zin0 = ZIN(0);
1426 for (int i=0; i<numOutputs; ++i) {
1427 float *out = ZOUT(i);
1428 float nextchanamp;
1429 float chanpos = pos - i;
1430 chanpos *= rwidth;
1431 chanpos = chanpos - range * std::floor(rrange * chanpos);
1432 if (chanpos > 1.f) {
1433 nextchanamp = 0.f;
1434 } else {
1435 nextchanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1437 float chanamp = unit->m_chanamp[i];
1439 if (nextchanamp == chanamp) {
1440 if (nextchanamp == 0.f) {
1441 ZClear(inNumSamples, out);
1442 } else {
1443 float *in = zin0;
1444 LOOP1(inNumSamples,
1445 ZXP(out) = ZXP(in) * chanamp;
1448 } else {
1449 float chanampslope = CALCSLOPE(nextchanamp, chanamp);
1450 float *in = zin0;
1451 LOOP1(inNumSamples,
1452 ZXP(out) = ZXP(in) * chanamp;
1453 chanamp += chanampslope;
1455 unit->m_chanamp[i] = nextchanamp;
1460 void PanAz_next_aa(PanAz *unit, int inNumSamples)
1462 float level = ZIN0(2);
1463 float width = ZIN0(3);
1464 float orientation = ZIN0(4);
1466 int numOutputs = unit->mNumOutputs;
1467 float rwidth = 1.f / width;
1468 float range = numOutputs * rwidth;
1469 float rrange = 1.f / range;
1472 // compute constant parts with which the pos has to be multiplied/added to respect numOutputs, width and orientation
1473 // see PanAz_next_ak for details
1474 float alignedPosFac = 0.5f * numOutputs;
1475 float alignedPosConst = width * 0.5f + orientation;
1478 float *zin0 = ZIN(0);
1479 float *pos = ZIN(1);
1481 for (int i=0; i<numOutputs; ++i) {
1482 float *out = ZOUT(i);
1484 float *in = zin0;
1485 float *thePos = pos;
1487 LOOP1(inNumSamples,
1488 float chanpos = (ZXP(thePos) * alignedPosFac + alignedPosConst) - i * rwidth;
1489 chanpos = chanpos - range * std::floor(rrange * chanpos);
1491 float chanamp;
1492 if (chanpos > 1.f) {
1493 chanamp = 0.f;
1494 } else {
1495 chanamp = level * ft->mSine[(long)(4096.f * chanpos)];
1498 ZXP(out) = ZXP(in) * chanamp;
1504 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1505 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1507 void Rotate2_next_ak(Rotate2 *unit, int inNumSamples)
1509 float *xout = ZOUT(0);
1510 float *yout = ZOUT(1);
1511 float *xin = ZIN(0);
1512 float *yin = ZIN(1);
1513 float pos = ZIN0(2);
1514 float sint = unit->m_sint;
1515 float cost = unit->m_cost;
1517 if (pos != unit->m_pos) {
1518 int kSineSize = ft->mSineSize;
1519 int kSineMask = kSineSize - 1;
1521 int32 isinpos = kSineMask & (int32)(pos * (float)(kSineSize >> 1));
1522 int32 icospos = kSineMask & ((kSineSize>>2) + isinpos);
1524 float nextsint = unit->m_sint = ft->mSine[isinpos];
1525 float nextcost = unit->m_cost = ft->mSine[icospos];
1527 float slopeFactor = unit->mRate->mSlopeFactor;
1528 float sinslope = (nextsint - sint) * slopeFactor;
1529 float cosslope = (nextcost - cost) * slopeFactor;
1531 LOOP1(inNumSamples,
1532 float x = ZXP(xin);
1533 float y = ZXP(yin);
1534 ZXP(xout) = cost * x + sint * y;
1535 ZXP(yout) = cost * y - sint * x;
1536 sint += sinslope;
1537 cost += cosslope;
1539 unit->m_pos = pos;
1540 } else {
1541 LOOP1(inNumSamples,
1542 float x = ZXP(xin);
1543 float y = ZXP(yin);
1544 ZXP(xout) = cost * x + sint * y;
1545 ZXP(yout) = cost * y - sint * x;
1550 void Rotate2_Ctor(Rotate2 *unit)
1552 SETCALC(Rotate2_next_ak);
1554 unit->m_pos = ZIN0(2);
1555 int32 isinpos = 8191 & (int32)(4096.f * unit->m_pos);
1556 int32 icospos = 8191 & (2048 + isinpos);
1558 unit->m_sint = ft->mSine[isinpos];
1559 unit->m_cost = ft->mSine[icospos];
1561 Rotate2_next_ak(unit, 1);
1564 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1566 void DecodeB2_Ctor(DecodeB2 *unit)
1568 #if defined(NOVA_SIMD)
1569 if (!(BUFLENGTH & 15))
1570 SETCALC(DecodeB2_next_nova);
1571 else
1572 #endif
1573 SETCALC(DecodeB2_next);
1575 DecodeB2_next(unit, 1);
1577 float orientation = ZIN0(3);
1579 int numOutputs = unit->mNumOutputs;
1580 float angle = twopi_f / numOutputs;
1581 unit->m_cosa = cos(angle);
1582 unit->m_sina = sin(angle);
1583 unit->m_W_amp = 0.7071067811865476f;
1584 unit->m_X_amp = 0.5f * (float)cos(orientation * angle);
1585 unit->m_Y_amp = 0.5f * (float)sin(orientation * angle);
1588 void DecodeB2_next(DecodeB2 *unit, int inNumSamples)
1590 float *Win0 = ZIN(0);
1591 float *Xin0 = ZIN(1);
1592 float *Yin0 = ZIN(2);
1594 float W_amp = unit->m_W_amp;
1595 float X_amp = unit->m_X_amp;
1596 float Y_amp = unit->m_Y_amp;
1597 float X_tmp;
1598 float cosa = unit->m_cosa;
1599 float sina = unit->m_sina;
1601 int numOutputs = unit->mNumOutputs;
1602 for (int i=0; i<numOutputs; ++i) {
1603 float *out = ZOUT(i);
1604 float *Win = Win0;
1605 float *Xin = Xin0;
1606 float *Yin = Yin0;
1607 LOOP1(inNumSamples,
1608 ZXP(out) = ZXP(Win) * W_amp + ZXP(Xin) * X_amp + ZXP(Yin) * Y_amp;
1610 X_tmp = X_amp * cosa + Y_amp * sina;
1611 Y_amp = Y_amp * cosa - X_amp * sina;
1612 X_amp = X_tmp;
1616 #ifdef NOVA_SIMD
1617 void DecodeB2_next_nova(DecodeB2 *unit, int inNumSamples)
1619 float *Win0 = IN(0);
1620 float *Xin0 = IN(1);
1621 float *Yin0 = IN(2);
1623 using namespace nova;
1624 vec<float> W_amp = unit->m_W_amp;
1625 vec<float> X_amp = unit->m_X_amp;
1626 vec<float> Y_amp = unit->m_Y_amp;
1627 vec<float> X_tmp;
1628 vec<float> cosa = unit->m_cosa;
1629 vec<float> sina = unit->m_sina;
1631 int numOutputs = unit->mNumOutputs;
1632 int vs = vec<float>::size;
1633 int loops = inNumSamples / vs;
1634 for (int i=0; i<numOutputs; ++i) {
1635 float *out = OUT(i);
1636 float *Win = Win0;
1637 float *Xin = Xin0;
1638 float *Yin = Yin0;
1640 for (int j = 0; j != loops; ++j) {
1641 vec<float> result, w, x, y;
1642 w.load_aligned(Win); x.load_aligned(Xin); y.load_aligned(Yin);
1643 result = w * W_amp + x * X_amp + y * Y_amp;
1644 result.store_aligned(out);
1645 out += vs; Win += vs; Xin += vs; Yin += vs;
1648 X_tmp = X_amp * cosa + Y_amp * sina;
1649 Y_amp = Y_amp * cosa - X_amp * sina;
1650 X_amp = X_tmp;
1653 #endif
1656 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1657 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1659 PluginLoad(Pan)
1661 ft = inTable;
1663 DefineSimpleUnit(Pan2);
1664 DefineSimpleUnit(Pan4);
1665 DefineSimpleUnit(LinPan2);
1666 DefineSimpleCantAliasUnit(Balance2);
1667 DefineSimpleUnit(Rotate2);
1668 DefineSimpleUnit(XFade2);
1669 DefineSimpleUnit(LinXFade2);
1670 DefineSimpleUnit(PanB);
1671 DefineSimpleCantAliasUnit(PanB2);
1672 DefineSimpleUnit(BiPanB2);
1673 DefineDtorCantAliasUnit(PanAz);
1674 DefineSimpleCantAliasUnit(DecodeB2);
1677 //////////////////////////////////////////////////////////////////////////////////////////////////