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"
29 #include "nova-tt/spin_lock.hpp"
30 #include "nova-tt/rw_spinlock.hpp"
34 #include "simd_memory.hpp"
35 #include "simd_mix.hpp"
36 #include "simd_binary_arithmetic.hpp"
38 #include "function_attributes.h"
39 using nova::slope_argument
;
43 static InterfaceTable
*ft
;
45 //////////////////////////////////////////////////////////////////////////////////////////////////
47 struct IOUnit
: public Unit
54 struct XOut
: public IOUnit
59 struct OffsetOut
: public IOUnit
65 struct AudioControl
: public Unit
67 float *prevVal
; // this will have to be a pointer later!
70 const int kMaxLags
= 16;
72 struct LagControl
: public IOUnit
79 struct LagIn
: public IOUnit
85 struct LocalIn
: public Unit
94 void Control_Ctor(Unit
*inUnit
);
95 void Control_next_k(Unit
*unit
, int inNumSamples
);
96 void Control_next_1(Unit
*unit
, int inNumSamples
);
98 void AudioControl_Ctor(AudioControl
*inUnit
);
99 // void AudioControl_Dtor(AudioControl *inUnit);
100 void AudioControl_next_k(AudioControl
*unit
, int inNumSamples
);
101 void AudioControl_next_1(AudioControl
*unit
, int inNumSamples
);
103 void TrigControl_Ctor(Unit
*inUnit
);
104 void TrigControl_next_k(Unit
*unit
, int inNumSamples
);
105 void TrigControl_next_1(Unit
*unit
, int inNumSamples
);
107 void LagControl_Ctor(LagControl
*inUnit
);
108 void LagControl_next_k(LagControl
*unit
, int inNumSamples
);
109 void LagControl_next_1(LagControl
*unit
, int inNumSamples
);
111 void InTrig_Ctor(IOUnit
*unit
);
112 void InTrig_next_k(IOUnit
*unit
, int inNumSamples
);
114 void In_Ctor(IOUnit
*unit
);
115 void In_next_a(IOUnit
*unit
, int inNumSamples
);
116 void In_next_k(IOUnit
*unit
, int inNumSamples
);
118 void LagIn_Ctor(LagIn
*unit
);
119 void LagIn_next_0(LagIn
*unit
, int inNumSamples
);
120 void LagIn_next_k(LagIn
*unit
, int inNumSamples
);
122 void InFeedback_Ctor(IOUnit
*unit
);
123 void InFeedback_next_a(IOUnit
*unit
, int inNumSamples
);
125 void LocalIn_Ctor(LocalIn
*unit
);
126 void LocalIn_Dtor(LocalIn
*unit
);
127 void LocalIn_next_a(LocalIn
*unit
, int inNumSamples
);
128 void LocalIn_next_k(LocalIn
*unit
, int inNumSamples
);
130 void Out_Ctor(IOUnit
*unit
);
131 void Out_next_a(IOUnit
*unit
, int inNumSamples
);
132 void Out_next_k(IOUnit
*unit
, int inNumSamples
);
134 void XOut_Ctor(XOut
*unit
);
135 void XOut_next_a(XOut
*unit
, int inNumSamples
);
136 void XOut_next_k(XOut
*unit
, int inNumSamples
);
138 void ReplaceOut_Ctor(IOUnit
*unit
);
139 void ReplaceOut_next_a(IOUnit
*unit
, int inNumSamples
);
140 void ReplaceOut_next_k(IOUnit
*unit
, int inNumSamples
);
142 void OffsetOut_Ctor(OffsetOut
*unit
);
143 void OffsetOut_Dtor(OffsetOut
* unit
);
144 void OffsetOut_next_a(OffsetOut
*unit
, int inNumSamples
);
146 void LocalOut_Ctor(IOUnit
*unit
);
147 void LocalOut_next_a(IOUnit
*unit
, int inNumSamples
);
148 void LocalOut_next_k(IOUnit
*unit
, int inNumSamples
);
152 //////////////////////////////////////////////////////////////////////////////////////////////////
154 void Control_next_k(Unit
*unit
, int inNumSamples
)
156 uint32 numChannels
= unit
->mNumOutputs
;
157 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
158 for (uint32 i
=0; i
<numChannels
; ++i
, mapin
++) {
164 void Control_next_1(Unit
*unit
, int inNumSamples
)
166 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
171 void Control_Ctor(Unit
* unit
)
173 if (unit
->mNumOutputs
== 1) {
174 SETCALC(Control_next_1
);
175 Control_next_1(unit
, 1);
177 SETCALC(Control_next_k
);
178 Control_next_k(unit
, 1);
182 //////////////////////////////////////////////////////////////////////////////////////////////////
184 void AudioControl_next_k(AudioControl
*unit
, int inNumSamples
)
186 uint32 numChannels
= unit
->mNumOutputs
;
187 float *prevVal
= unit
->prevVal
;
188 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
189 for(uint32 i
= 0; i
< numChannels
; ++i
, mapin
++){
193 float nextVal
, curVal
, valSlope
;
194 mapRatep
= unit
->mParent
->mControlRates
+ unit
->mSpecialIndex
;
195 mapRate
= mapRatep
[i
];
198 for(int j
= 0; j
< inNumSamples
; j
++){
205 valSlope
= CALCSLOPE(nextVal
, curVal
);
206 for(int j
= 0; j
< inNumSamples
; j
++){
207 out
[j
] = curVal
; // should be prevVal
210 unit
->prevVal
[i
] = curVal
;
212 case 2 : Copy(inNumSamples
, out
, *mapin
);
218 void AudioControl_next_1(AudioControl
*unit
, int inNumSamples
)
220 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
224 float nextVal
, curVal
, valSlope
;
226 prevVal
= unit
->prevVal
;
228 mapRatep
= unit
->mParent
->mControlRates
+ unit
->mSpecialIndex
;
229 mapRate
= mapRatep
[0];
233 for(int i
= 0; i
< inNumSamples
; i
++){
239 valSlope
= CALCSLOPE(nextVal
, curVal
);
240 for(int i
= 0; i
< inNumSamples
; i
++){
244 unit
->prevVal
[0] = curVal
;
247 Copy(inNumSamples
, out
, *mapin
);
253 void AudioControl_Ctor(AudioControl
* unit
)
255 unit
->prevVal
= (float*)RTAlloc(unit
->mWorld
, unit
->mNumOutputs
* sizeof(float));
256 for(int i
= 0; i
< unit
->mNumOutputs
; i
++){
257 unit
->prevVal
[i
] = 0.0;
259 if (unit
->mNumOutputs
== 1) {
260 SETCALC(AudioControl_next_1
);
261 AudioControl_next_1(unit
, 1);
263 SETCALC(AudioControl_next_k
);
264 AudioControl_next_k(unit
, 1);
268 void AudioControl_Dtor(AudioControl
* unit
)
270 RTFree(unit
->mWorld
, unit
->prevVal
);
272 //////////////////////////////////////////////////////////////////////////////////////////////////
273 //////////////////////////////////////////////////////////////////////////////////////////////////
275 void TrigControl_next_k(Unit
*unit
, int inNumSamples
)
277 uint32 numChannels
= unit
->mNumOutputs
;
278 int specialIndex
= unit
->mSpecialIndex
;
279 Graph
*parent
= unit
->mParent
;
280 float **mapin
= parent
->mMapControls
+ specialIndex
;
281 float *control
= parent
->mControls
+ specialIndex
;
282 World
*world
= unit
->mWorld
;
283 float *buses
= world
->mControlBus
;
284 int32
*touched
= world
->mControlBusTouched
;
285 int bufCount
= world
->mBufCounter
;
286 for (uint32 i
=0; i
<numChannels
; ++i
, mapin
++, control
++) {
288 // requires a bit of detective work to see what it has been mapped to.
289 if (*mapin
== control
) {
290 // read local control.
293 // global control bus. look at time stamp.
294 int busindex
= *mapin
- buses
;
295 if (touched
[busindex
] == bufCount
) {
296 *out
= buses
[busindex
];
301 // must zero the control even if mapped - otherwise it triggers on unmap
306 void TrigControl_next_1(Unit
*unit
, int inNumSamples
)
308 int specialIndex
= unit
->mSpecialIndex
;
309 Graph
*parent
= unit
->mParent
;
310 float **mapin
= parent
->mMapControls
+ specialIndex
;
311 float *control
= parent
->mControls
+ specialIndex
;
313 // requires a bit of detective work to see what it has been mapped to.
314 if (*mapin
== control
) {
315 // read local control.
318 // global control bus. look at time stamp.
319 World
*world
= unit
->mWorld
;
320 int busindex
= *mapin
- world
->mControlBus
;
321 if (world
->mControlBusTouched
[busindex
] == world
->mBufCounter
) {
327 // must zero the control even if mapped - otherwise it triggers on unmap
331 void TrigControl_Ctor(Unit
* unit
)
333 //Print("TrigControl_Ctor\n");
334 if (unit
->mNumOutputs
== 1) {
335 SETCALC(TrigControl_next_1
);
337 SETCALC(TrigControl_next_k
);
339 ClearUnitOutputs(unit
, 1);
342 //////////////////////////////////////////////////////////////////////////////////////////////////
344 void LagControl_next_k(LagControl
*unit
, int inNumSamples
)
346 uint32 numChannels
= unit
->mNumOutputs
;
347 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
348 for (uint32 i
=0; i
<numChannels
; ++i
, mapin
++) {
351 float x
= z
+ unit
->m_b1
[i
] * (unit
->m_y1
[i
] - z
);
352 *out
= unit
->m_y1
[i
] = zapgremlins(x
);
356 void LagControl_next_1(LagControl
*unit
, int inNumSamples
)
358 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
361 float x
= z
+ unit
->m_b1
[0] * (unit
->m_y1
[0] - z
);
362 *out
= unit
->m_y1
[0] = zapgremlins(x
);
365 void LagControl_Ctor(LagControl
* unit
)
367 int numChannels
= unit
->mNumInputs
;
368 float **mapin
= unit
->mParent
->mMapControls
+ unit
->mSpecialIndex
;
370 char * chunk
= (char*)RTAlloc(unit
->mWorld
, numChannels
* 2 * sizeof(float));
371 unit
->m_y1
= (float*)chunk
;
372 unit
->m_b1
= unit
->m_y1
+ numChannels
;
374 for (int i
=0; i
<numChannels
; ++i
, mapin
++) {
375 unit
->m_y1
[i
] = **mapin
;
377 unit
->m_b1
[i
] = lag
== 0.f
? 0.f
: (float)exp(log001
/ (lag
* unit
->mRate
->mSampleRate
));
380 if (unit
->mNumOutputs
== 1) {
381 SETCALC(LagControl_next_1
);
382 LagControl_next_1(unit
, 1);
384 SETCALC(LagControl_next_k
);
385 LagControl_next_k(unit
, 1);
389 void LagControl_Dtor(LagControl
* unit
)
391 RTFree(unit
->mWorld
, unit
->m_y1
);
394 //////////////////////////////////////////////////////////////////////////////////////////////////
397 FLATTEN
void In_next_a_nova(IOUnit
*unit
, int inNumSamples
)
399 World
*world
= unit
->mWorld
;
400 int bufLength
= world
->mBufLength
;
401 int numChannels
= unit
->mNumOutputs
;
403 float fbusChannel
= ZIN0(0);
404 if (fbusChannel
!= unit
->m_fbusChannel
) {
405 unit
->m_fbusChannel
= fbusChannel
;
406 int busChannel
= (uint32
)fbusChannel
;
407 int lastChannel
= busChannel
+ numChannels
;
409 if (!(busChannel
< 0 || lastChannel
> (int)world
->mNumAudioBusChannels
)) {
410 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
411 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
415 float *in
= unit
->m_bus
;
416 int32
*touched
= unit
->m_busTouched
;
417 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
419 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
420 ACQUIRE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
422 if (touched
[i
] == bufCounter
)
423 nova::copyvec_simd(out
, in
, inNumSamples
);
425 nova::zerovec_simd(out
, inNumSamples
);
426 RELEASE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
430 FLATTEN
void In_next_a_nova_64(IOUnit
*unit
, int inNumSamples
)
432 World
*world
= unit
->mWorld
;
433 int bufLength
= world
->mBufLength
;
434 int numChannels
= unit
->mNumOutputs
;
436 float fbusChannel
= ZIN0(0);
437 if (fbusChannel
!= unit
->m_fbusChannel
) {
438 unit
->m_fbusChannel
= fbusChannel
;
439 int busChannel
= (uint32
)fbusChannel
;
440 int lastChannel
= busChannel
+ numChannels
;
442 if (!(busChannel
< 0 || lastChannel
> (int)world
->mNumAudioBusChannels
)) {
443 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
444 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
448 float *in
= unit
->m_bus
;
449 int32
*touched
= unit
->m_busTouched
;
450 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
452 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
453 ACQUIRE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
455 if (touched
[i
] == bufCounter
)
456 nova::copyvec_simd
<64>(out
, in
);
458 nova::zerovec_simd
<64>(out
);
459 RELEASE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
465 void In_next_a(IOUnit
*unit
, int inNumSamples
)
467 World
*world
= unit
->mWorld
;
468 int bufLength
= world
->mBufLength
;
469 int numChannels
= unit
->mNumOutputs
;
471 float fbusChannel
= ZIN0(0);
472 if (fbusChannel
!= unit
->m_fbusChannel
) {
473 unit
->m_fbusChannel
= fbusChannel
;
474 uint32 busChannel
= (uint32
)fbusChannel
;
475 uint32 lastChannel
= busChannel
+ numChannels
;
477 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
478 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
479 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
483 float *in
= unit
->m_bus
;
484 int32
*touched
= unit
->m_busTouched
;
485 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
487 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
488 ACQUIRE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
490 if (touched
[i
] == bufCounter
) Copy(inNumSamples
, out
, in
);
491 else Fill(inNumSamples
, out
, 0.f
);
492 RELEASE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
497 void vIn_next_a(IOUnit
*unit
, int inNumSamples
)
499 World
*world
= unit
->mWorld
;
500 int bufLength
= world
->mBufLength
;
501 int numChannels
= unit
->mNumOutputs
;
503 float fbusChannel
= ZIN0(0);
504 if (fbusChannel
!= unit
->m_fbusChannel
) {
505 unit
->m_fbusChannel
= fbusChannel
;
506 int busChannel
= (uint32
)fbusChannel
;
507 int lastChannel
= busChannel
+ numChannels
;
509 if (!(busChannel
< 0 || lastChannel
> (int)world
->mNumAudioBusChannels
)) {
510 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
511 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
515 float *in
= unit
->m_bus
;
516 int32
*touched
= unit
->m_busTouched
;
517 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
519 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
520 ACQUIRE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
522 if (touched
[i
] == bufCounter
)
524 vcopy(out
, in
, inNumSamples
);
528 vfill(out
, 0.f
, inNumSamples
);
530 RELEASE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
535 void In_next_k(IOUnit
*unit
, int inNumSamples
)
537 //Print("->In_next_k\n");
538 World
*world
= unit
->mWorld
;
539 uint32 numChannels
= unit
->mNumOutputs
;
541 float fbusChannel
= ZIN0(0);
542 if (fbusChannel
!= unit
->m_fbusChannel
) {
543 unit
->m_fbusChannel
= fbusChannel
;
544 uint32 busChannel
= (uint32
)fbusChannel
;
545 uint32 lastChannel
= busChannel
+ numChannels
;
547 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
548 unit
->m_bus
= world
->mControlBus
+ busChannel
;
552 float *in
= unit
->m_bus
;
553 for (uint32 i
=0; i
<numChannels
; ++i
, in
++) {
557 //Print("<-In_next_k\n");
560 void In_Ctor(IOUnit
* unit
)
562 //Print("->In_Ctor\n");
563 World
*world
= unit
->mWorld
;
564 unit
->m_fbusChannel
= -1.;
566 if (unit
->mCalcRate
== calc_FullRate
) {
569 SETCALC(In_next_a_nova_64
);
570 else if (!(BUFLENGTH
& 15))
571 SETCALC(In_next_a_nova
);
575 unit
->m_bus
= world
->mAudioBus
;
576 unit
->m_busTouched
= world
->mAudioBusTouched
;
578 // vIn_next_a(unit, 1);
584 unit
->m_bus
= world
->mControlBus
;
585 //unit->m_busTouched = world->mControlBusTouched;
588 //Print("<-In_Ctor\n");
591 //////////////////////////////////////////////////////////////////////////////////////////////////
592 //////////////////////////////////////////////////////////////////////////////////////////////////
594 void LagIn_next_k(LagIn
*unit
, int inNumSamples
)
596 //Print("->LagIn_next_k\n");
597 World
*world
= unit
->mWorld
;
598 int numChannels
= unit
->mNumOutputs
;
600 float fbusChannel
= ZIN0(0);
601 if (fbusChannel
!= unit
->m_fbusChannel
) {
602 unit
->m_fbusChannel
= fbusChannel
;
603 uint32 busChannel
= (uint32
)fbusChannel
;
604 uint32 lastChannel
= busChannel
+ numChannels
;
606 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
607 unit
->m_bus
= world
->mControlBus
+ busChannel
;
611 float *in
= unit
->m_bus
;
612 float b1
= unit
->m_b1
;
613 float *y1
= unit
->m_y1
;
614 for (int i
=0; i
<numChannels
; ++i
, in
++) {
617 float x
= z
+ b1
* (y1
[i
] - z
);
618 *out
= y1
[i
] = zapgremlins(x
);
620 //Print("<-In_next_k\n");
623 void LagIn_next_0(LagIn
*unit
, int inNumSamples
)
625 //Print("->LagIn_next_k\n");
626 World
*world
= unit
->mWorld
;
627 int numChannels
= unit
->mNumOutputs
;
629 float fbusChannel
= ZIN0(0);
630 if (fbusChannel
!= unit
->m_fbusChannel
) {
631 unit
->m_fbusChannel
= fbusChannel
;
632 uint32 busChannel
= (uint32
)fbusChannel
;
633 uint32 lastChannel
= busChannel
+ numChannels
;
635 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
636 unit
->m_bus
= world
->mControlBus
+ busChannel
;
640 float *in
= unit
->m_bus
;
641 float *y1
= unit
->m_y1
;
642 for (int i
=0; i
<numChannels
; ++i
, in
++) {
646 //Print("<-In_next_k\n");
649 void LagIn_Ctor(LagIn
* unit
)
651 //Print("->LagIn_Ctor\n");
652 World
*world
= unit
->mWorld
;
653 unit
->m_fbusChannel
= -1.;
656 unit
->m_b1
= lag
== 0.f
? 0.f
: (float)exp(log001
/ (lag
* unit
->mRate
->mSampleRate
));
658 SETCALC(LagIn_next_k
);
659 unit
->m_bus
= world
->mControlBus
;
660 //unit->m_busTouched = world->mControlBusTouched;
661 LagIn_next_0(unit
, 1);
662 //Print("<-LagIn_Ctor\n");
665 //////////////////////////////////////////////////////////////////////////////////////////////////
666 //////////////////////////////////////////////////////////////////////////////////////////////////
668 void InFeedback_next_a(IOUnit
*unit
, int inNumSamples
)
670 World
*world
= unit
->mWorld
;
671 int bufLength
= world
->mBufLength
;
672 int numChannels
= unit
->mNumOutputs
;
674 float fbusChannel
= ZIN0(0);
675 if (fbusChannel
!= unit
->m_fbusChannel
) {
676 unit
->m_fbusChannel
= fbusChannel
;
677 uint32 busChannel
= (uint32
)fbusChannel
;
678 uint32 lastChannel
= busChannel
+ numChannels
;
680 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
681 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
682 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
686 float *in
= unit
->m_bus
;
687 int32
*touched
= unit
->m_busTouched
;
688 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
690 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
691 ACQUIRE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
693 int diff
= bufCounter
- touched
[i
];
694 if (diff
== 1 || diff
== 0) Copy(inNumSamples
, out
, in
);
695 else Fill(inNumSamples
, out
, 0.f
);
696 RELEASE_BUS_AUDIO_SHARED((int32
)fbusChannel
+ i
);
701 void InFeedback_Ctor(IOUnit
* unit
)
703 //Print("->InFeedback_Ctor\n");
704 World
*world
= unit
->mWorld
;
705 unit
->m_fbusChannel
= -1.;
707 SETCALC(InFeedback_next_a
);
708 unit
->m_bus
= world
->mAudioBus
;
709 unit
->m_busTouched
= world
->mAudioBusTouched
;
710 InFeedback_next_a(unit
, 1);
711 //Print("<-InFeedback_Ctor\n");
714 //////////////////////////////////////////////////////////////////////////////////////////////////
716 void InTrig_next_k(IOUnit
*unit
, int inNumSamples
)
718 World
*world
= unit
->mWorld
;
719 int numChannels
= unit
->mNumOutputs
;
721 float fbusChannel
= ZIN0(0);
722 if (fbusChannel
!= unit
->m_fbusChannel
) {
723 unit
->m_fbusChannel
= fbusChannel
;
724 uint32 busChannel
= (uint32
)fbusChannel
;
725 uint32 lastChannel
= busChannel
+ numChannels
;
727 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
728 unit
->m_bus
= world
->mControlBus
+ busChannel
;
729 unit
->m_busTouched
= world
->mControlBusTouched
+ busChannel
;
733 float *in
= unit
->m_bus
;
734 int32
*touched
= unit
->m_busTouched
;
735 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
736 for (int i
=0; i
<numChannels
; ++i
, in
++) {
738 if (touched
[i
] == bufCounter
) *out
= *in
;
743 void InTrig_Ctor(IOUnit
* unit
)
745 World
*world
= unit
->mWorld
;
746 unit
->m_fbusChannel
= -1.;
748 if (unit
->mCalcRate
== calc_FullRate
) {
749 SETCALC(ClearUnitOutputs
);
750 ClearUnitOutputs(unit
, 1);
752 SETCALC(InTrig_next_k
);
753 unit
->m_bus
= world
->mControlBus
;
754 unit
->m_busTouched
= world
->mControlBusTouched
;
755 InTrig_next_k(unit
, 1);
759 //////////////////////////////////////////////////////////////////////////////////////////////////
762 void ReplaceOut_next_a(IOUnit
*unit
, int inNumSamples
)
764 World
*world
= unit
->mWorld
;
765 int bufLength
= world
->mBufLength
;
766 int numChannels
= unit
->mNumInputs
- 1;
768 float fbusChannel
= ZIN0(0);
769 if (fbusChannel
!= unit
->m_fbusChannel
) {
770 unit
->m_fbusChannel
= fbusChannel
;
771 uint32 busChannel
= (uint32
)fbusChannel
;
772 uint32 lastChannel
= busChannel
+ numChannels
;
774 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
775 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
776 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
780 float *out
= unit
->m_bus
;
781 int32
*touched
= unit
->m_busTouched
;
782 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
783 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
784 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
786 Copy(inNumSamples
, out
, in
);
787 touched
[i
] = bufCounter
;
788 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
792 void ReplaceOut_next_k(IOUnit
*unit
, int inNumSamples
)
794 World
*world
= unit
->mWorld
;
795 int numChannels
= unit
->mNumInputs
- 1;
797 float fbusChannel
= ZIN0(0);
798 if (fbusChannel
!= unit
->m_fbusChannel
) {
799 unit
->m_fbusChannel
= fbusChannel
;
800 uint32 busChannel
= (uint32
)fbusChannel
;
801 uint32 lastChannel
= busChannel
+ numChannels
;
803 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
804 unit
->m_bus
= world
->mControlBus
+ busChannel
;
805 unit
->m_busTouched
= world
->mControlBusTouched
+ busChannel
;
809 float *out
= unit
->m_bus
;
810 int32
*touched
= unit
->m_busTouched
;
811 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
812 for (int i
=0; i
<numChannels
; ++i
, out
++) {
814 ACQUIRE_BUS_CONTROL((int32
)fbusChannel
+ i
);
816 touched
[i
] = bufCounter
;
817 RELEASE_BUS_CONTROL((int32
)fbusChannel
+ i
);
822 FLATTEN
void ReplaceOut_next_a_nova(IOUnit
*unit
, int inNumSamples
)
824 World
*world
= unit
->mWorld
;
825 int bufLength
= world
->mBufLength
;
826 int numChannels
= unit
->mNumInputs
- 1;
828 float fbusChannel
= ZIN0(0);
829 if (fbusChannel
!= unit
->m_fbusChannel
) {
830 unit
->m_fbusChannel
= fbusChannel
;
831 uint32 busChannel
= (uint32
)fbusChannel
;
832 uint32 lastChannel
= busChannel
+ numChannels
;
834 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
835 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
836 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
840 float *out
= unit
->m_bus
;
841 int32
*touched
= unit
->m_busTouched
;
842 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
843 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
844 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
846 nova::copyvec_simd(out
, in
, inNumSamples
);
847 touched
[i
] = bufCounter
;
848 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
852 FLATTEN
void ReplaceOut_next_a_nova_64(IOUnit
*unit
, int inNumSamples
)
854 World
*world
= unit
->mWorld
;
855 int bufLength
= world
->mBufLength
;
856 int numChannels
= unit
->mNumInputs
- 1;
858 float fbusChannel
= ZIN0(0);
859 if (fbusChannel
!= unit
->m_fbusChannel
) {
860 unit
->m_fbusChannel
= fbusChannel
;
861 uint32 busChannel
= (uint32
)fbusChannel
;
862 uint32 lastChannel
= busChannel
+ numChannels
;
864 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
865 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
866 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
870 float *out
= unit
->m_bus
;
871 int32
*touched
= unit
->m_busTouched
;
872 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
873 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
874 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
876 nova::copyvec_simd
<64>(out
, in
);
877 touched
[i
] = bufCounter
;
878 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
882 #endif /* NOVA_SIMD */
884 void ReplaceOut_Ctor(IOUnit
* unit
)
886 World
*world
= unit
->mWorld
;
887 unit
->m_fbusChannel
= -1.;
889 if (unit
->mCalcRate
== calc_FullRate
) {
892 SETCALC(ReplaceOut_next_a_nova_64
);
893 else if (!(BUFLENGTH
& 15))
894 SETCALC(ReplaceOut_next_a_nova
);
897 SETCALC(ReplaceOut_next_a
);
898 unit
->m_bus
= world
->mAudioBus
;
899 unit
->m_busTouched
= world
->mAudioBusTouched
;
901 SETCALC(ReplaceOut_next_k
);
902 unit
->m_bus
= world
->mControlBus
;
903 unit
->m_busTouched
= world
->mControlBusTouched
;
907 //////////////////////////////////////////////////////////////////////////////////////////////////
909 void Out_next_a(IOUnit
*unit
, int inNumSamples
)
911 //Print("Out_next_a %d\n", unit->mNumInputs);
912 World
*world
= unit
->mWorld
;
913 int bufLength
= world
->mBufLength
;
914 int numChannels
= unit
->mNumInputs
- 1;
916 float fbusChannel
= ZIN0(0);
917 if (fbusChannel
!= unit
->m_fbusChannel
) {
918 unit
->m_fbusChannel
= fbusChannel
;
919 uint32 busChannel
= (uint32
)fbusChannel
;
920 uint32 lastChannel
= busChannel
+ numChannels
;
922 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
923 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
924 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
928 float *out
= unit
->m_bus
;
929 int32
*touched
= unit
->m_busTouched
;
930 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
931 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
932 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
934 if (touched
[i
] == bufCounter
) Accum(inNumSamples
, out
, in
);
936 Copy(inNumSamples
, out
, in
);
937 touched
[i
] = bufCounter
;
939 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
940 //Print("out %d %g %g\n", i, in[0], out[0]);
947 void vOut_next_a(IOUnit
*unit
, int inNumSamples
)
949 //Print("Out_next_a %d\n", unit->mNumInputs);
950 World
*world
= unit
->mWorld
;
951 int bufLength
= world
->mBufLength
;
952 int numChannels
= unit
->mNumInputs
- 1;
954 float fbusChannel
= ZIN0(0);
955 if (fbusChannel
!= unit
->m_fbusChannel
) {
956 unit
->m_fbusChannel
= fbusChannel
;
957 int busChannel
= (int)fbusChannel
;
958 int lastChannel
= busChannel
+ numChannels
;
960 if (!(busChannel
< 0 || lastChannel
> (int)world
->mNumAudioBusChannels
)) {
961 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
962 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
966 float *out
= unit
->m_bus
;
967 int32
*touched
= unit
->m_busTouched
;
968 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
969 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
970 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
972 if (touched
[i
] == bufCounter
)
974 vadd(out
, out
, in
, inNumSamples
);
978 vcopy(out
, in
, inNumSamples
);
979 touched
[i
] = bufCounter
;
981 //Print("out %d %g %g\n", i, in[0], out[0]);
982 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
989 FLATTEN
void Out_next_a_nova(IOUnit
*unit
, int inNumSamples
)
991 //Print("Out_next_a %d\n", unit->mNumInputs);
992 World
*world
= unit
->mWorld
;
993 int bufLength
= world
->mBufLength
;
994 int numChannels
= unit
->mNumInputs
- 1;
996 float fbusChannel
= ZIN0(0);
997 if (fbusChannel
!= unit
->m_fbusChannel
) {
998 unit
->m_fbusChannel
= fbusChannel
;
999 int busChannel
= (int)fbusChannel
;
1000 int lastChannel
= busChannel
+ numChannels
;
1002 if (!(busChannel
< 0 || lastChannel
> (int)world
->mNumAudioBusChannels
)) {
1003 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
1004 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
1008 float *out
= unit
->m_bus
;
1009 int32
*touched
= unit
->m_busTouched
;
1010 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1011 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1012 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1013 float *in
= IN(i
+1);
1014 if (touched
[i
] == bufCounter
)
1015 nova::addvec_simd(out
, in
, inNumSamples
);
1017 nova::copyvec_simd(out
, in
, inNumSamples
);
1018 touched
[i
] = bufCounter
;
1020 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1021 //Print("out %d %g %g\n", i, in[0], out[0]);
1025 FLATTEN
void Out_next_a_nova_64(IOUnit
*unit
, int inNumSamples
)
1027 //Print("Out_next_a %d\n", unit->mNumInputs);
1028 World
*world
= unit
->mWorld
;
1029 int bufLength
= world
->mBufLength
;
1030 int numChannels
= unit
->mNumInputs
- 1;
1032 float fbusChannel
= ZIN0(0);
1033 if (fbusChannel
!= unit
->m_fbusChannel
) {
1034 unit
->m_fbusChannel
= fbusChannel
;
1035 int busChannel
= (int)fbusChannel
;
1036 int lastChannel
= busChannel
+ numChannels
;
1038 if (!(busChannel
< 0 || lastChannel
> (int)world
->mNumAudioBusChannels
)) {
1039 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
1040 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
1044 float *out
= unit
->m_bus
;
1045 int32
*touched
= unit
->m_busTouched
;
1046 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1047 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1048 float *in
= IN(i
+1);
1049 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1050 if (touched
[i
] == bufCounter
)
1051 nova::addvec_simd
<64>(out
, in
);
1053 nova::copyvec_simd
<64>(out
, in
);
1054 touched
[i
] = bufCounter
;
1056 //Print("out %d %g %g\n", i, in[0], out[0]);
1057 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1063 void Out_next_k(IOUnit
*unit
, int inNumSamples
)
1065 World
*world
= unit
->mWorld
;
1066 int numChannels
= unit
->mNumInputs
- 1;
1068 float fbusChannel
= ZIN0(0);
1069 if (fbusChannel
!= unit
->m_fbusChannel
) {
1070 unit
->m_fbusChannel
= fbusChannel
;
1071 uint32 busChannel
= (uint32
)fbusChannel
;
1072 uint32 lastChannel
= busChannel
+ numChannels
;
1074 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
1075 unit
->m_bus
= world
->mControlBus
+ busChannel
;
1076 unit
->m_busTouched
= world
->mControlBusTouched
+ busChannel
;
1079 float *out
= unit
->m_bus
;
1080 int32
*touched
= unit
->m_busTouched
;
1081 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1082 for (int i
=0; i
<numChannels
; ++i
, out
++) {
1083 float *in
= IN(i
+1);
1084 ACQUIRE_BUS_CONTROL((int32
)fbusChannel
+ i
);
1085 if (touched
[i
] == bufCounter
)
1089 touched
[i
] = bufCounter
;
1091 RELEASE_BUS_CONTROL((int32
)fbusChannel
+ i
);
1095 void Out_Ctor(IOUnit
* unit
)
1097 //Print("->Out_Ctor\n");
1098 World
*world
= unit
->mWorld
;
1099 unit
->m_fbusChannel
= -1.;
1101 if (unit
->mCalcRate
== calc_FullRate
) {
1103 #if defined(NOVA_SIMD)
1104 if (BUFLENGTH
== 64)
1105 SETCALC(Out_next_a_nova_64
);
1106 else if (!(BUFLENGTH
& 15))
1107 SETCALC(Out_next_a_nova
);
1109 SETCALC(Out_next_a
);
1113 SETCALC(vOut_next_a
);
1115 SETCALC(Out_next_a
);
1118 unit
->m_bus
= world
->mAudioBus
;
1119 unit
->m_busTouched
= world
->mAudioBusTouched
;
1121 SETCALC(Out_next_k
);
1122 unit
->m_bus
= world
->mControlBus
;
1123 unit
->m_busTouched
= world
->mControlBusTouched
;
1125 //Print("<-Out_Ctor\n");
1128 //////////////////////////////////////////////////////////////////////////////////////////////////
1129 //////////////////////////////////////////////////////////////////////////////////////////////////
1131 void XOut_next_a(XOut
*unit
, int inNumSamples
)
1133 World
*world
= unit
->mWorld
;
1134 int bufLength
= world
->mBufLength
;
1135 int numChannels
= unit
->mNumInputs
- 2;
1137 float fbusChannel
= ZIN0(0);
1138 if (fbusChannel
!= unit
->m_fbusChannel
) {
1139 unit
->m_fbusChannel
= fbusChannel
;
1140 uint32 busChannel
= (uint32
)fbusChannel
;
1141 uint32 lastChannel
= busChannel
+ numChannels
;
1143 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
1144 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
1145 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
1149 float next_xfade
= ZIN0(1);
1150 float xfade0
= unit
->m_xfade
;
1151 float *out
= unit
->m_bus
;
1152 int32
*touched
= unit
->m_busTouched
;
1153 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1154 if (xfade0
!= next_xfade
) {
1155 float slope
= CALCSLOPE(next_xfade
, xfade0
);
1156 for (int i
=0; i
<numChannels
; ++i
) {
1157 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1158 float xfade
= xfade0
;
1159 float *in
= IN(i
+2);
1160 if (touched
[i
] == bufCounter
) {
1164 *out
= zout
+ xfade
* (zin
- zout
);
1165 //if (xxi==0) Print("x %d %d %g %g %g %g\n", bufCounter, i, zin, zout, xfade, *out);
1176 touched
[i
] = bufCounter
;
1178 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1180 } else if (xfade0
== 1.f
) {
1181 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1182 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1183 float *in
= IN(i
+2);
1184 Copy(inNumSamples
, out
, in
);
1185 touched
[i
] = bufCounter
;
1186 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1188 } else if (xfade0
== 0.f
) {
1191 for (int i
=0; i
<numChannels
; ++i
) {
1192 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1193 float *in
= IN(i
+2);
1194 if (touched
[i
] == bufCounter
) {
1198 *out
= zout
+ xfade0
* (zin
- zout
);
1204 *out
= xfade0
* zin
;
1207 touched
[i
] = bufCounter
;
1209 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1212 unit
->m_xfade
= next_xfade
;
1216 FLATTEN
void XOut_next_a_nova(XOut
*unit
, int inNumSamples
)
1218 World
*world
= unit
->mWorld
;
1219 int bufLength
= world
->mBufLength
;
1220 int numChannels
= unit
->mNumInputs
- 2;
1222 float fbusChannel
= ZIN0(0);
1223 if (fbusChannel
!= unit
->m_fbusChannel
) {
1224 unit
->m_fbusChannel
= fbusChannel
;
1225 uint32 busChannel
= (uint32
)fbusChannel
;
1226 uint32 lastChannel
= busChannel
+ numChannels
;
1228 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
1229 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
1230 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
1234 float next_xfade
= ZIN0(1);
1235 float xfade0
= unit
->m_xfade
;
1236 float *out
= unit
->m_bus
;
1237 int32
*touched
= unit
->m_busTouched
;
1238 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1239 if (xfade0
!= next_xfade
) {
1240 float slope
= CALCSLOPE(next_xfade
, xfade0
);
1241 for (int i
=0; i
<numChannels
; ++i
) {
1242 float xfade
= xfade0
;
1243 float *in
= IN(i
+2);
1244 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1245 if (touched
[i
] == bufCounter
)
1246 nova::mix_vec_simd(out
, out
, slope_argument(1-xfade0
, -slope
), in
, slope_argument(xfade0
, slope
), inNumSamples
);
1248 nova::times_vec_simd(out
, in
, slope_argument(xfade
, slope
), inNumSamples
);
1249 touched
[i
] = bufCounter
;
1251 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1253 unit
->m_xfade
= next_xfade
;
1254 } else if (xfade0
== 1.f
) {
1255 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1256 float *in
= IN(i
+2);
1257 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1258 nova::copyvec_simd(out
, in
, inNumSamples
);
1259 touched
[i
] = bufCounter
;
1260 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1262 } else if (xfade0
== 0.f
) {
1265 for (int i
=0; i
<numChannels
; ++i
) {
1266 float *in
= IN(i
+2);
1267 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1268 if (touched
[i
] == bufCounter
)
1269 nova::mix_vec_simd(out
, out
, 1-xfade0
, in
, xfade0
, inNumSamples
);
1271 nova::times_vec_simd(out
, in
, xfade0
, inNumSamples
);
1272 touched
[i
] = bufCounter
;
1274 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1283 void XOut_next_k(XOut
*unit
, int inNumSamples
)
1285 World
*world
= unit
->mWorld
;
1286 int numChannels
= unit
->mNumInputs
- 2;
1288 float fbusChannel
= ZIN0(0);
1289 if (fbusChannel
!= unit
->m_fbusChannel
) {
1290 unit
->m_fbusChannel
= fbusChannel
;
1291 uint32 busChannel
= (uint32
)fbusChannel
;
1292 uint32 lastChannel
= busChannel
+ numChannels
;
1294 if (!(lastChannel
> world
->mNumControlBusChannels
)) {
1295 unit
->m_bus
= world
->mControlBus
+ busChannel
;
1296 unit
->m_busTouched
= world
->mControlBusTouched
+ busChannel
;
1300 float xfade
= ZIN0(1);
1301 float *out
= unit
->m_bus
;
1302 int32
*touched
= unit
->m_busTouched
;
1303 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1304 for (int i
=0; i
<numChannels
; ++i
, out
++) {
1305 float *in
= IN(i
+2);
1306 ACQUIRE_BUS_CONTROL((int32
)fbusChannel
+ i
);
1307 if (touched
[i
] == bufCounter
) {
1310 *out
= zout
+ xfade
* (zin
- zout
);
1313 touched
[i
] = bufCounter
;
1315 RELEASE_BUS_CONTROL((int32
)fbusChannel
+ i
);
1319 void XOut_Ctor(XOut
* unit
)
1321 //Print("->Out_Ctor\n");
1322 World
*world
= unit
->mWorld
;
1323 unit
->m_fbusChannel
= -1.;
1324 unit
->m_xfade
= ZIN0(1);
1325 if (unit
->mCalcRate
== calc_FullRate
) {
1327 if (!(BUFLENGTH
& 15))
1328 SETCALC(XOut_next_a_nova
);
1330 SETCALC(XOut_next_a
);
1331 unit
->m_bus
= world
->mAudioBus
;
1332 unit
->m_busTouched
= world
->mAudioBusTouched
;
1334 SETCALC(XOut_next_k
);
1335 unit
->m_bus
= world
->mControlBus
;
1336 unit
->m_busTouched
= world
->mControlBusTouched
;
1338 //Print("<-Out_Ctor\n");
1341 //////////////////////////////////////////////////////////////////////////////////////////////////
1343 void OffsetOut_next_a(OffsetOut
*unit
, int inNumSamples
)
1345 World
*world
= unit
->mWorld
;
1346 int bufLength
= world
->mBufLength
;
1347 int numChannels
= unit
->mNumInputs
- 1;
1349 float fbusChannel
= ZIN0(0);
1350 if (fbusChannel
!= unit
->m_fbusChannel
) {
1351 unit
->m_fbusChannel
= fbusChannel
;
1352 uint32 busChannel
= (uint32
)fbusChannel
;
1353 uint32 lastChannel
= busChannel
+ numChannels
;
1355 if (!(lastChannel
> world
->mNumAudioBusChannels
)) {
1356 unit
->m_bus
= world
->mAudioBus
+ (busChannel
* bufLength
);
1357 unit
->m_busTouched
= world
->mAudioBusTouched
+ busChannel
;
1361 int32 offset
= unit
->mParent
->mSampleOffset
;
1362 int32 remain
= BUFLENGTH
- offset
;
1364 float *out
= unit
->m_bus
;
1365 float *saved
= unit
->m_saved
;
1366 int32
*touched
= unit
->m_busTouched
;
1367 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1368 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
, saved
+= offset
) {
1369 ACQUIRE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1370 float *in
= IN(i
+1);
1371 //Print("out %d %d %d %d %d\n",
1372 // i, touched[i] == bufCounter, unit->m_empty,
1375 if (touched
[i
] == bufCounter
) {
1376 if (unit
->m_empty
) {
1377 //Print("touched offset %d\n", offset);
1379 Accum(offset
, out
, saved
);
1381 Accum(remain
, out
+ offset
, in
);
1383 if (unit
->m_empty
) {
1385 //Print("untouched offset %d\n", offset);
1387 Copy(offset
, out
, saved
);
1389 Copy(remain
, out
+ offset
, in
);
1390 touched
[i
] = bufCounter
;
1392 Copy(offset
, saved
, in
+ remain
);
1393 RELEASE_BUS_AUDIO((int32
)fbusChannel
+ i
);
1394 //Print("out %d %d %d %g %g\n", i, in[0], out[0]);
1396 unit
->m_empty
= false;
1399 void OffsetOut_Ctor(OffsetOut
* unit
)
1401 //Print("->Out_Ctor\n");
1402 World
*world
= unit
->mWorld
;
1403 unit
->m_fbusChannel
= -1.;
1405 SETCALC(OffsetOut_next_a
);
1406 unit
->m_bus
= world
->mAudioBus
;
1407 unit
->m_busTouched
= world
->mAudioBusTouched
;
1408 int32 offset
= unit
->mParent
->mSampleOffset
;
1409 int numChannels
= unit
->mNumInputs
- 1;
1411 unit
->m_saved
= (float*)RTAlloc(unit
->mWorld
, offset
* numChannels
* sizeof(float));
1412 unit
->m_empty
= true;
1413 //Print("<-Out_Ctor\n");
1416 void OffsetOut_Dtor(OffsetOut
* unit
)
1418 // Ctor may not have run, if unit was immediately created->paused->freed!
1420 World
*world
= unit
->mWorld
;
1421 int bufLength
= world
->mBufLength
;
1422 int numChannels
= unit
->mNumInputs
- 1;
1424 int32 offset
= unit
->mParent
->mSampleOffset
;
1425 int32 remain
= BUFLENGTH
- offset
;
1427 float *out
= unit
->m_bus
;
1428 float *saved
= unit
->m_saved
;
1429 int32
*touched
= unit
->m_busTouched
;
1430 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1431 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
, saved
+= offset
) {
1432 //Print("out %d %d %d %d %d\n",
1433 // i, touched[i] == bufCounter, unit->m_empty,
1436 if (!unit
->m_empty
) {
1437 if (touched
[i
] == bufCounter
) {
1438 Accum(offset
, out
, saved
);
1440 Copy(offset
, out
, saved
);
1441 Clear(remain
, out
+ offset
);
1442 touched
[i
] = bufCounter
;
1445 //Print("out %d %d %d %g %g\n", i, in[0], out[0]);
1448 RTFree(unit
->mWorld
, unit
->m_saved
);
1452 //////////////////////////////////////////////////////////////////////////////////////////////////
1454 void SharedIn_next_k(IOUnit
*unit
, int inNumSamples
)
1456 //Print("->SharedIn_next_k\n");
1457 World
*world
= unit
->mWorld
;
1458 int numChannels
= unit
->mNumOutputs
;
1460 float fbusChannel
= ZIN0(0);
1461 if (fbusChannel
!= unit
->m_fbusChannel
) {
1462 unit
->m_fbusChannel
= fbusChannel
;
1463 uint32 busChannel
= (uint32
)fbusChannel
;
1464 uint32 lastChannel
= busChannel
+ numChannels
;
1466 if (!(lastChannel
> world
->mNumSharedControls
)) {
1467 unit
->m_bus
= world
->mSharedControls
+ busChannel
;
1471 float *in
= unit
->m_bus
;
1473 for (int i
=0; i
<numChannels
; ++i
, in
++) {
1474 float *out
= OUT(i
);
1478 ClearUnitOutputs(unit
, 1);
1480 //Print("<-SharedIn_next_k\n");
1483 void SharedIn_Ctor(IOUnit
* unit
)
1485 //Print("->SharedIn_Ctor\n");
1486 World
*world
= unit
->mWorld
;
1487 unit
->m_fbusChannel
= -1.;
1489 SETCALC(SharedIn_next_k
);
1490 unit
->m_bus
= world
->mSharedControls
;
1491 SharedIn_next_k(unit
, 1);
1493 //Print("<-SharedIn_Ctor\n");
1496 //////////////////////////////////////////////////////////////////////////////////////////////////
1497 //////////////////////////////////////////////////////////////////////////////////////////////////
1499 void SharedOut_next_k(IOUnit
*unit
, int inNumSamples
)
1501 //Print("->SharedOut_next_k\n");
1502 World
*world
= unit
->mWorld
;
1503 int numChannels
= unit
->mNumInputs
- 1;
1505 float fbusChannel
= ZIN0(0);
1506 if (fbusChannel
!= unit
->m_fbusChannel
) {
1507 unit
->m_fbusChannel
= fbusChannel
;
1508 uint32 busChannel
= (uint32
)fbusChannel
;
1509 uint32 lastChannel
= busChannel
+ numChannels
;
1511 if (!(lastChannel
> world
->mNumSharedControls
)) {
1512 unit
->m_bus
= world
->mSharedControls
+ busChannel
;
1516 float *out
= unit
->m_bus
;
1518 for (int i
=1; i
<numChannels
+1; ++i
, out
++) {
1523 //Print("<-SharedOut_next_k\n");
1526 void SharedOut_Ctor(IOUnit
* unit
)
1528 //Print("->SharedOut_Ctor\n");
1529 World
*world
= unit
->mWorld
;
1530 unit
->m_fbusChannel
= -1.;
1532 SETCALC(SharedOut_next_k
);
1533 unit
->m_bus
= world
->mSharedControls
;
1534 SharedOut_next_k(unit
, 1);
1536 //Print("<-SharedOut_Ctor\n");
1539 //////////////////////////////////////////////////////////////////////////////////////////////////
1541 void LocalIn_next_a(LocalIn
*unit
, int inNumSamples
)
1543 World
*world
= unit
->mWorld
;
1544 int bufLength
= world
->mBufLength
;
1545 int numChannels
= unit
->mNumOutputs
;
1547 float *in
= unit
->m_bus
;
1548 int32
*touched
= unit
->m_busTouched
;
1549 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1551 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
1552 float *out
= OUT(i
);
1553 int diff
= bufCounter
- touched
[i
];
1554 //Print("LocalIn %d %d %g\n", i, diff, in[0]);
1555 if (diff
== 1 || diff
== 0) Copy(inNumSamples
, out
, in
);
1556 else Fill(inNumSamples
, out
, IN0(i
));
1561 FLATTEN
void LocalIn_next_a_nova(LocalIn
*unit
, int inNumSamples
)
1563 World
*world
= unit
->mWorld
;
1564 int bufLength
= world
->mBufLength
;
1565 int numChannels
= unit
->mNumOutputs
;
1567 float *in
= unit
->m_bus
;
1568 int32
*touched
= unit
->m_busTouched
;
1569 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1571 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
1572 float *out
= OUT(i
);
1573 int diff
= bufCounter
- touched
[i
];
1574 //Print("LocalIn %d %d %g\n", i, diff, in[0]);
1575 if (diff
== 1 || diff
== 0)
1576 nova::copyvec_simd(out
, in
, inNumSamples
);
1578 //nova::zerovec_simd(out, inNumSamples);
1579 Fill(inNumSamples
, out
, IN0(i
));
1583 FLATTEN
void LocalIn_next_a_nova_64(LocalIn
*unit
, int inNumSamples
)
1585 World
*world
= unit
->mWorld
;
1586 int bufLength
= world
->mBufLength
;
1587 int numChannels
= unit
->mNumOutputs
;
1589 float *in
= unit
->m_bus
;
1590 int32
*touched
= unit
->m_busTouched
;
1591 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1592 for (int i
=0; i
<numChannels
; ++i
, in
+= bufLength
) {
1593 float *out
= OUT(i
);
1594 int diff
= bufCounter
- touched
[i
];
1595 //Print("LocalIn %d %d %g\n", i, diff, in[0]);
1596 if (diff
== 1 || diff
== 0)
1597 nova::copyvec_simd
<64>(out
, in
);
1599 //nova::zerovec_simd<64>(out);
1600 Fill(inNumSamples
, out
, IN0(i
));
1606 void LocalIn_next_k(LocalIn
*unit
, int inNumSamples
)
1608 uint32 numChannels
= unit
->mNumOutputs
;
1610 float *in
= unit
->m_bus
;
1611 int32
*touched
= unit
->m_busTouched
;
1612 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1613 for (uint32 i
=0; i
<numChannels
; ++i
, in
++) {
1614 int diff
= bufCounter
- touched
[i
];
1615 float *out
= OUT(i
);
1616 if (diff
== 1 || diff
== 0)
1623 void LocalIn_Ctor(LocalIn
* unit
)
1625 //Print("->LocalIn_Ctor\n");
1626 int numChannels
= unit
->mNumOutputs
;
1628 World
*world
= unit
->mWorld
;
1630 int busDataSize
= numChannels
* BUFLENGTH
;
1632 // align the buffer to 256 bytes so that we can use avx instructions
1633 unit
->m_realData
= (float*)RTAlloc(world
, busDataSize
* sizeof(float) + numChannels
* sizeof(int32
) + 32 * sizeof(float));
1634 size_t alignment
= (size_t)unit
->m_realData
& 31;
1636 unit
->m_bus
= alignment
? (float*)(size_t(unit
->m_realData
+ 32) & ~31)
1639 unit
->m_busTouched
= (int32
*)(unit
->m_bus
+ busDataSize
);
1640 for (int i
=0; i
<numChannels
; ++i
)
1641 unit
->m_busTouched
[i
] = -1;
1643 if (unit
->mCalcRate
== calc_FullRate
) {
1644 if (unit
->mParent
->mLocalAudioBusUnit
)
1646 SETCALC(ClearUnitOutputs
);
1647 ClearUnitOutputs(unit
, 1);
1650 unit
->mParent
->mLocalAudioBusUnit
= unit
;
1652 if (BUFLENGTH
== 64)
1653 SETCALC(LocalIn_next_a_nova_64
);
1654 else if (!(BUFLENGTH
& 15))
1655 SETCALC(LocalIn_next_a_nova
);
1658 SETCALC(LocalIn_next_a
);
1659 LocalIn_next_a(unit
, 1);
1661 if (unit
->mParent
->mLocalControlBusUnit
)
1663 SETCALC(ClearUnitOutputs
);
1664 ClearUnitOutputs(unit
, 1);
1667 unit
->mParent
->mLocalControlBusUnit
= unit
;
1668 SETCALC(LocalIn_next_k
);
1669 LocalIn_next_k(unit
, 1);
1671 //Print("<-LocalIn_Ctor\n");
1674 void LocalIn_Dtor(LocalIn
* unit
)
1676 World
*world
= unit
->mWorld
;
1677 RTFree(world
, unit
->m_realData
);
1680 //////////////////////////////////////////////////////////////////////////////////////////////////
1681 //////////////////////////////////////////////////////////////////////////////////////////////////
1683 void LocalOut_next_a(IOUnit
*unit
, int inNumSamples
)
1685 //Print("LocalOut_next_a %d\n", unit->mNumInputs);
1686 World
*world
= unit
->mWorld
;
1687 int bufLength
= world
->mBufLength
;
1688 int numChannels
= unit
->mNumInputs
;
1690 LocalIn
*localIn
= (LocalIn
*)unit
->mParent
->mLocalAudioBusUnit
;
1691 if (!localIn
|| numChannels
!= localIn
->mNumOutputs
)
1693 ClearUnitOutputs(unit
, inNumSamples
);
1696 float *out
= localIn
->m_bus
;
1697 int32
*touched
= localIn
->m_busTouched
;
1699 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1700 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1702 if (touched
[i
] == bufCounter
) Accum(inNumSamples
, out
, in
);
1704 Copy(inNumSamples
, out
, in
);
1705 touched
[i
] = bufCounter
;
1707 //Print("LocalOut %d %g %g\n", i, in[0], out[0]);
1712 FLATTEN
void LocalOut_next_a_nova(IOUnit
*unit
, int inNumSamples
)
1714 //Print("LocalOut_next_a %d\n", unit->mNumInputs);
1715 World
*world
= unit
->mWorld
;
1716 int bufLength
= world
->mBufLength
;
1717 int numChannels
= unit
->mNumInputs
;
1719 LocalIn
*localIn
= (LocalIn
*)unit
->mParent
->mLocalAudioBusUnit
;
1720 if (!localIn
|| numChannels
!= localIn
->mNumOutputs
)
1722 ClearUnitOutputs(unit
, inNumSamples
);
1725 float *out
= localIn
->m_bus
;
1726 int32
*touched
= localIn
->m_busTouched
;
1728 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1729 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1731 if (touched
[i
] == bufCounter
)
1732 nova::addvec_simd(out
, in
, inNumSamples
);
1734 nova::copyvec_simd(out
, in
, inNumSamples
);
1735 touched
[i
] = bufCounter
;
1737 //Print("LocalOut %d %g %g\n", i, in[0], out[0]);
1741 void LocalOut_next_a_nova_64(IOUnit
*unit
, int inNumSamples
)
1743 //Print("LocalOut_next_a %d\n", unit->mNumInputs);
1744 World
*world
= unit
->mWorld
;
1745 int bufLength
= world
->mBufLength
;
1746 int numChannels
= unit
->mNumInputs
;
1748 LocalIn
*localIn
= (LocalIn
*)unit
->mParent
->mLocalAudioBusUnit
;
1749 if (!localIn
|| numChannels
!= localIn
->mNumOutputs
)
1751 ClearUnitOutputs(unit
, inNumSamples
);
1754 float *out
= localIn
->m_bus
;
1755 int32
*touched
= localIn
->m_busTouched
;
1757 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1758 for (int i
=0; i
<numChannels
; ++i
, out
+=bufLength
) {
1760 if (touched
[i
] == bufCounter
)
1761 nova::addvec_simd
<64>(out
, in
);
1763 nova::copyvec_simd
<64>(out
, in
);
1764 touched
[i
] = bufCounter
;
1766 //Print("LocalOut %d %g %g\n", i, in[0], out[0]);
1772 void LocalOut_next_k(IOUnit
*unit
, int inNumSamples
)
1774 int numChannels
= unit
->mNumInputs
;
1776 LocalIn
*localIn
= (LocalIn
*)unit
->mParent
->mLocalControlBusUnit
;
1777 if (!localIn
|| numChannels
!= localIn
->mNumOutputs
)
1779 ClearUnitOutputs(unit
, inNumSamples
);
1782 float *out
= localIn
->m_bus
;
1783 int32
*touched
= localIn
->m_busTouched
;
1785 int32 bufCounter
= unit
->mWorld
->mBufCounter
;
1786 for (int i
=0; i
<numChannels
; ++i
, out
++) {
1788 if (touched
[i
] == bufCounter
) *out
+= *in
;
1791 touched
[i
] = bufCounter
;
1796 void LocalOut_Ctor(IOUnit
* unit
)
1798 //Print("->LocalOut_Ctor\n");
1799 World
*world
= unit
->mWorld
;
1800 unit
->m_fbusChannel
= -1.;
1802 if (unit
->mCalcRate
== calc_FullRate
) {
1805 if (BUFLENGTH
== 64)
1806 SETCALC(LocalOut_next_a_nova_64
);
1807 else if (!(BUFLENGTH
& 15))
1808 SETCALC(LocalOut_next_a_nova
);
1811 SETCALC(LocalOut_next_a
);
1812 unit
->m_bus
= world
->mAudioBus
;
1813 unit
->m_busTouched
= world
->mAudioBusTouched
;
1815 SETCALC(LocalOut_next_k
);
1816 unit
->m_bus
= world
->mControlBus
;
1817 unit
->m_busTouched
= world
->mControlBusTouched
;
1819 //Print("<-LocalOut_Ctor\n");
1822 //////////////////////////////////////////////////////////////////////////////////////////////////
1823 //////////////////////////////////////////////////////////////////////////////////////////////////
1829 DefineDtorUnit(OffsetOut
);
1830 DefineDtorUnit(LocalIn
);
1831 DefineSimpleUnit(XOut
);
1832 DefineDtorUnit(LagControl
);
1833 DefineDtorUnit(AudioControl
);
1834 DefineUnit("Control", sizeof(Unit
), (UnitCtorFunc
)&Control_Ctor
, 0, 0);
1835 DefineUnit("TrigControl", sizeof(Unit
), (UnitCtorFunc
)&TrigControl_Ctor
, 0, 0);
1836 DefineUnit("ReplaceOut", sizeof(IOUnit
), (UnitCtorFunc
)&ReplaceOut_Ctor
, 0, 0);
1837 DefineUnit("Out", sizeof(IOUnit
), (UnitCtorFunc
)&Out_Ctor
, 0, 0);
1838 DefineUnit("LocalOut", sizeof(IOUnit
), (UnitCtorFunc
)&LocalOut_Ctor
, 0, 0);
1839 DefineUnit("In", sizeof(IOUnit
), (UnitCtorFunc
)&In_Ctor
, 0, 0);
1840 DefineUnit("LagIn", sizeof(IOUnit
), (UnitCtorFunc
)&LagIn_Ctor
, 0, 0);
1841 DefineUnit("InFeedback", sizeof(IOUnit
), (UnitCtorFunc
)&InFeedback_Ctor
, 0, 0);
1842 DefineUnit("InTrig", sizeof(IOUnit
), (UnitCtorFunc
)&InTrig_Ctor
, 0, 0);
1844 DefineUnit("SharedOut", sizeof(IOUnit
), (UnitCtorFunc
)&SharedOut_Ctor
, 0, 0);
1845 DefineUnit("SharedIn", sizeof(IOUnit
), (UnitCtorFunc
)&SharedIn_Ctor
, 0, 0);