FFT: Prevent user from attempting hops smaller than SC's block size
[supercollider.git] / server / plugins / DelayUGens.cpp
blob5fdeaeaad1f1ba8c9b99869c0015ecf9e5d0b54e
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
21 #ifdef NOVA_SIMD
22 #include "simd_memory.hpp"
23 #endif
25 #include "SC_PlugIn.h"
26 #include <cstdio>
28 using namespace std; // for math functions
31 const int kMAXMEDIANSIZE = 32;
33 static InterfaceTable *ft;
35 struct ScopeOut : public Unit
37 SndBuf *m_buf;
38 SndBufUpdates *m_bufupdates;
39 float m_fbufnum;
40 uint32 m_framepos, m_framecount;
41 float **mIn;
44 struct PlayBuf : public Unit
46 double m_phase;
47 float m_prevtrig;
48 float m_fbufnum;
49 SndBuf *m_buf;
53 struct Grain
55 double phase, rate;
56 double b1, y1, y2; // envelope
57 float pan1, pan2;
58 int counter;
59 int bufnum;
60 int chan;
61 int interp;
64 const int kMaxGrains = 64;
66 struct TGrains : public Unit
68 float mPrevTrig;
69 int mNumActive;
70 Grain mGrains[kMaxGrains];
74 #if NOTYET
75 struct SimpleLoopBuf : public Unit
77 int m_phase;
78 float m_prevtrig;
79 float m_fbufnum;
80 SndBuf *m_buf;
82 #endif
84 struct BufRd : public Unit
86 float m_fbufnum;
87 SndBuf *m_buf;
90 struct BufWr : public Unit
92 float m_fbufnum;
93 SndBuf *m_buf;
96 struct RecordBuf : public Unit
98 float m_fbufnum;
99 SndBuf *m_buf;
100 int32 m_writepos;
101 float m_recLevel, m_preLevel;
102 float m_prevtrig;
103 float **mIn;
106 struct Pitch : public Unit
108 float m_values[kMAXMEDIANSIZE];
109 int m_ages[kMAXMEDIANSIZE];
110 float *m_buffer;
112 float m_freq, m_minfreq, m_maxfreq, m_hasfreq, m_srate, m_ampthresh, m_peakthresh;
113 int m_minperiod, m_maxperiod, m_execPeriod, m_index, m_readp, m_size;
114 int m_downsamp, m_maxlog2bins, m_medianSize;
115 int m_state;
116 bool m_getClarity;
119 struct InterpolationUnit
121 static const int minDelaySamples = 1;
124 struct CubicInterpolationUnit
126 static const int minDelaySamples = 2;
129 struct BufDelayUnit : public Unit
131 float m_fbufnum;
132 SndBuf *m_buf;
133 float m_dsamp;
134 float m_delaytime;
135 int m_iwrphase;
136 uint32 m_numoutput;
139 struct BufDelayN : public BufDelayUnit, InterpolationUnit
142 struct BufDelayL : public BufDelayUnit, InterpolationUnit
145 struct BufDelayC : public BufDelayUnit, CubicInterpolationUnit
148 struct BufFeedbackDelay : public BufDelayUnit
150 float m_feedbk, m_decaytime;
153 struct BufCombN : public BufFeedbackDelay, InterpolationUnit
156 struct BufCombL : public BufFeedbackDelay, InterpolationUnit
159 struct BufCombC : public BufFeedbackDelay, CubicInterpolationUnit
162 struct BufAllpassN : public BufFeedbackDelay, InterpolationUnit
165 struct BufAllpassL : public BufFeedbackDelay, InterpolationUnit
168 struct BufAllpassC : public BufFeedbackDelay, CubicInterpolationUnit
171 struct DelayUnit : public Unit
173 float *m_dlybuf;
175 float m_dsamp, m_fdelaylen;
176 float m_delaytime, m_maxdelaytime;
177 long m_iwrphase, m_idelaylen, m_mask;
178 long m_numoutput;
181 struct DelayN : public DelayUnit, InterpolationUnit
184 struct DelayL : public DelayUnit, InterpolationUnit
187 struct DelayC : public DelayUnit, InterpolationUnit
190 struct FeedbackDelay : public DelayUnit
192 float m_feedbk, m_decaytime;
195 struct CombN : public FeedbackDelay, InterpolationUnit
198 struct CombL : public FeedbackDelay, InterpolationUnit
201 struct CombC : public FeedbackDelay, CubicInterpolationUnit
204 struct AllpassN : public FeedbackDelay, InterpolationUnit
207 struct AllpassL : public FeedbackDelay, InterpolationUnit
210 struct AllpassC : public FeedbackDelay, CubicInterpolationUnit
213 struct BufInfoUnit : public Unit
215 float m_fbufnum;
216 SndBuf *m_buf;
219 struct Pluck : public FeedbackDelay, CubicInterpolationUnit
221 float m_lastsamp, m_prevtrig, m_coef;
222 long m_inputsamps;
225 struct LocalBuf : public Unit
227 SndBuf *m_buf;
230 struct MaxLocalBufs : public Unit
234 struct SetBuf : public Unit
237 struct ClearBuf : public Unit
240 struct DelTapWr : public Unit
242 SndBuf *m_buf;
243 float m_fbufnum;
244 uint32 m_phase;
247 struct DelTapRd : public Unit
249 SndBuf *m_buf;
250 float m_fbufnum, m_delTime;
254 //////////////////////////////////////////////////////////////////////////////////////////////////
256 extern "C"
259 void SampleRate_Ctor(Unit *unit, int inNumSamples);
260 void ControlRate_Ctor(Unit *unit, int inNumSamples);
261 void SampleDur_Ctor(Unit *unit, int inNumSamples);
262 void ControlDur_Ctor(Unit *unit, int inNumSamples);
263 void SubsampleOffset_Ctor(Unit *unit, int inNumSamples);
264 void RadiansPerSample_Ctor(Unit *unit, int inNumSamples);
265 void NumInputBuses_Ctor(Unit *unit, int inNumSamples);
266 void NumOutputBuses_Ctor(Unit *unit, int inNumSamples);
267 void NumAudioBuses_Ctor(Unit *unit, int inNumSamples);
268 void NumControlBuses_Ctor(Unit *unit, int inNumSamples);
269 void NumBuffers_Ctor(Unit *unit, int inNumSamples);
270 void NumRunningSynths_Ctor(Unit *unit, int inNumSamples);
271 void NumRunningSynths_next(Unit *unit, int inNumSamples);
273 void BufSampleRate_next(BufInfoUnit *unit, int inNumSamples);
274 void BufSampleRate_Ctor(BufInfoUnit *unit, int inNumSamples);
276 void BufFrames_next(BufInfoUnit *unit, int inNumSamples);
277 void BufFrames_Ctor(BufInfoUnit *unit, int inNumSamples);
279 void BufDur_next(BufInfoUnit *unit, int inNumSamples);
280 void BufDur_Ctor(BufInfoUnit *unit, int inNumSamples);
282 void BufChannels_next(BufInfoUnit *unit, int inNumSamples);
283 void BufChannels_Ctor(BufInfoUnit *unit, int inNumSamples);
285 void BufSamples_next(BufInfoUnit *unit, int inNumSamples);
286 void BufSamples_Ctor(BufInfoUnit *unit, int inNumSamples);
288 void BufRateScale_next(BufInfoUnit *unit, int inNumSamples);
289 void BufRateScale_Ctor(BufInfoUnit *unit, int inNumSamples);
291 void PlayBuf_next_aa(PlayBuf *unit, int inNumSamples);
292 void PlayBuf_next_ak(PlayBuf *unit, int inNumSamples);
293 void PlayBuf_next_ka(PlayBuf *unit, int inNumSamples);
294 void PlayBuf_next_kk(PlayBuf *unit, int inNumSamples);
295 void PlayBuf_Ctor(PlayBuf* unit);
297 void TGrains_next(TGrains *unit, int inNumSamples);
298 void TGrains_Ctor(TGrains* unit);
300 #if NOTYET
301 void SimpleLoopBuf_next_kk(SimpleLoopBuf *unit, int inNumSamples);
302 void SimpleLoopBuf_Ctor(SimpleLoopBuf* unit);
303 void SimpleLoopBuf_Dtor(SimpleLoopBuf* unit);
304 #endif
306 void BufRd_Ctor(BufRd *unit);
307 void BufRd_next_4(BufRd *unit, int inNumSamples);
308 void BufRd_next_2(BufRd *unit, int inNumSamples);
309 void BufRd_next_1(BufRd *unit, int inNumSamples);
311 void BufWr_Ctor(BufWr *unit);
312 void BufWr_next(BufWr *unit, int inNumSamples);
314 void RecordBuf_Ctor(RecordBuf *unit);
315 void RecordBuf_Dtor(RecordBuf *unit);
316 void RecordBuf_next(RecordBuf *unit, int inNumSamples);
317 void RecordBuf_next_10(RecordBuf *unit, int inNumSamples);
319 void Pitch_Ctor(Pitch *unit);
320 void Pitch_next_a(Pitch *unit, int inNumSamples);
321 void Pitch_next_k(Pitch *unit, int inNumSamples);
323 void LocalBuf_Ctor(LocalBuf *unit);
324 void LocalBuf_Dtor(LocalBuf *unit);
326 void MaxLocalBufs_Ctor(MaxLocalBufs *unit);
328 void SetBuf_Ctor(SetBuf *unit);
329 void ClearBuf_Ctor(ClearBuf *unit);
331 void BufDelayN_Ctor(BufDelayN *unit);
332 void BufDelayN_next(BufDelayN *unit, int inNumSamples);
333 void BufDelayN_next_z(BufDelayN *unit, int inNumSamples);
334 void BufDelayN_next_a(BufDelayN *unit, int inNumSamples);
335 void BufDelayN_next_a_z(BufDelayN *unit, int inNumSamples);
337 void BufDelayL_Ctor(BufDelayL *unit);
338 void BufDelayL_next(BufDelayL *unit, int inNumSamples);
339 void BufDelayL_next_z(BufDelayL *unit, int inNumSamples);
340 void BufDelayL_next_a(BufDelayL *unit, int inNumSamples);
341 void BufDelayL_next_a_z(BufDelayL *unit, int inNumSamples);
343 void BufDelayC_Ctor(BufDelayC *unit);
344 void BufDelayC_next(BufDelayC *unit, int inNumSamples);
345 void BufDelayC_next_z(BufDelayC *unit, int inNumSamples);
346 void BufDelayC_next_a(BufDelayC *unit, int inNumSamples);
347 void BufDelayC_next_a_z(BufDelayC *unit, int inNumSamples);
349 void BufCombN_Ctor(BufCombN *unit);
350 void BufCombN_next(BufCombN *unit, int inNumSamples);
351 void BufCombN_next_z(BufCombN *unit, int inNumSamples);
352 void BufCombN_next_a(BufCombN *unit, int inNumSamples);
353 void BufCombN_next_a_z(BufCombN *unit, int inNumSamples);
355 void BufCombL_Ctor(BufCombL *unit);
356 void BufCombL_next(BufCombL *unit, int inNumSamples);
357 void BufCombL_next_z(BufCombL *unit, int inNumSamples);
358 void BufCombL_next_a(BufCombL *unit, int inNumSamples);
359 void BufCombL_next_a_z(BufCombL *unit, int inNumSamples);
361 void BufCombC_Ctor(BufCombC *unit);
362 void BufCombC_next(BufCombC *unit, int inNumSamples);
363 void BufCombC_next_z(BufCombC *unit, int inNumSamples);
364 void BufCombC_next_a(BufCombC *unit, int inNumSamples);
365 void BufCombC_next_a_z(BufCombC *unit, int inNumSamples);
367 void BufAllpassN_Ctor(BufAllpassN *unit);
368 void BufAllpassN_next(BufAllpassN *unit, int inNumSamples);
369 void BufAllpassN_next_z(BufAllpassN *unit, int inNumSamples);
370 void BufAllpassN_next_a(BufAllpassN *unit, int inNumSamples);
371 void BufAllpassN_next_a_z(BufAllpassN *unit, int inNumSamples);
373 void BufAllpassL_Ctor(BufAllpassL *unit);
374 void BufAllpassL_next(BufAllpassL *unit, int inNumSamples);
375 void BufAllpassL_next_z(BufAllpassL *unit, int inNumSamples);
376 void BufAllpassL_next_a(BufAllpassL *unit, int inNumSamples);
377 void BufAllpassL_next_a_z(BufAllpassL *unit, int inNumSamples);
379 void BufAllpassC_Ctor(BufAllpassC *unit);
380 void BufAllpassC_next(BufAllpassC *unit, int inNumSamples);
381 void BufAllpassC_next_z(BufAllpassC *unit, int inNumSamples);
382 void BufAllpassC_next_a(BufAllpassC *unit, int inNumSamples);
383 void BufAllpassC_next_a_z(BufAllpassC *unit, int inNumSamples);
385 void DelayUnit_Dtor(DelayUnit *unit);
387 void DelayN_Ctor(DelayN *unit);
388 void DelayN_next(DelayN *unit, int inNumSamples);
389 void DelayN_next_z(DelayN *unit, int inNumSamples);
390 void DelayN_next_a(DelayN *unit, int inNumSamples);
391 void DelayN_next_a_z(DelayN *unit, int inNumSamples);
393 void DelayL_Ctor(DelayL *unit);
394 void DelayL_next(DelayL *unit, int inNumSamples);
395 void DelayL_next_z(DelayL *unit, int inNumSamples);
396 void DelayL_next_a(DelayL *unit, int inNumSamples);
397 void DelayL_next_a_z(DelayL *unit, int inNumSamples);
399 void DelayC_Ctor(DelayC *unit);
400 void DelayC_next(DelayC *unit, int inNumSamples);
401 void DelayC_next_z(DelayC *unit, int inNumSamples);
402 void DelayC_next_a(DelayC *unit, int inNumSamples);
403 void DelayC_next_a_z(DelayC *unit, int inNumSamples);
405 void CombN_Ctor(CombN *unit);
406 void CombN_next(CombN *unit, int inNumSamples);
407 void CombN_next_z(CombN *unit, int inNumSamples);
408 void CombN_next_a(CombN *unit, int inNumSamples);
409 void CombN_next_a_z(CombN *unit, int inNumSamples);
411 void CombL_Ctor(CombL *unit);
412 void CombL_next(CombL *unit, int inNumSamples);
413 void CombL_next_z(CombL *unit, int inNumSamples);
414 void CombL_next_a(CombL *unit, int inNumSamples);
415 void CombL_next_a_z(CombL *unit, int inNumSamples);
417 void CombC_Ctor(CombC *unit);
418 void CombC_next(CombC *unit, int inNumSamples);
419 void CombC_next_z(CombC *unit, int inNumSamples);
420 void CombC_next_a(CombC *unit, int inNumSamples);
421 void CombC_next_a_z(CombC *unit, int inNumSamples);
423 void AllpassN_Ctor(AllpassN *unit);
424 void AllpassN_next(AllpassN *unit, int inNumSamples);
425 void AllpassN_next_z(AllpassN *unit, int inNumSamples);
426 void AllpassN_next_a(AllpassN *unit, int inNumSamples);
427 void AllpassN_next_a_z(AllpassN *unit, int inNumSamples);
429 void AllpassL_Ctor(AllpassL *unit);
430 void AllpassL_next(AllpassL *unit, int inNumSamples);
431 void AllpassL_next_z(AllpassL *unit, int inNumSamples);
432 void AllpassL_next_a(AllpassL *unit, int inNumSamples);
433 void AllpassL_next_a_z(AllpassL *unit, int inNumSamples);
435 void AllpassC_Ctor(AllpassC *unit);
436 void AllpassC_next(AllpassC *unit, int inNumSamples);
437 void AllpassC_next_z(AllpassC *unit, int inNumSamples);
438 void AllpassC_next_a(AllpassC *unit, int inNumSamples);
439 void AllpassC_next_a_z(AllpassC *unit, int inNumSamples);
441 void ScopeOut_next(ScopeOut *unit, int inNumSamples);
442 void ScopeOut_Ctor(ScopeOut *unit);
443 void ScopeOut_Dtor(ScopeOut *unit);
445 void Pluck_Ctor(Pluck* unit);
446 void Pluck_next_aa(Pluck *unit, int inNumSamples);
447 void Pluck_next_aa_z(Pluck *unit, int inNumSamples);
448 void Pluck_next_kk(Pluck *unit, int inNumSamples);
449 void Pluck_next_kk_z(Pluck *unit, int inNumSamples);
450 void Pluck_next_ka(Pluck *unit, int inNumSamples);
451 void Pluck_next_ka_z(Pluck *unit, int inNumSamples);
452 void Pluck_next_ak(Pluck *unit, int inNumSamples);
453 void Pluck_next_ak_z(Pluck *unit, int inNumSamples);
455 void DelTapWr_Ctor(DelTapWr* unit);
456 void DelTapWr_next(DelTapWr *unit, int inNumSamples);
457 void DelTapWr_next_simd(DelTapWr *unit, int inNumSamples);
459 void DelTapRd_Ctor(DelTapRd* unit);
460 void DelTapRd_next1_a(DelTapRd *unit, int inNumSamples);
461 void DelTapRd_next2_a(DelTapRd *unit, int inNumSamples);
462 void DelTapRd_next4_a(DelTapRd *unit, int inNumSamples);
463 void DelTapRd_next1_k(DelTapRd *unit, int inNumSamples);
464 void DelTapRd_next1_k_simd(DelTapRd *unit, int inNumSamples);
465 void DelTapRd_next2_k(DelTapRd *unit, int inNumSamples);
466 void DelTapRd_next4_k(DelTapRd *unit, int inNumSamples);
469 //////////////////////////////////////////////////////////////////////////////////////////////////
471 void SampleRate_Ctor(Unit *unit, int inNumSamples)
473 ZOUT0(0) = unit->mWorld->mSampleRate;
477 void ControlRate_Ctor(Unit *unit, int inNumSamples)
479 ZOUT0(0) = unit->mWorld->mBufRate.mSampleRate;
483 void SampleDur_Ctor(Unit *unit, int inNumSamples)
485 ZOUT0(0) = unit->mWorld->mFullRate.mSampleDur;
488 void ControlDur_Ctor(Unit *unit, int inNumSamples)
490 ZOUT0(0) = unit->mWorld->mFullRate.mBufDuration;
493 void RadiansPerSample_Ctor(Unit *unit, int inNumSamples)
495 ZOUT0(0) = unit->mWorld->mFullRate.mRadiansPerSample;
498 void SubsampleOffset_Ctor(Unit *unit, int inNumSamples)
500 ZOUT0(0) = unit->mParent->mSubsampleOffset;
504 void NumInputBuses_Ctor(Unit *unit, int inNumSamples)
506 ZOUT0(0) = unit->mWorld->mNumInputs;
509 void NumOutputBuses_Ctor(Unit *unit, int inNumSamples)
511 ZOUT0(0) = unit->mWorld->mNumOutputs;
514 void NumAudioBuses_Ctor(Unit *unit, int inNumSamples)
516 ZOUT0(0) = unit->mWorld->mNumAudioBusChannels;
519 void NumControlBuses_Ctor(Unit *unit, int inNumSamples)
521 ZOUT0(0) = unit->mWorld->mNumControlBusChannels;
524 void NumBuffers_Ctor(Unit *unit, int inNumSamples)
526 ZOUT0(0) = unit->mWorld->mNumSndBufs;
529 //////////////////////////////////////////////////////////////////////////////////////////////////
531 void NumRunningSynths_Ctor(Unit *unit, int inNumSamples)
533 if(INRATE(0) != calc_ScalarRate) { SETCALC(NumRunningSynths_next); }
534 ZOUT0(0) = unit->mWorld->mNumGraphs;
537 void NumRunningSynths_next(Unit *unit, int inNumSamples)
539 ZOUT0(0) = unit->mWorld->mNumGraphs;
543 //////////////////////////////////////////////////////////////////////////////////////////////////
546 #define CTOR_GET_BUF \
547 float fbufnum = ZIN0(0); \
548 fbufnum = sc_max(0.f, fbufnum); \
549 uint32 bufnum = (int)fbufnum; \
550 World *world = unit->mWorld; \
551 SndBuf *buf; \
552 if (bufnum >= world->mNumSndBufs) { \
553 int localBufNum = bufnum - world->mNumSndBufs; \
554 Graph *parent = unit->mParent; \
555 if(localBufNum <= parent->localBufNum) { \
556 buf = parent->mLocalSndBufs + localBufNum; \
557 } else { \
558 bufnum = 0; \
559 buf = world->mSndBufs + bufnum; \
561 } else { \
562 buf = world->mSndBufs + bufnum; \
565 void BufSampleRate_next(BufInfoUnit *unit, int inNumSamples)
567 SIMPLE_GET_BUF_SHARED
568 ZOUT0(0) = buf->samplerate;
571 void BufSampleRate_Ctor(BufInfoUnit *unit, int inNumSamples)
573 SETCALC(BufSampleRate_next);
574 CTOR_GET_BUF
575 unit->m_fbufnum = fbufnum;
576 unit->m_buf = buf;
577 ZOUT0(0) = buf->samplerate;
581 void BufFrames_next(BufInfoUnit *unit, int inNumSamples)
583 SIMPLE_GET_BUF_SHARED
584 ZOUT0(0) = buf->frames;
587 void BufFrames_Ctor(BufInfoUnit *unit, int inNumSamples)
589 SETCALC(BufFrames_next);
590 CTOR_GET_BUF
591 unit->m_fbufnum = fbufnum;
592 unit->m_buf = buf;
593 ZOUT0(0) = buf->frames;
597 void BufDur_next(BufInfoUnit *unit, int inNumSamples)
599 SIMPLE_GET_BUF_SHARED
600 ZOUT0(0) = buf->frames * buf->sampledur;
603 void BufDur_Ctor(BufInfoUnit *unit, int inNumSamples)
605 SETCALC(BufDur_next);
606 CTOR_GET_BUF
607 unit->m_fbufnum = fbufnum;
608 unit->m_buf = buf;
609 ZOUT0(0) = buf->frames * buf->sampledur;
613 void BufChannels_next(BufInfoUnit *unit, int inNumSamples)
615 SIMPLE_GET_BUF_SHARED
616 ZOUT0(0) = buf->channels;
619 void BufChannels_Ctor(BufInfoUnit *unit, int inNumSamples)
621 SETCALC(BufChannels_next);
622 CTOR_GET_BUF
623 unit->m_fbufnum = fbufnum;
624 unit->m_buf = buf;
625 ZOUT0(0) = buf->channels;
629 void BufSamples_next(BufInfoUnit *unit, int inNumSamples)
631 SIMPLE_GET_BUF_SHARED
632 ZOUT0(0) = buf->samples;
635 void BufSamples_Ctor(BufInfoUnit *unit, int inNumSamples)
637 SETCALC(BufSamples_next);
638 CTOR_GET_BUF
639 unit->m_fbufnum = fbufnum;
640 unit->m_buf = buf;
641 ZOUT0(0) = buf->samples;
645 void BufRateScale_next(BufInfoUnit *unit, int inNumSamples)
647 SIMPLE_GET_BUF_SHARED
648 ZOUT0(0) = buf->samplerate * unit->mWorld->mFullRate.mSampleDur;
651 void BufRateScale_Ctor(BufInfoUnit *unit, int inNumSamples)
653 SETCALC(BufRateScale_next);
654 CTOR_GET_BUF
655 unit->m_fbufnum = fbufnum;
656 unit->m_buf = buf;
657 ZOUT0(0) = buf->samplerate * unit->mWorld->mFullRate.mSampleDur;
660 //////////////////////////////////////////////////////////////////////////////////////////////////
662 inline int32 BUFMASK(int32 x)
664 return (1 << (31 - CLZ(x))) - 1;
668 static void LocalBuf_allocBuffer(LocalBuf *unit, SndBuf *buf, int numChannels, int numFrames)
670 int numSamples = numFrames * numChannels;
671 // Print("bufnum: %i, allocating %i channels and %i frames. memsize: %i\n", (int)unit->m_fbufnum, numChannels, numFrames, numSamples * sizeof(float));
672 buf->data = (float*)RTAlloc(unit->mWorld, numSamples * sizeof(float));
674 if (!buf->data) {
675 if(unit->mWorld->mVerbosity > -2){
676 Print("failed to allocate memory for LocalBuffer\n");
678 return;
681 buf->channels = numChannels;
682 buf->frames = numFrames;
683 buf->samples = numSamples;
684 buf->mask = BUFMASK(numSamples); // for delay lines
685 buf->mask1 = buf->mask - 1; // for oscillators
686 buf->samplerate = unit->mWorld->mSampleRate;
687 buf->sampledur = 1. / buf->samplerate;
688 #if SUPERNOVA
689 buf->isLocal = true;
690 #endif
696 void LocalBuf_Ctor(LocalBuf *unit)
698 Graph *parent = unit->mParent;
700 int offset = unit->mWorld->mNumSndBufs;
701 int bufnum = parent->localBufNum;
702 float fbufnum;
704 if (parent->localBufNum >= parent->localMaxBufNum) {
705 fbufnum = -1.f;
706 if(unit->mWorld->mVerbosity > -2)
707 printf("warning: LocalBuf tried to allocate too many local buffers.\n");
708 } else {
709 fbufnum = (float) (bufnum + offset);
710 unit->m_buf = parent->mLocalSndBufs + bufnum;
711 parent->localBufNum = parent->localBufNum + 1;
713 LocalBuf_allocBuffer(unit, unit->m_buf, (int)IN0(0), (int)IN0(1));
716 OUT0(0) = fbufnum;
719 void LocalBuf_Dtor(LocalBuf *unit)
721 RTFree(unit->mWorld, unit->m_buf->data);
722 if(unit->mParent->localBufNum <= 1) { // only the last time.
723 for (int i = 0; i != unit->mParent->localMaxBufNum; ++i)
724 unit->mParent->mLocalSndBufs[i].~SndBuf();
725 RTFree(unit->mWorld, unit->mParent->mLocalSndBufs);
726 unit->mParent->localMaxBufNum = 0;
727 } else {
728 unit->mParent->localBufNum = unit->mParent->localBufNum - 1;
733 //////////////////////////////////////////////////////////////////////////////////////////////////
735 void MaxLocalBufs_Ctor(MaxLocalBufs *unit)
737 Graph *parent = unit->mParent;
739 int offset = unit->mWorld->mNumSndBufs;
740 int bufnum = parent->localBufNum;
741 int maxBufNum = (int)(IN0(0) + .5f);
742 if(!parent->localMaxBufNum) {
743 parent->mLocalSndBufs = (SndBuf*)RTAlloc(unit->mWorld, maxBufNum * sizeof(SndBuf));
744 #ifdef SUPERNOVA
745 for (int i = 0; i != maxBufNum; ++i)
746 new(&parent->mLocalSndBufs[i]) SndBuf();
747 #endif
748 parent->localMaxBufNum = maxBufNum;
749 } else {
750 printf("warning: MaxLocalBufs - maximum number of local buffers is already declared (%i) and must remain unchanged.\n", parent->localMaxBufNum);
755 //////////////////////////////////////////////////////////////////////////////////////////////////
757 void SetBuf_Ctor(SetBuf *unit)
759 OUT0(0) = 0.f;
760 CTOR_GET_BUF
761 if (!buf || !buf->data) {
762 if(unit->mWorld->mVerbosity > -2){
763 Print("SetBuf: no valid buffer\n");
765 return;
768 int offset = (int)IN0(1);
769 int numArgs = (int)IN0(2);
770 int end = sc_min(buf->samples, numArgs + offset);
772 int j = 3;
773 for(int i=offset; i<end; ++j, ++i) {
774 buf->data[i] = IN0(j);
779 //////////////////////////////////////////////////////////////////////////////////////////////////
781 void ClearBuf_Ctor(ClearBuf *unit)
783 OUT0(0) = 0.f;
784 CTOR_GET_BUF
786 if (!buf || !buf->data) {
787 if(unit->mWorld->mVerbosity > -2){
788 Print("ClearBuf: no valid buffer\n");
790 return;
793 Clear(buf->samples, buf->data);
797 ////////////////////////////////////////////////////////////////////////////////////////////////////////
799 inline double sc_loop(Unit *unit, double in, double hi, int loop)
801 // avoid the divide if possible
802 if (in >= hi) {
803 if (!loop) {
804 unit->mDone = true;
805 return hi;
807 in -= hi;
808 if (in < hi) return in;
809 } else if (in < 0.) {
810 if (!loop) {
811 unit->mDone = true;
812 return 0.;
814 in += hi;
815 if (in >= 0.) return in;
816 } else return in;
818 return in - hi * floor(in/hi);
821 #define CHECK_BUF \
822 if (!bufData) { \
823 unit->mDone = true; \
824 ClearUnitOutputs(unit, inNumSamples); \
825 return; \
828 static inline bool checkBuffer(Unit * unit, const float * bufData, uint32 bufChannels,
829 uint32 expectedChannels, int inNumSamples)
831 if (!bufData)
832 goto handle_failure;
834 if (expectedChannels > bufChannels) {
835 if(unit->mWorld->mVerbosity > -1 && !unit->mDone)
836 Print("Buffer UGen channel mismatch: expected %i, yet buffer has %i channels\n",
837 expectedChannels, bufChannels);
838 goto handle_failure;
840 return true;
842 handle_failure:
843 unit->mDone = true;
844 ClearUnitOutputs(unit, inNumSamples);
845 return false;
848 #define SETUP_IN(offset) \
849 uint32 numInputs = unit->mNumInputs - (uint32)offset; \
850 if (numInputs != bufChannels) { \
851 if(unit->mWorld->mVerbosity > -1 && !unit->mDone){ \
852 Print("buffer-writing UGen channel mismatch: numInputs %i, yet buffer has %i channels\n", numInputs, bufChannels); \
854 unit->mDone = true; \
855 ClearUnitOutputs(unit, inNumSamples); \
856 return; \
858 if(!unit->mIn){ \
859 unit->mIn = (float**)RTAlloc(unit->mWorld, numInputs * sizeof(float*)); \
860 if (unit->mIn == NULL) { \
861 unit->mDone = true; \
862 ClearUnitOutputs(unit, inNumSamples); \
863 return; \
866 float **in = unit->mIn; \
867 for (uint32 i=0; i<numInputs; ++i) { \
868 in[i] = ZIN(i+offset); \
871 #define TAKEDOWN_IN \
872 if(unit->mIn){ \
873 RTFree(unit->mWorld, unit->mIn); \
877 #define LOOP_BODY_4(SAMPLE_INDEX) \
878 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
879 int32 iphase = (int32)phase; \
880 const float* table1 = bufData + iphase * bufChannels; \
881 const float* table0 = table1 - bufChannels; \
882 const float* table2 = table1 + bufChannels; \
883 const float* table3 = table2 + bufChannels; \
884 if (iphase == 0) { \
885 if (loop) { \
886 table0 += bufSamples; \
887 } else { \
888 table0 += bufChannels; \
890 } else if (iphase >= guardFrame) { \
891 if (iphase == guardFrame) { \
892 if (loop) { \
893 table3 -= bufSamples; \
894 } else { \
895 table3 -= bufChannels; \
897 } else { \
898 if (loop) { \
899 table2 -= bufSamples; \
900 table3 -= bufSamples; \
901 } else { \
902 table2 -= bufChannels; \
903 table3 -= 2 * bufChannels; \
907 int32 index = 0; \
908 float fracphase = phase - (double)iphase; \
909 for (uint32 channel=0; channel<numOutputs; ++channel) { \
910 float a = table0[index]; \
911 float b = table1[index]; \
912 float c = table2[index]; \
913 float d = table3[index]; \
914 OUT(channel)[SAMPLE_INDEX] = cubicinterp(fracphase, a, b, c, d); \
915 index++; \
918 #define LOOP_BODY_2(SAMPLE_INDEX) \
919 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
920 int32 iphase = (int32)phase; \
921 const float* table1 = bufData + iphase * bufChannels; \
922 const float* table2 = table1 + bufChannels; \
923 if (iphase > guardFrame) { \
924 if (loop) { \
925 table2 -= bufSamples; \
926 } else { \
927 table2 -= bufChannels; \
930 int32 index = 0; \
931 float fracphase = phase - (double)iphase; \
932 for (uint32 channel=0; channel<numOutputs; ++channel) { \
933 float b = table1[index]; \
934 float c = table2[index]; \
935 OUT(channel)[SAMPLE_INDEX] = b + fracphase * (c - b); \
936 index++; \
939 #define LOOP_BODY_1(SAMPLE_INDEX) \
940 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
941 int32 iphase = (int32)phase; \
942 const float* table1 = bufData + iphase * bufChannels; \
943 int32 index = 0; \
944 for (uint32 channel=0; channel<numOutputs; ++channel) { \
945 OUT(channel)[SAMPLE_INDEX] = table1[index++]; \
949 void PlayBuf_Ctor(PlayBuf *unit)
951 if (INRATE(1) == calc_FullRate) {
952 if (INRATE(2) == calc_FullRate) {
953 SETCALC(PlayBuf_next_aa);
954 } else {
955 SETCALC(PlayBuf_next_ak);
957 } else {
958 if (INRATE(2) == calc_FullRate) {
959 SETCALC(PlayBuf_next_ka);
960 } else {
961 SETCALC(PlayBuf_next_kk);
965 unit->m_fbufnum = -1e9f;
966 unit->m_prevtrig = 0.;
967 unit->m_phase = ZIN0(3);
969 ClearUnitOutputs(unit, 1);
972 void PlayBuf_next_aa(PlayBuf *unit, int inNumSamples)
974 float *ratein = ZIN(1);
975 float *trigin = ZIN(2);
976 int32 loop = (int32)ZIN0(4);
978 float fbufnum = ZIN0(0);
979 if (fbufnum != unit->m_fbufnum) {
980 uint32 bufnum = (int)fbufnum;
981 World *world = unit->mWorld;
982 if (bufnum >= world->mNumSndBufs) bufnum = 0;
983 unit->m_fbufnum = fbufnum;
984 unit->m_buf = world->mSndBufs + bufnum;
986 const SndBuf *buf = unit->m_buf;
987 ACQUIRE_SNDBUF_SHARED(buf);
988 const float *bufData __attribute__((__unused__)) = buf->data;
989 uint32 bufChannels __attribute__((__unused__)) = buf->channels;
990 uint32 bufSamples __attribute__((__unused__)) = buf->samples;
991 uint32 bufFrames = buf->frames;
992 int mask __attribute__((__unused__)) = buf->mask;
993 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
995 int numOutputs = unit->mNumOutputs;
996 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
997 return;
999 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1000 double phase = unit->m_phase;
1001 float prevtrig = unit->m_prevtrig;
1003 for (int i=0; i<inNumSamples; ++i) {
1004 float trig = ZXP(trigin);
1005 if (trig > 0.f && prevtrig <= 0.f) {
1006 unit->mDone = false;
1007 phase = ZIN0(3);
1009 prevtrig = trig;
1011 LOOP_BODY_4(i)
1013 phase += ZXP(ratein);
1015 RELEASE_SNDBUF_SHARED(buf);
1017 if(unit->mDone)
1018 DoneAction((int)ZIN0(5), unit);
1019 unit->m_phase = phase;
1020 unit->m_prevtrig = prevtrig;
1023 void PlayBuf_next_ak(PlayBuf *unit, int inNumSamples)
1025 float *ratein = ZIN(1);
1026 float trig = ZIN0(2);
1027 int32 loop = (int32)ZIN0(4);
1029 float fbufnum = ZIN0(0);
1030 if (fbufnum != unit->m_fbufnum) {
1031 uint32 bufnum = (int)fbufnum;
1032 World *world = unit->mWorld;
1033 if (bufnum >= world->mNumSndBufs) bufnum = 0;
1034 unit->m_fbufnum = fbufnum;
1035 unit->m_buf = world->mSndBufs + bufnum;
1037 const SndBuf *buf = unit->m_buf;
1038 ACQUIRE_SNDBUF_SHARED(buf);
1039 const float *bufData __attribute__((__unused__)) = buf->data;
1040 uint32 bufChannels __attribute__((__unused__)) = buf->channels;
1041 uint32 bufSamples __attribute__((__unused__)) = buf->samples;
1042 uint32 bufFrames = buf->frames;
1043 int mask __attribute__((__unused__)) = buf->mask;
1044 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
1046 int numOutputs = unit->mNumOutputs;
1047 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1048 return;
1050 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1051 double phase = unit->m_phase;
1052 if(phase == -1.) phase = bufFrames;
1053 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1054 unit->mDone = false;
1055 phase = ZIN0(3);
1057 unit->m_prevtrig = trig;
1058 for (int i=0; i<inNumSamples; ++i) {
1060 LOOP_BODY_4(i)
1062 phase += ZXP(ratein);
1064 RELEASE_SNDBUF_SHARED(buf);
1065 if(unit->mDone)
1066 DoneAction((int)ZIN0(5), unit);
1067 unit->m_phase = phase;
1070 void PlayBuf_next_kk(PlayBuf *unit, int inNumSamples)
1072 float rate = ZIN0(1);
1073 float trig = ZIN0(2);
1074 int32 loop = (int32)ZIN0(4);
1076 GET_BUF_SHARED
1077 int numOutputs = unit->mNumOutputs;
1078 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1079 return;
1081 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1082 double phase = unit->m_phase;
1083 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1084 unit->mDone = false;
1085 phase = ZIN0(3);
1087 unit->m_prevtrig = trig;
1088 for (int i=0; i<inNumSamples; ++i) {
1089 LOOP_BODY_4(i)
1091 phase += rate;
1093 if(unit->mDone)
1094 DoneAction((int)ZIN0(5), unit);
1095 unit->m_phase = phase;
1098 void PlayBuf_next_ka(PlayBuf *unit, int inNumSamples)
1100 float rate = ZIN0(1);
1101 float *trigin = ZIN(2);
1102 int32 loop = (int32)ZIN0(4);
1104 GET_BUF_SHARED
1105 int numOutputs = unit->mNumOutputs;
1106 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1107 return;
1109 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1110 double phase = unit->m_phase;
1111 float prevtrig = unit->m_prevtrig;
1112 for (int i=0; i<inNumSamples; ++i) {
1113 float trig = ZXP(trigin);
1114 if (trig > 0.f && prevtrig <= 0.f) {
1115 unit->mDone = false;
1116 if (INRATE(3) == calc_FullRate) phase = IN(3)[i];
1117 else phase = ZIN0(3);
1119 prevtrig = trig;
1121 LOOP_BODY_4(i)
1123 phase += rate;
1125 if(unit->mDone)
1126 DoneAction((int)ZIN0(5), unit);
1127 unit->m_phase = phase;
1128 unit->m_prevtrig = prevtrig;
1132 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1134 void BufRd_Ctor(BufRd *unit)
1136 int interp = (int)ZIN0(3);
1137 switch (interp) {
1138 case 1 : SETCALC(BufRd_next_1); break;
1139 case 2 : SETCALC(BufRd_next_2); break;
1140 default : SETCALC(BufRd_next_4); break;
1143 unit->m_fbufnum = -1e9f;
1145 BufRd_next_1(unit, 1);
1148 void BufRd_next_4(BufRd *unit, int inNumSamples)
1150 float *phasein = ZIN(1);
1151 int32 loop = (int32)ZIN0(2);
1153 GET_BUF_SHARED
1154 uint32 numOutputs = unit->mNumOutputs;
1155 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1156 return;
1158 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1160 for (int i=0; i<inNumSamples; ++i) {
1161 double phase = ZXP(phasein);
1162 LOOP_BODY_4(i)
1166 void BufRd_next_2(BufRd *unit, int inNumSamples)
1168 float *phasein = ZIN(1);
1169 int32 loop = (int32)ZIN0(2);
1171 GET_BUF_SHARED
1172 uint32 numOutputs = unit->mNumOutputs;
1173 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1174 return;
1176 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1178 for (int i=0; i<inNumSamples; ++i) {
1179 double phase = ZXP(phasein);
1180 LOOP_BODY_2(i)
1184 void BufRd_next_1(BufRd *unit, int inNumSamples)
1186 float *phasein = ZIN(1);
1187 int32 loop = (int32)ZIN0(2);
1189 GET_BUF_SHARED
1190 uint32 numOutputs = unit->mNumOutputs;
1191 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1192 return;
1194 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1196 for (int i=0; i<inNumSamples; ++i) {
1197 double phase = ZXP(phasein);
1198 LOOP_BODY_1(i)
1202 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1204 void BufWr_Ctor(BufWr *unit)
1206 SETCALC(BufWr_next);
1208 unit->m_fbufnum = -1e9f;
1210 ClearUnitOutputs(unit, 1);
1213 void BufWr_next(BufWr *unit, int inNumSamples)
1215 float *phasein = ZIN(1);
1216 int32 loop = (int32)ZIN0(2);
1218 GET_BUF
1219 uint32 numInputChannels = unit->mNumInputs - 3;
1220 if (!checkBuffer(unit, bufData, bufChannels, numInputChannels, inNumSamples))
1221 return;
1223 double loopMax = (double)(bufFrames - (loop ? 0 : 1));
1225 for (int32 k=0; k<inNumSamples; ++k) {
1226 double phase = sc_loop((Unit*)unit, ZXP(phasein), loopMax, loop);
1227 int32 iphase = (int32)phase;
1228 float* table0 = bufData + iphase * bufChannels;
1229 for (uint32 channel=0; channel<numInputChannels; ++channel)
1230 table0[channel] = IN(channel+3)[k];
1234 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1236 //bufnum=0, offset=0.0, recLevel=1.0, preLevel=0.0, run=1.0, loop=1.0, trigger=1.0
1238 void RecordBuf_Ctor(RecordBuf *unit)
1241 uint32 numInputs = unit->mNumInputs - 8;
1242 unit->m_fbufnum = -1e9f;
1243 unit->mIn = 0;
1244 unit->m_writepos = (int32)ZIN0(1) * numInputs;
1245 unit->m_recLevel = ZIN0(2);
1246 unit->m_preLevel = ZIN0(3);
1248 if (INRATE(2) == calc_ScalarRate && INRATE(3) == calc_ScalarRate
1249 && unit->m_recLevel == 1.0 && unit->m_preLevel == 0.0)
1251 SETCALC(RecordBuf_next_10);
1252 } else {
1253 SETCALC(RecordBuf_next);
1256 ClearUnitOutputs(unit, 1);
1259 void RecordBuf_Dtor(RecordBuf *unit)
1261 TAKEDOWN_IN
1264 void RecordBuf_next(RecordBuf *unit, int inNumSamples)
1266 //printf("RecordBuf_next\n");
1267 GET_BUF
1268 CHECK_BUF
1269 SETUP_IN(8)
1271 float recLevel = ZIN0(2);
1272 float preLevel = ZIN0(3);
1273 float run = ZIN0(4);
1274 int32 loop = (int32)ZIN0(5);
1275 float trig = ZIN0(6);
1276 //printf("loop %d run %g\n", loop, run);
1278 int32 writepos = unit->m_writepos;
1280 float recLevel_slope = CALCSLOPE(recLevel, unit->m_recLevel);
1281 float preLevel_slope = CALCSLOPE(preLevel, unit->m_preLevel);
1283 /* reset recLevel and preLevel to use the previous value ... bug fix */
1284 recLevel = unit->m_recLevel;
1285 preLevel = unit->m_preLevel;
1287 if (loop) {
1288 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1289 unit->mDone = false;
1290 writepos = (int32)ZIN0(1) * bufChannels;
1292 if (writepos < 0) writepos = bufSamples - bufChannels;
1293 else if (writepos >= (int32)bufSamples) writepos = 0;
1294 if (run > 0.f) {
1295 if (bufChannels == 1) {
1296 for (int32 k=0; k<inNumSamples; ++k) {
1297 float* table0 = bufData + writepos;
1298 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1299 writepos += 1;
1300 if (writepos >= (int32)bufSamples) writepos = 0;
1302 recLevel += recLevel_slope;
1303 preLevel += preLevel_slope;
1305 } else if (bufChannels == 2 && numInputs == 2) {
1306 for (int32 k=0; k<inNumSamples; ++k) {
1307 float* table0 = bufData + writepos;
1308 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1309 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1310 writepos += 2;
1311 if (writepos >= (int32)bufSamples) writepos = 0;
1313 recLevel += recLevel_slope;
1314 preLevel += preLevel_slope;
1316 } else {
1317 for (int32 k=0; k<inNumSamples; ++k) {
1318 float* table0 = bufData + writepos;
1319 for (uint32 i=0; i<numInputs; ++i) {
1320 float *samp = table0 + i;
1321 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1323 writepos += bufChannels;
1324 if (writepos >= (int32)bufSamples) writepos = 0;
1326 recLevel += recLevel_slope;
1327 preLevel += preLevel_slope;
1330 } else if (run < 0.f) {
1331 if (bufChannels == 1) {
1332 for (int32 k=0; k<inNumSamples; ++k) {
1333 float* table0 = bufData + writepos;
1334 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1335 writepos -= 1;
1336 if (writepos < 0) writepos = bufSamples - bufChannels;
1338 recLevel += recLevel_slope;
1339 preLevel += preLevel_slope;
1341 } else if (bufChannels == 2 && numInputs == 2) {
1342 for (int32 k=0; k<inNumSamples; ++k) {
1343 float* table0 = bufData + writepos;
1344 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1345 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1346 writepos -= 2;
1347 if (writepos < 0) writepos = bufSamples - bufChannels;
1349 recLevel += recLevel_slope;
1350 preLevel += preLevel_slope;
1352 } else {
1353 for (int32 k=0; k<inNumSamples; ++k) {
1354 float* table0 = bufData + writepos;
1355 for (uint32 i=0; i<numInputs; ++i) {
1356 float *samp = table0 + i;
1357 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1359 writepos -= bufChannels;
1360 if (writepos < 0) writepos = bufSamples - bufChannels;
1362 recLevel += recLevel_slope;
1363 preLevel += preLevel_slope;
1367 } else {
1368 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1369 unit->mDone = false;
1370 writepos = (int32)ZIN0(1) * bufChannels;
1372 if (run > 0.f) {
1373 int nsmps = bufSamples - writepos;
1374 nsmps = sc_clip(nsmps, 0, inNumSamples);
1375 if (bufChannels == 1) {
1376 for (int32 k=0; k<nsmps; ++k) {
1377 float* table0 = bufData + writepos;
1378 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1379 writepos += 1;
1381 recLevel += recLevel_slope;
1382 preLevel += preLevel_slope;
1384 } else if (bufChannels == 2 && numInputs == 2) {
1385 for (int32 k=0; k<nsmps; ++k) {
1386 float* table0 = bufData + writepos;
1387 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1388 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1389 writepos += 2;
1391 recLevel += recLevel_slope;
1392 preLevel += preLevel_slope;
1394 } else {
1395 for (int32 k=0; k<nsmps; ++k) {
1396 float* table0 = bufData + writepos;
1397 for (uint32 i=0; i<numInputs; ++i) {
1398 float *samp = table0 + i;
1399 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1401 writepos += bufChannels;
1403 recLevel += recLevel_slope;
1404 preLevel += preLevel_slope;
1407 } else if (run < 0.f) {
1408 int nsmps = writepos;
1409 nsmps = sc_clip(nsmps, 0, inNumSamples);
1410 if (bufChannels == 1) {
1411 for (int32 k=0; k<inNumSamples; ++k) {
1412 float* table0 = bufData + writepos;
1413 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1414 writepos -= bufChannels;
1416 recLevel += recLevel_slope;
1417 preLevel += preLevel_slope;
1419 } else if (bufChannels == 2 && numInputs == 2) {
1420 for (int32 k=0; k<inNumSamples; ++k) {
1421 float* table0 = bufData + writepos;
1422 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1423 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1424 writepos -= bufChannels;
1426 recLevel += recLevel_slope;
1427 preLevel += preLevel_slope;
1429 } else {
1430 for (int32 k=0; k<inNumSamples; ++k) {
1431 float* table0 = bufData + writepos;
1432 for (uint32 i=0; i<numInputs; ++i) {
1433 float *samp = table0 + i;
1434 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1436 writepos -= bufChannels;
1438 recLevel += recLevel_slope;
1439 preLevel += preLevel_slope;
1443 if (writepos >= (int32)bufSamples){
1444 unit->mDone = true;
1445 DoneAction(IN0(7), unit);
1448 unit->m_prevtrig = trig;
1449 unit->m_writepos = writepos;
1450 unit->m_recLevel = recLevel;
1451 unit->m_preLevel = preLevel;
1454 void RecordBuf_next_10(RecordBuf *unit, int inNumSamples)
1456 // printf("RecordBuf_next_10\n");
1457 GET_BUF
1458 CHECK_BUF
1459 SETUP_IN(8)
1461 float run = ZIN0(4);
1462 int32 loop = (int32)ZIN0(5);
1463 float trig = ZIN0(6);
1464 //printf("loop %d run %g\n", loop, run);
1466 int32 writepos = unit->m_writepos;
1468 if (loop) {
1469 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1470 unit->mDone = false;
1471 writepos = (int32)ZIN0(1) * bufChannels;
1473 if (writepos < 0) writepos = bufSamples - bufChannels;
1474 else if (writepos >= (int32)bufSamples) writepos = 0;
1475 if (run > 0.f) {
1476 if (bufChannels == 1) {
1477 for (int32 k=0; k<inNumSamples; ++k) {
1478 float* table0 = bufData + writepos;
1479 table0[0] = *++(in[0]);
1480 writepos += 1;
1481 if (writepos >= (int32)bufSamples) writepos = 0;
1483 } else if (bufChannels == 2) {
1484 for (int32 k=0; k<inNumSamples; ++k) {
1485 float* table0 = bufData + writepos;
1486 table0[0] = *++(in[0]);
1487 table0[1] = *++(in[1]);
1488 writepos += 2;
1489 if (writepos >= (int32)bufSamples) writepos = 0;
1491 } else {
1492 for (int32 k=0; k<inNumSamples; ++k) {
1493 float* table0 = bufData + writepos;
1494 for (uint32 i=0; i<bufChannels; ++i) {
1495 float *samp = table0 + i;
1496 *samp = *++(in[i]);
1498 writepos += bufChannels;
1499 if (writepos >= (int32)bufSamples) writepos = 0;
1502 } else if (run < 0.f) {
1503 if (bufChannels == 1) {
1504 for (int32 k=0; k<inNumSamples; ++k) {
1505 float* table0 = bufData + writepos;
1506 table0[0] = *++(in[0]);
1507 writepos -= 1;
1508 if (writepos < 0) writepos = bufSamples - bufChannels;
1510 } else if (bufChannels == 2) {
1511 for (int32 k=0; k<inNumSamples; ++k) {
1512 float* table0 = bufData + writepos;
1513 table0[0] = *++(in[0]);
1514 table0[1] = *++(in[1]);
1515 writepos -= 2;
1516 if (writepos < 0) writepos = bufSamples - bufChannels;
1518 } else {
1519 for (int32 k=0; k<inNumSamples; ++k) {
1520 float* table0 = bufData + writepos;
1521 for (uint32 i=0; i<bufChannels; ++i) {
1522 float *samp = table0 + i;
1523 *samp = *++(in[i]);
1525 writepos -= bufChannels;
1526 if (writepos < 0) writepos = bufSamples - bufChannels;
1530 } else {
1531 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1532 unit->mDone = false;
1533 writepos = (int32)ZIN0(1) * bufChannels;
1535 if (run > 0.f) {
1536 int nsmps = bufSamples - writepos;
1537 nsmps = sc_clip(nsmps, 0, inNumSamples);
1538 if (bufChannels == 1) {
1539 for (int32 k=0; k<nsmps; ++k) {
1540 float* table0 = bufData + writepos;
1541 table0[0] = *++(in[0]);
1542 writepos += 1;
1544 } else if (bufChannels == 2) {
1545 for (int32 k=0; k<nsmps; ++k) {
1546 float* table0 = bufData + writepos;
1547 table0[0] = *++(in[0]);
1548 table0[1] = *++(in[1]);
1549 writepos += 2;
1550 if (writepos >= (int32)bufSamples) writepos = (int32)bufSamples - 2; // added by jrhb
1552 } else {
1553 for (int32 k=0; k<nsmps; ++k) {
1554 float* table0 = bufData + writepos;
1555 for (uint32 i=0; i<bufChannels; ++i) {
1556 float *samp = table0 + i;
1557 *samp = *++(in[i]);
1559 writepos += bufChannels;
1560 if (writepos >= (int32)bufSamples) writepos = (int32)bufSamples - bufChannels; // added by jrhb
1563 } else if (run < 0.f) {
1564 int nsmps = writepos;
1565 nsmps = sc_clip(nsmps, 0, inNumSamples);
1566 if (bufChannels == 1) {
1567 for (int32 k=0; k<inNumSamples; ++k) {
1568 float* table0 = bufData + writepos;
1569 table0[0] = *++(in[0]);
1570 writepos -= 1;
1572 } else if (bufChannels == 2) {
1573 for (int32 k=0; k<inNumSamples; ++k) {
1574 float* table0 = bufData + writepos;
1575 table0[0] = *++(in[0]);
1576 table0[1] = *++(in[1]);
1577 writepos -= 2;
1579 } else {
1580 for (int32 k=0; k<inNumSamples; ++k) {
1581 float* table0 = bufData + writepos;
1582 for (uint32 i=0; i<bufChannels; ++i) {
1583 float *samp = table0 + i;
1584 *samp = *++(in[i]);
1586 writepos -= bufChannels;
1590 if (writepos >= (int32)bufSamples){
1591 unit->mDone = true;
1592 DoneAction(IN0(7), unit);
1595 unit->m_prevtrig = trig;
1596 unit->m_writepos = writepos;
1600 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1602 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1606 static float insertMedian(float* values, int* ages, int size, float value)
1608 int pos=-1;
1610 // keeps a sorted list of the previous n=size values
1611 // the oldest is removed and the newest is inserted.
1612 // values between the oldest and the newest are shifted over by one.
1614 // values and ages are both arrays that are 'size' int.
1615 // the median value is always values[size>>1]
1617 int last = size - 1;
1618 // find oldest bin and age the other bins.
1619 for (int i=0; i<size; ++i) {
1620 if (ages[i] == last) { // is it the oldest bin ?
1621 pos = i;
1622 } else {
1623 ages[i]++; // age the bin
1626 // move values to fill in place of the oldest and make a space for the newest
1627 // search lower if value is too small for the open space
1628 while (pos != 0 && value < values[pos-1]) {
1629 values[pos] = values[pos-1];
1630 ages[pos] = ages[pos-1];
1631 pos--;
1633 // search higher if value is too big for the open space
1634 while (pos != last && value > values[pos+1]) {
1635 values[pos] = values[pos+1];
1636 ages[pos] = ages[pos+1];
1637 pos++;
1639 values[pos] = value;
1640 ages[pos] = 0; // this is the newest bin, age = 0
1641 return values[size>>1];
1644 static void initMedian(float* values, int* ages, int size, float value)
1646 // initialize the arrays with the first value
1647 for (int i=0; i<size; ++i) {
1648 values[i] = value;
1649 ages[i] = i;
1656 enum {
1657 kPitchIn,
1658 kPitchInitFreq,
1659 kPitchMinFreq,
1660 kPitchMaxFreq,
1661 kPitchExecFreq,
1662 kPitchMaxBins,
1663 kPitchMedian,
1664 kPitchAmpThreshold,
1665 kPitchPeakThreshold,
1666 kPitchDownsamp,
1667 kPitchGetClarity
1670 void Pitch_Ctor(Pitch *unit)
1672 unit->m_freq = ZIN0(kPitchInitFreq);
1673 unit->m_minfreq = ZIN0(kPitchMinFreq);
1674 unit->m_maxfreq = ZIN0(kPitchMaxFreq);
1676 float execfreq = ZIN0(kPitchExecFreq);
1677 execfreq = sc_clip(execfreq, unit->m_minfreq, unit->m_maxfreq);
1679 int maxbins = (int)ZIN0(kPitchMaxBins);
1680 unit->m_maxlog2bins = LOG2CEIL(maxbins);
1682 unit->m_medianSize = sc_clip((int)ZIN0(0), 0, kMAXMEDIANSIZE); // (int)ZIN0(kPitchMedian);
1683 unit->m_ampthresh = ZIN0(kPitchAmpThreshold);
1684 unit->m_peakthresh = ZIN0(kPitchPeakThreshold);
1686 int downsamp = (int)ZIN0(kPitchDownsamp);
1688 if (INRATE(kPitchIn) == calc_FullRate) {
1689 SETCALC(Pitch_next_a);
1690 unit->m_downsamp = sc_clip(downsamp, 1, unit->mWorld->mFullRate.mBufLength);
1691 unit->m_srate = FULLRATE / (float)unit->m_downsamp;
1692 } else {
1693 SETCALC(Pitch_next_k);
1694 unit->m_downsamp = sc_max(downsamp, 1);
1695 unit->m_srate = FULLRATE / (float) (unit->mWorld->mFullRate.mBufLength*unit->m_downsamp);
1698 unit->m_minperiod = (long)(unit->m_srate / unit->m_maxfreq);
1699 unit->m_maxperiod = (long)(unit->m_srate / unit->m_minfreq);
1701 unit->m_execPeriod = (int)(unit->m_srate / execfreq);
1702 unit->m_execPeriod = sc_max(unit->m_execPeriod, unit->mWorld->mFullRate.mBufLength);
1704 unit->m_size = sc_max(unit->m_maxperiod << 1, unit->m_execPeriod);
1706 unit->m_buffer = (float*)RTAlloc(unit->mWorld, unit->m_size * sizeof(float));
1708 unit->m_index = 0;
1709 unit->m_readp = 0;
1710 unit->m_hasfreq = 0.f;
1712 initMedian(unit->m_values, unit->m_ages, unit->m_medianSize, unit->m_freq);
1714 unit->m_getClarity = ZIN0(kPitchGetClarity) > 0.f;
1716 ZOUT0(0) = 0.f;
1717 ZOUT0(1) = 0.f;
1720 void Pitch_Dtor(Pitch *unit)
1722 RTFree(unit->mWorld, unit->m_buffer);
1725 void Pitch_next_a(Pitch *unit, int inNumSamples)
1727 bool foundPeak;
1729 float* in = ZIN(kPitchIn);
1730 uint32 size = unit->m_size;
1731 uint32 index = unit->m_index;
1732 int downsamp = unit->m_downsamp;
1733 int readp = unit->m_readp;
1734 int ksamps = unit->mWorld->mFullRate.mBufLength;
1736 float *bufData = unit->m_buffer;
1738 float freq = unit->m_freq;
1739 float hasfreq = unit->m_hasfreq;
1740 //printf("> %d %d readp %d ksamps %d ds %d\n", index, size, readp, ksamps, downsamp);
1741 do {
1742 float z = in[readp];
1743 bufData[index++] = z;
1744 readp += downsamp;
1746 if (index >= size) {
1747 float ampthresh = unit->m_ampthresh;
1748 bool ampok = false;
1750 hasfreq = 0.f; // assume failure
1752 int minperiod = unit->m_minperiod;
1753 int maxperiod = unit->m_maxperiod;
1754 //float maxamp = 0.f;
1755 // check for amp threshold
1756 for (int j = 0; j < maxperiod; ++j) {
1757 if (fabs(bufData[j]) >= ampthresh) {
1758 ampok = true;
1759 break;
1761 //if (fabs(bufData[j]) > maxamp) maxamp = fabs(bufData[j]);
1763 //printf("ampok %d maxperiod %d maxamp %g\n", ampok, maxperiod, maxamp);
1765 // if amplitude is too small then don't even look for pitch
1766 float ampsum;
1767 if (ampok) {
1768 int maxlog2bins = unit->m_maxlog2bins;
1769 int octave;
1770 // calculate the zero lag value and compute the threshold based on that
1771 float zerolagval = 0.f;
1772 for (int j = 0; j < maxperiod; ++j) {
1773 zerolagval += bufData[j] * bufData[j];
1775 float threshold = zerolagval * unit->m_peakthresh;
1777 // skip until drop below threshold
1778 int binstep, peakbinstep = 0;
1779 int i;
1780 for (i = 1; i <= maxperiod; i += binstep) {
1781 // compute sum of one lag
1782 ampsum = 0.f;
1783 for (int j = 0; j < maxperiod; ++j) {
1784 ampsum += bufData[i+j] * bufData[j];
1786 if (ampsum < threshold) break;
1788 octave = LOG2CEIL(i);
1789 if (octave <= maxlog2bins) {
1790 binstep = 1;
1791 } else {
1792 binstep = 1L << (octave - maxlog2bins);
1795 int startperiod = i;
1796 int period = startperiod;
1797 //printf("startperiod %d\n", startperiod);
1799 // find the first peak
1800 float maxsum = threshold;
1801 foundPeak = false;
1802 for (i = startperiod; i <= maxperiod; i += binstep) {
1803 if (i >= minperiod) {
1804 ampsum = 0.f;
1805 for (int j = 0; j < maxperiod; ++j) {
1806 ampsum += bufData[i+j] * bufData[j];
1808 if (ampsum > threshold) {
1809 if (ampsum > maxsum) {
1810 foundPeak = true;
1811 maxsum = ampsum;
1812 peakbinstep = binstep;
1813 period = i;
1815 } else if (foundPeak) break;
1817 octave = LOG2CEIL(i);
1818 if (octave <= maxlog2bins) {
1819 binstep = 1;
1820 } else {
1821 binstep = 1L << (octave - maxlog2bins);
1825 //printf("found %d thr %g maxs %g per %d bs %d\n", foundPeak, threshold, maxsum, period, peakbinstep);
1826 if (foundPeak) {
1827 float prevampsum, nextampsum;
1829 // find amp sums immediately surrounding max
1830 prevampsum = 0.f;
1831 if (period > 0) {
1832 i = period - 1;
1833 for (int j = 0; j < maxperiod; ++j) {
1834 prevampsum += bufData[i+j] * bufData[j];
1838 nextampsum = 0.f;
1839 if (period < maxperiod) {
1840 i = period + 1;
1841 for (int j = 0; j < maxperiod; ++j) {
1842 nextampsum += bufData[i+j] * bufData[j];
1846 //printf("prevnext %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1847 // not on a peak yet. This can happen if binstep > 1
1848 while (prevampsum > maxsum && period > 0) {
1849 nextampsum = maxsum;
1850 maxsum = prevampsum;
1851 period--;
1852 i = period - 1;
1853 prevampsum = 0.f;
1854 for (int j = 0; j < maxperiod; ++j) {
1855 prevampsum += bufData[i+j] * bufData[j];
1857 //printf("slide left %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1859 while (nextampsum > maxsum && period < maxperiod) {
1860 prevampsum = maxsum;
1861 maxsum = nextampsum;
1862 period++;
1863 i = period + 1;
1864 nextampsum = 0.f;
1865 for (int j = 0; j < maxperiod; ++j) {
1866 nextampsum += bufData[i+j] * bufData[j];
1868 //printf("slide right %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1871 // make a fractional period
1872 float beta = 0.5f * (nextampsum - prevampsum);
1873 float gamma = 2.f * maxsum - nextampsum - prevampsum;
1874 float fperiod = (float)period + (beta/gamma);
1876 // calculate frequency
1877 float tempfreq = unit->m_srate / fperiod;
1879 //printf("freq %g %g / %g %g %g %d\n", tempfreq, unit->m_srate, fperiod,
1880 // unit->m_minfreq, unit->m_maxfreq,
1881 // tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq);
1883 if (tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq) {
1884 freq = tempfreq;
1886 // median filter
1887 if (unit->m_medianSize > 1) {
1888 freq = insertMedian(unit->m_values, unit->m_ages, unit->m_medianSize, freq);
1890 if(unit->m_getClarity)
1891 hasfreq = maxsum / zerolagval; // "clarity" measure is normalised size of first peak
1892 else
1893 hasfreq = 1.f;
1895 startperiod = (ksamps+downsamp-1)/downsamp;
1898 }/* else {
1899 printf("amp too low \n");
1902 // shift buffer for next fill
1903 int execPeriod = unit->m_execPeriod;
1904 int interval = size - execPeriod;
1905 //printf("interval %d sz %d ep %d\n", interval, size, execPeriod);
1906 for (int i = 0; i < interval; i++) {
1907 bufData[i] = bufData[i + execPeriod];
1909 index = interval;
1911 } while (readp < ksamps);
1913 ZOUT0(0) = freq;
1914 ZOUT0(1) = hasfreq;
1915 unit->m_readp = readp - ksamps;
1916 unit->m_index = index;
1917 unit->m_freq = freq;
1918 unit->m_hasfreq = hasfreq;
1922 // control rate pitch tracking (nescivi 11/2008)
1923 void Pitch_next_k(Pitch *unit, int inNumSamples)
1925 bool foundPeak;
1927 float in = ZIN0(kPitchIn); // one sample, current input
1928 uint32 size = unit->m_size;
1929 uint32 index = unit->m_index;
1930 int downsamp = unit->m_downsamp;
1931 int readp = unit->m_readp;
1932 // int ksamps = unit->mWorld->mFullRate.mBufLength;
1934 float *bufData = unit->m_buffer;
1936 float freq = unit->m_freq;
1937 float hasfreq = unit->m_hasfreq;
1938 // printf("> %d %d readp %d downsamp %d exec %d\n", index, size, readp, downsamp, unit->m_execPeriod);
1939 readp++;
1940 if ( readp == downsamp ){
1941 // do {
1942 // float z = in[readp];
1943 float z = in;
1944 bufData[index++] = z;
1945 readp = 0;
1946 // readp += downsamp;
1948 if (index >= size) {
1949 float ampthresh = unit->m_ampthresh;
1950 bool ampok = false;
1952 hasfreq = 0.f; // assume failure
1954 int minperiod = unit->m_minperiod;
1955 int maxperiod = unit->m_maxperiod;
1956 //float maxamp = 0.f;
1957 // check for amp threshold
1958 for (int j = 0; j < maxperiod; ++j) {
1959 if (fabs(bufData[j]) >= ampthresh) {
1960 ampok = true;
1961 break;
1963 //if (fabs(bufData[j]) > maxamp) maxamp = fabs(bufData[j]);
1965 //printf("ampok %d maxperiod %d maxamp %g\n", ampok, maxperiod, maxamp);
1967 // if amplitude is too small then don't even look for pitch
1968 float ampsum;
1969 if (ampok) {
1970 int maxlog2bins = unit->m_maxlog2bins;
1971 int octave;
1972 // calculate the zero lag value and compute the threshold based on that
1973 float zerolagval = 0.f;
1974 for (int j = 0; j < maxperiod; ++j) {
1975 zerolagval += bufData[j] * bufData[j];
1977 float threshold = zerolagval * unit->m_peakthresh;
1979 // skip until drop below threshold
1980 int binstep, peakbinstep = 0;
1981 int i;
1982 for (i = 1; i <= maxperiod; i += binstep) {
1983 // compute sum of one lag
1984 ampsum = 0.f;
1985 for (int j = 0; j < maxperiod; ++j) {
1986 ampsum += bufData[i+j] * bufData[j];
1988 if (ampsum < threshold) break;
1990 octave = LOG2CEIL(i);
1991 if (octave <= maxlog2bins) {
1992 binstep = 1;
1993 } else {
1994 binstep = 1L << (octave - maxlog2bins);
1997 int startperiod = i;
1998 int period = startperiod;
1999 //printf("startperiod %d\n", startperiod);
2001 // find the first peak
2002 float maxsum = threshold;
2003 foundPeak = false;
2004 for (i = startperiod; i <= maxperiod; i += binstep) {
2005 if (i >= minperiod) {
2006 ampsum = 0.f;
2007 for (int j = 0; j < maxperiod; ++j) {
2008 ampsum += bufData[i+j] * bufData[j];
2010 if (ampsum > threshold) {
2011 if (ampsum > maxsum) {
2012 foundPeak = true;
2013 maxsum = ampsum;
2014 peakbinstep = binstep;
2015 period = i;
2017 } else if (foundPeak) break;
2019 octave = LOG2CEIL(i);
2020 if (octave <= maxlog2bins) {
2021 binstep = 1;
2022 } else {
2023 binstep = 1L << (octave - maxlog2bins);
2027 //printf("found %d thr %g maxs %g per %d bs %d\n", foundPeak, threshold, maxsum, period, peakbinstep);
2028 if (foundPeak) {
2029 float prevampsum, nextampsum;
2031 // find amp sums immediately surrounding max
2032 prevampsum = 0.f;
2033 if (period > 0) {
2034 i = period - 1;
2035 for (int j = 0; j < maxperiod; ++j) {
2036 prevampsum += bufData[i+j] * bufData[j];
2040 nextampsum = 0.f;
2041 if (period < maxperiod) {
2042 i = period + 1;
2043 for (int j = 0; j < maxperiod; ++j) {
2044 nextampsum += bufData[i+j] * bufData[j];
2048 //printf("prevnext %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2049 // not on a peak yet. This can happen if binstep > 1
2050 while (prevampsum > maxsum && period > 0) {
2051 nextampsum = maxsum;
2052 maxsum = prevampsum;
2053 period--;
2054 i = period - 1;
2055 prevampsum = 0.f;
2056 for (int j = 0; j < maxperiod; ++j) {
2057 prevampsum += bufData[i+j] * bufData[j];
2059 //printf("slide left %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2061 while (nextampsum > maxsum && period < maxperiod) {
2062 prevampsum = maxsum;
2063 maxsum = nextampsum;
2064 period++;
2065 i = period + 1;
2066 nextampsum = 0.f;
2067 for (int j = 0; j < maxperiod; ++j) {
2068 nextampsum += bufData[i+j] * bufData[j];
2070 //printf("slide right %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2073 // make a fractional period
2074 float beta = 0.5 * (nextampsum - prevampsum);
2075 float gamma = 2.0 * maxsum - nextampsum - prevampsum;
2076 float fperiod = (float)period + (beta/gamma);
2078 // calculate frequency
2079 float tempfreq = unit->m_srate / fperiod;
2081 //printf("freq %g %g / %g %g %g %d\n", tempfreq, unit->m_srate, fperiod,
2082 // unit->m_minfreq, unit->m_maxfreq,
2083 // tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq);
2085 if (tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq) {
2086 freq = tempfreq;
2088 // median filter
2089 if (unit->m_medianSize > 1) {
2090 freq = insertMedian(unit->m_values, unit->m_ages, unit->m_medianSize, freq);
2092 if(unit->m_getClarity)
2093 hasfreq = maxsum / zerolagval; // "clarity" measure is normalised size of first peak
2094 else
2095 hasfreq = 1.f;
2097 // nescivi: not sure about this one?
2098 startperiod = 1; // (ksamps+downsamp-1)/downsamp;
2101 }/* else {
2102 printf("amp too low \n");
2105 // shift buffer for next fill
2106 int execPeriod = unit->m_execPeriod;
2107 int interval = size - execPeriod;
2108 //printf("interval %d sz %d ep %d\n", interval, size, execPeriod);
2109 for (int i = 0; i < interval; i++) {
2110 bufData[i] = bufData[i + execPeriod];
2112 index = interval;
2115 //while (readp < ksamps);
2117 ZOUT0(0) = freq;
2118 ZOUT0(1) = hasfreq;
2119 // unit->m_readp = readp - ksamps;
2120 unit->m_readp = readp;
2121 unit->m_index = index;
2122 unit->m_freq = freq;
2123 unit->m_hasfreq = hasfreq;
2126 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2129 #if 0
2130 void DelayUnit_AllocDelayLine(DelayUnit *unit)
2132 long delaybufsize = (long)ceil(unit->m_maxdelaytime * SAMPLERATE + 1.f);
2133 delaybufsize = delaybufsize + BUFLENGTH;
2134 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
2135 unit->m_fdelaylen = unit->m_idelaylen = delaybufsize;
2137 RTFree(unit->mWorld, unit->m_dlybuf);
2138 int size = delaybufsize * sizeof(float);
2139 //Print("->RTAlloc %d\n", size);
2140 unit->m_dlybuf = (float*)RTAlloc(unit->mWorld, size);
2141 //Print("<-RTAlloc %p\n", unit->m_dlybuf);
2142 unit->m_mask = delaybufsize - 1;
2144 #endif
2147 template <typename Unit>
2148 static float BufCalcDelay(const Unit * unit, int bufSamples, float delayTime)
2150 float minDelay = Unit::minDelaySamples;
2151 return sc_clip(delayTime * (float)SAMPLERATE, minDelay, (float)(PREVIOUSPOWEROFTWO(bufSamples))-1);
2154 template <typename Unit>
2155 static void BufDelayUnit_Reset(Unit *unit)
2157 //Print("->DelayUnit_Reset\n");
2158 //unit->m_maxdelaytime = ZIN0(1);
2159 unit->m_delaytime = ZIN0(2);
2160 //Print("unit->m_delaytime %g\n", unit->m_delaytime);
2161 //unit->m_dlybuf = 0;
2162 unit->m_fbufnum = -1e9f;
2164 //DelayUnit_AllocDelayLine(unit);
2165 //Print("->GET_BUF\n");
2166 GET_BUF
2167 //Print("<-GET_BUF\n");
2168 unit->m_dsamp = BufCalcDelay(unit, bufSamples, unit->m_delaytime);
2169 unit->m_numoutput = 0;
2170 unit->m_iwrphase = 0;
2173 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2175 template <typename Unit>
2176 static void BufFeedbackDelay_Reset(Unit *unit)
2178 BufDelayUnit_Reset(unit);
2180 unit->m_decaytime = ZIN0(3);
2181 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
2184 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2186 namespace {
2188 /* helper classes for delay functionality */
2189 template <bool Checked = false>
2190 struct DelayN_helper
2192 static const bool checked = false;
2194 static inline void perform(const float *& in, float *& out, float * bufData,
2195 long & iwrphase, long idsamp, long mask)
2197 long irdphase = iwrphase - idsamp;
2198 bufData[iwrphase & mask] = ZXP(in);
2199 ZXP(out) = bufData[irdphase & mask];
2200 iwrphase++;
2203 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2204 static inline void perform(const float *& in, float *& out, float * bufData,
2205 long & iwrphase, long idsamp, float frac, long mask)
2207 perform(in, out, bufData, iwrphase, idsamp, mask);
2211 template <>
2212 struct DelayN_helper<true>
2214 static const bool checked = true;
2216 static inline void perform(const float *& in, float *& out, float * bufData,
2217 long & iwrphase, long idsamp, long mask)
2219 long irdphase = iwrphase - idsamp;
2221 bufData[iwrphase & mask] = ZXP(in);
2222 if (irdphase < 0)
2223 ZXP(out) = 0.f;
2224 else
2225 ZXP(out) = bufData[irdphase & mask];
2227 iwrphase++;
2230 static inline void perform(const float *& in, float *& out, float * bufData,
2231 long & iwrphase, long idsamp, float frac, long mask)
2233 perform(in, out, bufData, iwrphase, idsamp, mask);
2237 template <bool initializing>
2238 static inline void DelayN_delay_loop(float * out, const float * in, long & iwrphase, float dsamp, long mask,
2239 float * dlybuf, int inNumSamples, int idelaylen)
2241 long irdphase = iwrphase - (long)dsamp;
2242 float* dlybuf1 = dlybuf - ZOFF;
2243 float* dlyrd = dlybuf1 + (irdphase & mask);
2244 float* dlywr = dlybuf1 + (iwrphase & mask);
2245 float* dlyN = dlybuf1 + idelaylen;
2246 long remain = inNumSamples;
2247 while (remain) {
2248 long rdspace = dlyN - dlyrd;
2249 long wrspace = dlyN - dlywr;
2250 if (initializing) {
2251 long nsmps = sc_min(rdspace, wrspace);
2252 nsmps = sc_min(remain, nsmps);
2253 remain -= nsmps;
2254 if (irdphase < 0) {
2255 if ((dlywr - dlyrd) > nsmps) {
2256 #ifdef NOVA_SIMD
2257 if ((nsmps & (nova::vec<float>::size - 1)) == 0) {
2258 nova::copyvec_nn_simd(dlywr + ZOFF, in + ZOFF, nsmps);
2259 nova::zerovec_na_simd(out + ZOFF, nsmps);
2260 } else
2261 #endif
2263 ZCopy(nsmps, dlywr, in);
2264 ZClear(nsmps, out);
2266 out += nsmps;
2267 in += nsmps;
2268 dlyrd += nsmps;
2269 dlywr += nsmps;
2270 } else
2271 LOOP(nsmps,
2272 ZXP(dlywr) = ZXP(in);
2273 ZXP(out) = 0.f;
2274 ZXP(dlyrd);
2276 } else {
2277 LOOP(nsmps,
2278 ZXP(dlywr) = ZXP(in);
2279 ZXP(out) = ZXP(dlyrd);
2282 irdphase += nsmps;
2283 if (dlyrd == dlyN) dlyrd = dlybuf1;
2284 if (dlywr == dlyN) dlywr = dlybuf1;
2286 else {
2287 long nsmps = sc_min(rdspace, wrspace);
2288 nsmps = sc_min(remain, nsmps);
2289 remain -= nsmps;
2291 if (std::abs((float)(dlyrd - dlywr)) > nsmps) {
2292 #ifdef NOVA_SIMD
2293 if ((nsmps & 15) == 0) {
2294 nova::copyvec_nn_simd(dlywr + ZOFF, in + ZOFF, nsmps);
2295 nova::copyvec_nn_simd(out + ZOFF, dlyrd + ZOFF, nsmps);
2296 } else
2297 #endif
2299 ZCopy(nsmps, dlywr, in);
2300 ZCopy(nsmps, out, dlyrd);
2302 out += nsmps;
2303 in += nsmps;
2304 dlyrd += nsmps;
2305 dlywr += nsmps;
2306 } else
2307 LOOP(nsmps,
2308 ZXP(dlywr) = ZXP(in);
2309 ZXP(out) = ZXP(dlyrd);
2311 if (dlyrd == dlyN) dlyrd = dlybuf1;
2312 if (dlywr == dlyN) dlywr = dlybuf1;
2315 iwrphase += inNumSamples;
2319 template <bool Checked = false>
2320 struct DelayL_helper
2322 static const bool checked = false;
2324 static inline void perform(const float *& in, float *& out, float * bufData,
2325 long & iwrphase, long idsamp, float frac, long mask)
2327 bufData[iwrphase & mask] = ZXP(in);
2328 long irdphase = iwrphase - idsamp;
2329 long irdphaseb = irdphase - 1;
2330 float d1 = bufData[irdphase & mask];
2331 float d2 = bufData[irdphaseb & mask];
2332 ZXP(out) = lininterp(frac, d1, d2);
2333 iwrphase++;
2337 template <>
2338 struct DelayL_helper<true>
2340 static const bool checked = true;
2342 static inline void perform(const float *& in, float *& out, float * bufData,
2343 long & iwrphase, long idsamp, float frac, long mask)
2345 bufData[iwrphase & mask] = ZXP(in);
2346 long irdphase = iwrphase - idsamp;
2347 long irdphaseb = irdphase - 1;
2349 if (irdphase < 0) {
2350 ZXP(out) = 0.f;
2351 } else if (irdphaseb < 0) {
2352 float d1 = bufData[irdphase & mask];
2353 ZXP(out) = d1 - frac * d1;
2354 } else {
2355 float d1 = bufData[irdphase & mask];
2356 float d2 = bufData[irdphaseb & mask];
2357 ZXP(out) = lininterp(frac, d1, d2);
2359 iwrphase++;
2363 template <bool Checked = false>
2364 struct DelayC_helper
2366 static const bool checked = false;
2368 static inline void perform(const float *& in, float *& out, float * bufData,
2369 long & iwrphase, long idsamp, float frac, long mask)
2371 bufData[iwrphase & mask] = ZXP(in);
2372 long irdphase1 = iwrphase - idsamp;
2373 long irdphase2 = irdphase1 - 1;
2374 long irdphase3 = irdphase1 - 2;
2375 long irdphase0 = irdphase1 + 1;
2376 float d0 = bufData[irdphase0 & mask];
2377 float d1 = bufData[irdphase1 & mask];
2378 float d2 = bufData[irdphase2 & mask];
2379 float d3 = bufData[irdphase3 & mask];
2380 ZXP(out) = cubicinterp(frac, d0, d1, d2, d3);
2381 iwrphase++;
2385 template <>
2386 struct DelayC_helper<true>
2388 static const bool checked = true;
2390 static inline void perform(const float *& in, float *& out, float * bufData,
2391 long & iwrphase, long idsamp, float frac, long mask)
2393 long irdphase1 = iwrphase - idsamp;
2394 long irdphase2 = irdphase1 - 1;
2395 long irdphase3 = irdphase1 - 2;
2396 long irdphase0 = irdphase1 + 1;
2398 bufData[iwrphase & mask] = ZXP(in);
2399 if (irdphase0 < 0) {
2400 ZXP(out) = 0.f;
2401 } else {
2402 float d0, d1, d2, d3;
2403 if (irdphase1 < 0) {
2404 d1 = d2 = d3 = 0.f;
2405 d0 = bufData[irdphase0 & mask];
2406 } else if (irdphase2 < 0) {
2407 d1 = d2 = d3 = 0.f;
2408 d0 = bufData[irdphase0 & mask];
2409 d1 = bufData[irdphase1 & mask];
2410 } else if (irdphase3 < 0) {
2411 d3 = 0.f;
2412 d0 = bufData[irdphase0 & mask];
2413 d1 = bufData[irdphase1 & mask];
2414 d2 = bufData[irdphase2 & mask];
2415 } else {
2416 d0 = bufData[irdphase0 & mask];
2417 d1 = bufData[irdphase1 & mask];
2418 d2 = bufData[irdphase2 & mask];
2419 d3 = bufData[irdphase3 & mask];
2421 ZXP(out) = cubicinterp(frac, d0, d1, d2, d3);
2423 iwrphase++;
2427 template <bool Checked = false>
2428 struct CombN_helper
2430 static const bool checked = false;
2432 static inline void perform(const float *& in, float *& out, float * bufData,
2433 long & iwrphase, long idsamp, long mask, float feedbk)
2435 long irdphase = iwrphase - idsamp;
2436 float value = bufData[irdphase & mask];
2437 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2438 ZXP(out) = value;
2439 ++iwrphase;
2442 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2443 static inline void perform(const float *& in, float *& out, float * bufData,
2444 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2446 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2450 template <>
2451 struct CombN_helper<true>
2453 static const bool checked = true;
2455 static inline void perform(const float *& in, float *& out, float * bufData,
2456 long & iwrphase, long idsamp, long mask, float feedbk)
2458 long irdphase = iwrphase - idsamp;
2460 if (irdphase < 0) {
2461 bufData[iwrphase & mask] = ZXP(in);
2462 ZXP(out) = 0.f;
2463 } else {
2464 float value = bufData[irdphase & mask];
2465 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2466 ZXP(out) = value;
2469 iwrphase++;
2472 static inline void perform(const float *& in, float *& out, float * bufData,
2473 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2475 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2479 template <bool Checked = false>
2480 struct CombL_helper
2482 static const bool checked = false;
2484 static inline void perform(const float *& in, float *& out, float * bufData,
2485 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2487 long irdphase = iwrphase - idsamp;
2488 long irdphaseb = irdphase - 1;
2489 float d1 = bufData[irdphase & mask];
2490 float d2 = bufData[irdphaseb & mask];
2491 float value = lininterp(frac, d1, d2);
2492 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2493 ZXP(out) = value;
2494 iwrphase++;
2498 template <>
2499 struct CombL_helper<true>
2501 static const bool checked = true;
2503 static inline void perform(const float *& in, float *& out, float * bufData,
2504 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2506 long irdphase = iwrphase - idsamp;
2507 long irdphaseb = irdphase - 1;
2509 float zin = ZXP(in);
2510 if (irdphase < 0) {
2511 bufData[iwrphase & mask] = zin;
2512 ZXP(out) = 0.f;
2513 } else if (irdphaseb < 0) {
2514 float d1 = bufData[irdphase & mask];
2515 float value = d1 - frac * d1;
2516 bufData[iwrphase & mask] = zin + feedbk * value;
2517 ZXP(out) = value;
2518 } else {
2519 float d1 = bufData[irdphase & mask];
2520 float d2 = bufData[irdphaseb & mask];
2521 float value = lininterp(frac, d1, d2);
2522 bufData[iwrphase & mask] = zin + feedbk * value;
2523 ZXP(out) = value;
2525 iwrphase++;
2529 template <bool Checked = false>
2530 struct CombC_helper
2532 static const bool checked = false;
2534 static inline void perform(const float *& in, float *& out, float * bufData,
2535 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2537 long irdphase1 = iwrphase - idsamp;
2538 long irdphase2 = irdphase1 - 1;
2539 long irdphase3 = irdphase1 - 2;
2540 long irdphase0 = irdphase1 + 1;
2541 float d0 = bufData[irdphase0 & mask];
2542 float d1 = bufData[irdphase1 & mask];
2543 float d2 = bufData[irdphase2 & mask];
2544 float d3 = bufData[irdphase3 & mask];
2545 float value = cubicinterp(frac, d0, d1, d2, d3);
2546 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2547 ZXP(out) = value;
2548 iwrphase++;
2552 template <>
2553 struct CombC_helper<true>
2555 static const bool checked = true;
2557 static inline void perform(const float *& in, float *& out, float * bufData,
2558 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2560 long irdphase1 = iwrphase - idsamp;
2561 long irdphase2 = irdphase1 - 1;
2562 long irdphase3 = irdphase1 - 2;
2563 long irdphase0 = irdphase1 + 1;
2565 if (irdphase0 < 0) {
2566 bufData[iwrphase & mask] = ZXP(in);
2567 ZXP(out) = 0.f;
2568 } else {
2569 float d0, d1, d2, d3;
2570 if (irdphase1 < 0) {
2571 d1 = d2 = d3 = 0.f;
2572 d0 = bufData[irdphase0 & mask];
2573 } else if (irdphase2 < 0) {
2574 d1 = d2 = d3 = 0.f;
2575 d0 = bufData[irdphase0 & mask];
2576 d1 = bufData[irdphase1 & mask];
2577 } else if (irdphase3 < 0) {
2578 d3 = 0.f;
2579 d0 = bufData[irdphase0 & mask];
2580 d1 = bufData[irdphase1 & mask];
2581 d2 = bufData[irdphase2 & mask];
2582 } else {
2583 d0 = bufData[irdphase0 & mask];
2584 d1 = bufData[irdphase1 & mask];
2585 d2 = bufData[irdphase2 & mask];
2586 d3 = bufData[irdphase3 & mask];
2588 float value = cubicinterp(frac, d0, d1, d2, d3);
2589 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2590 ZXP(out) = value;
2592 iwrphase++;
2596 template <bool Checked = false>
2597 struct AllpassN_helper
2599 static const bool checked = false;
2601 static inline void perform(const float *& in, float *& out, float * bufData,
2602 long & iwrphase, long idsamp, long mask, float feedbk)
2604 long irdphase = iwrphase - idsamp;
2605 float value = bufData[irdphase & mask];
2606 float dwr = value * feedbk + ZXP(in);
2607 bufData[iwrphase & mask] = dwr;
2608 ZXP(out) = value - feedbk * dwr;
2609 ++iwrphase;
2612 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2613 static inline void perform(const float *& in, float *& out, float * bufData,
2614 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2616 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2620 template <>
2621 struct AllpassN_helper<true>
2623 static const bool checked = true;
2625 static inline void perform(const float *& in, float *& out, float * bufData,
2626 long & iwrphase, long idsamp, long mask, float feedbk)
2628 long irdphase = iwrphase - idsamp;
2630 if (irdphase < 0) {
2631 float dwr = ZXP(in);
2632 bufData[iwrphase & mask] = dwr;
2633 ZXP(out) = -feedbk * dwr;
2634 } else {
2635 float value = bufData[irdphase & mask];
2636 float dwr = feedbk * value + ZXP(in);
2637 bufData[iwrphase & mask] = dwr;
2638 ZXP(out) = value - feedbk * dwr;
2640 ++iwrphase;
2643 static inline void perform(const float *& in, float *& out, float * bufData,
2644 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2646 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2650 template <bool Checked = false>
2651 struct AllpassL_helper
2653 static const bool checked = false;
2655 static inline void perform(const float *& in, float *& out, float * bufData,
2656 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2658 long irdphase = iwrphase - idsamp;
2659 long irdphaseb = irdphase - 1;
2660 float d1 = bufData[irdphase & mask];
2661 float d2 = bufData[irdphaseb & mask];
2662 float value = lininterp(frac, d1, d2);
2663 float dwr = ZXP(in) + feedbk * value;
2664 bufData[iwrphase & mask] = dwr;
2665 ZXP(out) = value - feedbk * dwr;
2666 iwrphase++;
2670 template <>
2671 struct AllpassL_helper<true>
2673 static const bool checked = true;
2675 static inline void perform(const float *& in, float *& out, float * bufData,
2676 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2678 long irdphase = iwrphase - idsamp;
2679 long irdphaseb = irdphase - 1;
2681 float zin = ZXP(in);
2682 if (irdphase < 0) {
2683 bufData[iwrphase & mask] = zin;
2684 ZXP(out) = - feedbk * zin;
2685 } else if (irdphaseb < 0) {
2686 float d1 = bufData[irdphase & mask];
2687 float value = d1 - frac * d1;
2688 float dwr = zin + feedbk * value;
2689 bufData[iwrphase & mask] = dwr;
2690 ZXP(out) = value - feedbk * dwr;
2691 } else {
2692 float d1 = bufData[irdphase & mask];
2693 float d2 = bufData[irdphaseb & mask];
2694 float value = lininterp(frac, d1, d2);
2695 float dwr = zin + feedbk * value;
2696 bufData[iwrphase & mask] = dwr;
2697 ZXP(out) = value - feedbk * dwr;
2699 iwrphase++;
2703 template <bool Checked = false>
2704 struct AllpassC_helper
2706 static const bool checked = false;
2708 static inline void perform(const float *& in, float *& out, float * bufData,
2709 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2711 long irdphase1 = iwrphase - idsamp;
2712 long irdphase2 = irdphase1 - 1;
2713 long irdphase3 = irdphase1 - 2;
2714 long irdphase0 = irdphase1 + 1;
2715 float d0 = bufData[irdphase0 & mask];
2716 float d1 = bufData[irdphase1 & mask];
2717 float d2 = bufData[irdphase2 & mask];
2718 float d3 = bufData[irdphase3 & mask];
2719 float value = cubicinterp(frac, d0, d1, d2, d3);
2720 float dwr = ZXP(in) + feedbk * value;
2721 bufData[iwrphase & mask] = dwr;
2722 ZXP(out) = value - feedbk * dwr;
2723 iwrphase++;
2727 template <>
2728 struct AllpassC_helper<true>
2730 static const bool checked = true;
2732 static inline void perform(const float *& in, float *& out, float * bufData,
2733 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2735 long irdphase1 = iwrphase - idsamp;
2736 long irdphase2 = irdphase1 - 1;
2737 long irdphase3 = irdphase1 - 2;
2738 long irdphase0 = irdphase1 + 1;
2740 if (irdphase0 < 0) {
2741 bufData[iwrphase & mask] = ZXP(in);
2742 ZXP(out) = 0.f;
2743 } else {
2744 float d0, d1, d2, d3;
2745 if (irdphase1 < 0) {
2746 d1 = d2 = d3 = 0.f;
2747 d0 = bufData[irdphase0 & mask];
2748 } else if (irdphase2 < 0) {
2749 d1 = d2 = d3 = 0.f;
2750 d0 = bufData[irdphase0 & mask];
2751 d1 = bufData[irdphase1 & mask];
2752 } else if (irdphase3 < 0) {
2753 d3 = 0.f;
2754 d0 = bufData[irdphase0 & mask];
2755 d1 = bufData[irdphase1 & mask];
2756 d2 = bufData[irdphase2 & mask];
2757 } else {
2758 d0 = bufData[irdphase0 & mask];
2759 d1 = bufData[irdphase1 & mask];
2760 d2 = bufData[irdphase2 & mask];
2761 d3 = bufData[irdphase3 & mask];
2763 float value = cubicinterp(frac, d0, d1, d2, d3);
2764 float dwr = ZXP(in) + feedbk * value;
2765 bufData[iwrphase & mask] = dwr;
2766 ZXP(out) = value - feedbk * dwr;
2768 iwrphase++;
2774 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2776 /* template function to generate buffer-based delay ugen function, control-rate delay time */
2777 template <typename PerformClass,
2778 typename BufDelayX
2780 inline void BufDelayX_perform(BufDelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
2782 float *out = ZOUT(0);
2783 const float *in = ZIN(1);
2784 float delaytime = ZIN0(2);
2786 GET_BUF
2787 CHECK_BUF
2788 long iwrphase = unit->m_iwrphase;
2789 float dsamp = unit->m_dsamp;
2791 if (delaytime == unit->m_delaytime) {
2792 long idsamp = (long)dsamp;
2793 float frac = dsamp - idsamp;
2794 LOOP1(inNumSamples,
2795 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2797 } else {
2798 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2799 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2801 LOOP1(inNumSamples,
2802 dsamp += dsamp_slope;
2803 long idsamp = (long)dsamp;
2804 float frac = dsamp - idsamp;
2805 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2807 unit->m_dsamp = dsamp;
2808 unit->m_delaytime = delaytime;
2811 unit->m_iwrphase = iwrphase;
2813 if (PerformClass::checked) {
2814 unit->m_numoutput += inNumSamples;
2815 if (unit->m_numoutput >= bufSamples)
2816 unit->mCalcFunc = resetFunc;
2821 /* template function to generate buffer-based delay ugen function, audio-rate delay time */
2822 template <typename PerformClass,
2823 typename BufDelayX
2825 inline void BufDelayX_perform_a(BufDelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
2827 float *out = ZOUT(0);
2828 const float *in = ZIN(1);
2829 float * delaytime = ZIN(2);
2831 GET_BUF
2832 CHECK_BUF
2833 long iwrphase = unit->m_iwrphase;
2835 LOOP1(inNumSamples,
2836 float dsamp = BufCalcDelay(unit, bufSamples, ZXP(delaytime));
2837 long idsamp = (long)dsamp;
2839 float frac = dsamp - idsamp;
2840 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2843 unit->m_iwrphase = iwrphase;
2845 if (PerformClass::checked)
2847 unit->m_numoutput += inNumSamples;
2848 if (unit->m_numoutput >= bufSamples)
2849 unit->mCalcFunc = resetFunc;
2853 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2855 void BufDelayN_Ctor(BufDelayN *unit)
2857 if(INRATE(2) == calc_FullRate)
2858 SETCALC(BufDelayN_next_a_z);
2859 else
2860 SETCALC(BufDelayN_next_z);
2861 BufDelayUnit_Reset(unit);
2862 ZOUT0(0) = 0.f;
2865 void BufDelayN_next(BufDelayN *unit, int inNumSamples)
2867 float *out = ZOUT(0);
2868 const float *in = ZIN(1);
2869 float delaytime = ZIN0(2);
2871 GET_BUF
2872 CHECK_BUF
2873 long iwrphase = unit->m_iwrphase;
2874 float dsamp = unit->m_dsamp;
2876 if (delaytime == unit->m_delaytime) {
2877 DelayN_delay_loop<false>(out, in, iwrphase, dsamp, mask, bufData, inNumSamples, PREVIOUSPOWEROFTWO(bufSamples));
2878 } else {
2879 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2880 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2882 LOOP1(inNumSamples,
2883 dsamp += dsamp_slope;
2884 long idsamp = (long)dsamp;
2885 DelayN_helper<false>::perform(in, out, bufData, iwrphase, idsamp, mask);
2887 unit->m_dsamp = dsamp;
2888 unit->m_delaytime = delaytime;
2891 unit->m_iwrphase = iwrphase;
2895 void BufDelayN_next_z(BufDelayN *unit, int inNumSamples)
2897 float *out = ZOUT(0);
2898 const float *in = ZIN(1);
2899 float delaytime = ZIN0(2);
2901 GET_BUF
2902 CHECK_BUF
2903 long iwrphase = unit->m_iwrphase;
2904 float dsamp = unit->m_dsamp;
2906 if (delaytime == unit->m_delaytime) {
2907 DelayN_delay_loop<true>(out, in, iwrphase, dsamp, mask, bufData, inNumSamples, PREVIOUSPOWEROFTWO(bufSamples));
2908 } else {
2909 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2910 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2912 LOOP1(inNumSamples,
2913 dsamp += dsamp_slope;
2914 long idsamp = (long)dsamp;
2915 DelayN_helper<true>::perform(in, out, bufData, iwrphase, idsamp, mask);
2917 unit->m_dsamp = dsamp;
2918 unit->m_delaytime = delaytime;
2921 unit->m_iwrphase = iwrphase;
2923 unit->m_numoutput += inNumSamples;
2924 if (unit->m_numoutput >= bufSamples)
2925 SETCALC(BufDelayN_next);
2928 template <bool checked>
2929 inline void BufDelayN_perform_a(BufDelayN *unit, int inNumSamples)
2931 BufDelayX_perform_a<DelayN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayN_next_a);
2934 void BufDelayN_next_a(BufDelayN *unit, int inNumSamples)
2936 BufDelayN_perform_a<false>(unit, inNumSamples);
2939 void BufDelayN_next_a_z(BufDelayN *unit, int inNumSamples)
2941 BufDelayN_perform_a<true>(unit, inNumSamples);
2944 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2945 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2947 void BufDelayL_Ctor(BufDelayL *unit)
2949 BufDelayUnit_Reset(unit);
2950 if(INRATE(2) == calc_FullRate)
2951 SETCALC(BufDelayL_next_a_z);
2952 else
2953 SETCALC(BufDelayL_next_z);
2954 ZOUT0(0) = 0.f;
2958 template <bool checked>
2959 inline void BufDelayL_perform(BufDelayL *unit, int inNumSamples)
2961 BufDelayX_perform<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next);
2964 void BufDelayL_next(BufDelayL *unit, int inNumSamples)
2966 BufDelayL_perform<false>(unit, inNumSamples);
2969 void BufDelayL_next_z(BufDelayL *unit, int inNumSamples)
2971 BufDelayL_perform<true>(unit, inNumSamples);
2974 template <bool checked>
2975 inline void BufDelayL_perform_a(BufDelayL *unit, int inNumSamples)
2977 BufDelayX_perform_a<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next_a);
2980 void BufDelayL_next_a(BufDelayL *unit, int inNumSamples)
2982 BufDelayL_perform_a<false>(unit, inNumSamples);
2985 void BufDelayL_next_a_z(BufDelayL *unit, int inNumSamples)
2987 BufDelayL_perform_a<true>(unit, inNumSamples);
2990 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2992 void BufDelayC_Ctor(BufDelayC *unit)
2994 BufDelayUnit_Reset(unit);
2995 if(INRATE(2) == calc_FullRate)
2996 SETCALC(BufDelayC_next_a_z);
2997 else
2998 SETCALC(BufDelayC_next_z);
2999 ZOUT0(0) = 0.f;
3002 template <bool checked>
3003 inline void BufDelayC_perform(BufDelayC *unit, int inNumSamples)
3005 BufDelayX_perform<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayC_next);
3008 void BufDelayC_next(BufDelayC *unit, int inNumSamples)
3010 BufDelayC_perform<false>(unit, inNumSamples);
3013 void BufDelayC_next_z(BufDelayC *unit, int inNumSamples)
3015 BufDelayC_perform<true>(unit, inNumSamples);
3018 template <bool checked>
3019 inline void BufDelayC_perform_a(BufDelayC *unit, int inNumSamples)
3021 BufDelayX_perform_a<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next_a);
3024 void BufDelayC_next_a(BufDelayC *unit, int inNumSamples)
3026 BufDelayC_perform_a<false>(unit, inNumSamples);
3029 void BufDelayC_next_a_z(BufDelayC *unit, int inNumSamples)
3031 BufDelayC_perform_a<true>(unit, inNumSamples);
3034 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3035 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3037 template <typename PerformClass,
3038 typename BufCombX
3040 inline void BufFilterX_perform(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3042 float *out = ZOUT(0);
3043 const float *in = ZIN(1);
3044 float delaytime = ZIN0(2);
3045 float decaytime = ZIN0(3);
3047 GET_BUF
3048 CHECK_BUF
3049 long iwrphase = unit->m_iwrphase;
3050 float dsamp = unit->m_dsamp;
3051 float feedbk = unit->m_feedbk;
3053 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
3054 long idsamp = (long)dsamp;
3055 float frac = dsamp - idsamp;
3056 LOOP1(inNumSamples,
3057 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3059 } else {
3060 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3061 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3063 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3064 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3066 LOOP1(inNumSamples,
3067 dsamp += dsamp_slope;
3068 feedbk += feedbk_slope;
3069 long idsamp = (long)dsamp;
3070 float frac = dsamp - idsamp;
3071 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3073 unit->m_feedbk = feedbk;
3074 unit->m_dsamp = dsamp;
3075 unit->m_delaytime = delaytime;
3076 unit->m_decaytime = decaytime;
3079 unit->m_iwrphase = iwrphase;
3081 if (PerformClass::checked) {
3082 unit->m_numoutput += inNumSamples;
3083 if (unit->m_numoutput >= bufSamples)
3084 unit->mCalcFunc = resetFunc;
3088 template <typename PerformClass,
3089 typename BufCombX
3091 inline void BufFilterX_perform_a(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3093 float *out = ZOUT(0);
3094 const float *in = ZIN(1);
3095 float * delaytime = ZIN(2);
3096 float decaytime = ZIN0(3);
3098 GET_BUF
3099 CHECK_BUF
3100 long iwrphase = unit->m_iwrphase;
3102 LOOP1(inNumSamples,
3103 float del = ZXP(delaytime);
3104 float dsamp = BufCalcDelay(unit, bufSamples, del);
3105 float feedbk = sc_CalcFeedback(del, decaytime);
3107 long idsamp = (long)dsamp;
3108 float frac = dsamp - idsamp;
3109 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3112 unit->m_iwrphase = iwrphase;
3114 if (PerformClass::checked)
3116 unit->m_numoutput += inNumSamples;
3117 if (unit->m_numoutput >= bufSamples)
3118 unit->mCalcFunc = resetFunc;
3123 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3125 void BufCombN_Ctor(BufCombN *unit)
3127 BufFeedbackDelay_Reset(unit);
3128 if(INRATE(2) == calc_FullRate)
3129 SETCALC(BufCombN_next_a_z);
3130 else
3131 SETCALC(BufCombN_next_z);
3132 ZOUT0(0) = 0.f;
3135 void BufCombN_next(BufCombN *unit, int inNumSamples)
3137 float *out = ZOUT(0);
3138 const float *in = ZIN(1);
3139 float delaytime = ZIN0(2);
3140 float decaytime = ZIN0(3);
3142 GET_BUF
3143 CHECK_BUF
3144 long iwrphase = unit->m_iwrphase;
3145 float dsamp = unit->m_dsamp;
3146 float feedbk = unit->m_feedbk;
3148 //postbuf("BufCombN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3149 if (delaytime == unit->m_delaytime) {
3150 long irdphase = iwrphase - (long)dsamp;
3151 float* dlybuf1 = bufData - ZOFF;
3152 float* dlyrd = dlybuf1 + (irdphase & mask);
3153 float* dlywr = dlybuf1 + (iwrphase & mask);
3154 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3155 if (decaytime == unit->m_decaytime) {
3156 long remain = inNumSamples;
3157 while (remain) {
3158 long rdspace = dlyN - dlyrd;
3159 long wrspace = dlyN - dlywr;
3160 long nsmps = sc_min(rdspace, wrspace);
3161 nsmps = sc_min(remain, nsmps);
3162 remain -= nsmps;
3163 LOOP1(nsmps,
3164 float value = ZXP(dlyrd);
3165 ZXP(dlywr) = value * feedbk + ZXP(in);
3166 ZXP(out) = value;
3168 if (dlyrd == dlyN) dlyrd = dlybuf1;
3169 if (dlywr == dlyN) dlywr = dlybuf1;
3171 } else {
3172 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3173 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3174 long remain = inNumSamples;
3175 while (remain) {
3176 long rdspace = dlyN - dlyrd;
3177 long wrspace = dlyN - dlywr;
3178 long nsmps = sc_min(rdspace, wrspace);
3179 nsmps = sc_min(remain, nsmps);
3180 remain -= nsmps;
3182 LOOP1(nsmps,
3183 float value = ZXP(dlyrd);
3184 ZXP(dlywr) = value * feedbk + ZXP(in);
3185 ZXP(out) = value;
3186 feedbk += feedbk_slope;
3188 if (dlyrd == dlyN) dlyrd = dlybuf1;
3189 if (dlywr == dlyN) dlywr = dlybuf1;
3191 unit->m_feedbk = feedbk;
3192 unit->m_decaytime = decaytime;
3194 iwrphase += inNumSamples;
3195 } else {
3196 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3197 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3199 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3200 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3201 LOOP1(inNumSamples,
3202 dsamp += dsamp_slope;
3203 feedbk += feedbk_slope;
3204 CombN_helper<false>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3206 unit->m_feedbk = feedbk;
3207 unit->m_dsamp = dsamp;
3208 unit->m_delaytime = delaytime;
3209 unit->m_decaytime = decaytime;
3212 unit->m_iwrphase = iwrphase;
3215 void BufCombN_next_z(BufCombN *unit, int inNumSamples)
3217 float *out = ZOUT(0);
3218 const float *in = ZIN(1);
3219 float delaytime = ZIN0(2);
3220 float decaytime = ZIN0(3);
3222 GET_BUF
3223 CHECK_BUF
3224 long iwrphase = unit->m_iwrphase;
3225 float dsamp = unit->m_dsamp;
3226 float feedbk = unit->m_feedbk;
3228 //Print("BufCombN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3229 if (delaytime == unit->m_delaytime) {
3230 long irdphase = iwrphase - (long)dsamp;
3231 float* dlybuf1 = bufData - ZOFF;
3232 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3233 if (decaytime == unit->m_decaytime) {
3234 long remain = inNumSamples;
3235 while (remain) {
3236 float* dlywr = dlybuf1 + (iwrphase & mask);
3237 float* dlyrd = dlybuf1 + (irdphase & mask);
3238 long rdspace = dlyN - dlyrd;
3239 long wrspace = dlyN - dlywr;
3240 long nsmps = sc_min(rdspace, wrspace);
3241 nsmps = sc_min(remain, nsmps);
3242 remain -= nsmps;
3243 if (irdphase < 0) {
3244 LOOP1(nsmps,
3245 ZXP(dlywr) = ZXP(in);
3246 ZXP(out) = 0.f;
3248 } else {
3249 LOOP1(nsmps,
3250 float value = ZXP(dlyrd);
3251 ZXP(dlywr) = value * feedbk + ZXP(in);
3252 ZXP(out) = value;
3255 iwrphase += nsmps;
3256 irdphase += nsmps;
3258 } else {
3259 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3260 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3261 long remain = inNumSamples;
3262 while (remain) {
3263 float* dlyrd = dlybuf1 + (irdphase & mask);
3264 float* dlywr = dlybuf1 + (iwrphase & mask);
3265 long rdspace = dlyN - dlyrd;
3266 long wrspace = dlyN - dlywr;
3267 long nsmps = sc_min(rdspace, wrspace);
3268 nsmps = sc_min(remain, nsmps);
3269 remain -= nsmps;
3271 if (irdphase < 0) {
3272 feedbk += nsmps * feedbk_slope;
3273 dlyrd += nsmps;
3274 LOOP1(nsmps,
3275 ZXP(dlywr) = ZXP(in);
3276 ZXP(out) = 0.f;
3278 } else {
3279 LOOP1(nsmps,
3280 float value = ZXP(dlyrd);
3281 ZXP(dlywr) = value * feedbk + ZXP(in);
3282 ZXP(out) = value;
3283 feedbk += feedbk_slope;
3286 iwrphase += nsmps;
3287 irdphase += nsmps;
3289 unit->m_feedbk = feedbk;
3290 unit->m_decaytime = decaytime;
3292 } else {
3293 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3294 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3296 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3297 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3299 LOOP1(inNumSamples,
3300 dsamp += dsamp_slope;
3301 feedbk += feedbk_slope;
3302 CombN_helper<true>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3304 unit->m_feedbk = feedbk;
3305 unit->m_dsamp = dsamp;
3306 unit->m_delaytime = delaytime;
3307 unit->m_decaytime = decaytime;
3310 unit->m_iwrphase = iwrphase;
3312 unit->m_numoutput += inNumSamples;
3313 if (unit->m_numoutput >= bufSamples)
3314 SETCALC(BufCombN_next);
3317 template <bool checked>
3318 inline void BufCombN_perform_a(BufCombN *unit, int inNumSamples)
3320 BufFilterX_perform_a<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombN_next_a);
3323 void BufCombN_next_a(BufCombN *unit, int inNumSamples)
3325 BufCombN_perform_a<false>(unit, inNumSamples);
3328 void BufCombN_next_a_z(BufCombN *unit, int inNumSamples)
3330 BufCombN_perform_a<true>(unit, inNumSamples);
3333 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3334 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3336 void BufCombL_Ctor(BufCombL *unit)
3338 BufFeedbackDelay_Reset(unit);
3339 if(INRATE(2) == calc_FullRate)
3340 SETCALC(BufCombL_next_a_z);
3341 else
3342 SETCALC(BufCombL_next_z);
3343 ZOUT0(0) = 0.f;
3346 template <bool checked>
3347 inline void BufCombL_perform(BufCombL *unit, int inNumSamples)
3349 BufFilterX_perform<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombL_next);
3352 void BufCombL_next(BufCombL *unit, int inNumSamples)
3354 BufCombL_perform<false>(unit, inNumSamples);
3357 void BufCombL_next_z(BufCombL *unit, int inNumSamples)
3359 BufCombL_perform<true>(unit, inNumSamples);
3362 template <bool checked>
3363 inline void BufCombL_perform_a(BufCombL *unit, int inNumSamples)
3365 BufFilterX_perform_a<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombL_next_a);
3368 void BufCombL_next_a(BufCombL *unit, int inNumSamples)
3370 BufCombL_perform_a<false>(unit, inNumSamples);
3373 void BufCombL_next_a_z(BufCombL *unit, int inNumSamples)
3375 BufCombL_perform_a<true>(unit, inNumSamples);
3379 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3381 void BufCombC_Ctor(BufCombC *unit)
3383 BufFeedbackDelay_Reset(unit);
3384 if(INRATE(2) == calc_FullRate)
3385 SETCALC(BufCombC_next_a_z);
3386 else
3387 SETCALC(BufCombC_next_z);
3388 ZOUT0(0) = 0.f;
3392 template <bool checked>
3393 inline void BufCombC_perform(BufCombC *unit, int inNumSamples)
3395 BufFilterX_perform<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombC_next);
3398 void BufCombC_next(BufCombC *unit, int inNumSamples)
3400 BufCombC_perform<false>(unit, inNumSamples);
3403 void BufCombC_next_z(BufCombC *unit, int inNumSamples)
3405 BufCombC_perform<true>(unit, inNumSamples);
3408 template <bool checked>
3409 inline void BufCombC_perform_a(BufCombC *unit, int inNumSamples)
3411 BufFilterX_perform_a<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombC_next_a);
3414 void BufCombC_next_a(BufCombC *unit, int inNumSamples)
3416 BufCombC_perform_a<false>(unit, inNumSamples);
3419 void BufCombC_next_a_z(BufCombC *unit, int inNumSamples)
3421 BufCombC_perform_a<true>(unit, inNumSamples);
3425 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3426 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3428 void BufAllpassN_Ctor(BufAllpassN *unit)
3430 BufFeedbackDelay_Reset(unit);
3431 if(INRATE(2) == calc_FullRate)
3432 SETCALC(BufAllpassN_next_a_z);
3433 else
3434 SETCALC(BufAllpassN_next_z);
3435 ZOUT0(0) = 0.f;
3438 void BufAllpassN_next(BufAllpassN *unit, int inNumSamples)
3440 float *out = ZOUT(0);
3441 const float *in = ZIN(1);
3442 float delaytime = ZIN0(2);
3443 float decaytime = ZIN0(3);
3445 GET_BUF
3446 CHECK_BUF
3447 long iwrphase = unit->m_iwrphase;
3448 float dsamp = unit->m_dsamp;
3449 float feedbk = unit->m_feedbk;
3451 //postbuf("BufAllpassN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3452 if (delaytime == unit->m_delaytime) {
3453 long irdphase = iwrphase - (long)dsamp;
3454 float* dlybuf1 = bufData - ZOFF;
3455 float* dlyrd = dlybuf1 + (irdphase & mask);
3456 float* dlywr = dlybuf1 + (iwrphase & mask);
3457 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3458 if (decaytime == unit->m_decaytime) {
3459 long remain = inNumSamples;
3460 while (remain) {
3461 long rdspace = dlyN - dlyrd;
3462 long wrspace = dlyN - dlywr;
3463 long nsmps = sc_min(rdspace, wrspace);
3464 nsmps = sc_min(remain, nsmps);
3465 remain -= nsmps;
3466 LOOP1(nsmps,
3467 float value = ZXP(dlyrd);
3468 float dwr = value * feedbk + ZXP(in);
3469 ZXP(dlywr) = dwr;
3470 ZXP(out) = value - feedbk * dwr;
3472 if (dlyrd == dlyN) dlyrd = dlybuf1;
3473 if (dlywr == dlyN) dlywr = dlybuf1;
3475 } else {
3476 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3477 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3478 long remain = inNumSamples;
3479 while (remain) {
3480 long rdspace = dlyN - dlyrd;
3481 long wrspace = dlyN - dlywr;
3482 long nsmps = sc_min(rdspace, wrspace);
3483 nsmps = sc_min(remain, nsmps);
3484 remain -= nsmps;
3486 LOOP1(nsmps,
3487 float value = ZXP(dlyrd);
3488 float dwr = value * feedbk + ZXP(in);
3489 ZXP(dlywr) = dwr;
3490 ZXP(out) = value - feedbk * dwr;
3491 feedbk += feedbk_slope;
3493 if (dlyrd == dlyN) dlyrd = dlybuf1;
3494 if (dlywr == dlyN) dlywr = dlybuf1;
3496 unit->m_feedbk = feedbk;
3497 unit->m_decaytime = decaytime;
3499 iwrphase += inNumSamples;
3500 } else {
3501 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3502 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3504 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3505 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3506 LOOP1(inNumSamples,
3507 dsamp += dsamp_slope;
3508 feedbk += feedbk_slope;
3509 AllpassN_helper<false>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3511 unit->m_feedbk = feedbk;
3512 unit->m_dsamp = dsamp;
3513 unit->m_delaytime = delaytime;
3514 unit->m_decaytime = decaytime;
3517 unit->m_iwrphase = iwrphase;
3521 void BufAllpassN_next_z(BufAllpassN *unit, int inNumSamples)
3523 float *out = ZOUT(0);
3524 const float *in = ZIN(1);
3525 float delaytime = ZIN0(2);
3526 float decaytime = ZIN0(3);
3528 GET_BUF
3529 CHECK_BUF
3530 long iwrphase = unit->m_iwrphase;
3531 float dsamp = unit->m_dsamp;
3532 float feedbk = unit->m_feedbk;
3534 //postbuf("BufAllpassN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3535 if (delaytime == unit->m_delaytime) {
3536 long irdphase = iwrphase - (long)dsamp;
3537 float* dlybuf1 = bufData - ZOFF;
3538 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3539 if (decaytime == unit->m_decaytime) {
3540 long remain = inNumSamples;
3541 while (remain) {
3542 float* dlywr = dlybuf1 + (iwrphase & mask);
3543 float* dlyrd = dlybuf1 + (irdphase & mask);
3544 long rdspace = dlyN - dlyrd;
3545 long wrspace = dlyN - dlywr;
3546 long nsmps = sc_min(rdspace, wrspace);
3547 nsmps = sc_min(remain, nsmps);
3548 remain -= nsmps;
3549 if (irdphase < 0) {
3550 feedbk = -feedbk;
3551 LOOP1(nsmps,
3552 float dwr = ZXP(in);
3553 ZXP(dlywr) = dwr;
3554 ZXP(out) = feedbk * dwr;
3556 feedbk = -feedbk;
3557 } else {
3558 LOOP1(nsmps,
3559 float x1 = ZXP(dlyrd);
3560 float dwr = x1 * feedbk + ZXP(in);
3561 ZXP(dlywr) = dwr;
3562 ZXP(out) = x1 - feedbk * dwr;
3565 iwrphase += nsmps;
3566 irdphase += nsmps;
3568 } else {
3569 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3570 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3571 long remain = inNumSamples;
3572 while (remain) {
3573 float* dlyrd = dlybuf1 + (irdphase & mask);
3574 float* dlywr = dlybuf1 + (iwrphase & mask);
3575 long rdspace = dlyN - dlyrd;
3576 long wrspace = dlyN - dlywr;
3577 long nsmps = sc_min(rdspace, wrspace);
3578 nsmps = sc_min(remain, nsmps);
3579 remain -= nsmps;
3581 if (irdphase < 0) {
3582 dlyrd += nsmps;
3583 LOOP1(nsmps,
3584 float dwr = ZXP(in);
3585 ZXP(dlywr) = dwr;
3586 ZXP(out) = -feedbk * dwr;
3587 feedbk += feedbk_slope;
3589 } else {
3590 LOOP1(nsmps,
3591 float x1 = ZXP(dlyrd);
3592 float dwr = x1 * feedbk + ZXP(in);
3593 ZXP(dlywr) = dwr;
3594 ZXP(out) = x1 - feedbk * dwr;
3595 feedbk += feedbk_slope;
3598 iwrphase += nsmps;
3599 irdphase += nsmps;
3601 unit->m_feedbk = feedbk;
3602 unit->m_decaytime = decaytime;
3604 } else {
3605 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3606 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3608 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3609 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3611 LOOP1(inNumSamples,
3612 dsamp += dsamp_slope;
3613 feedbk += feedbk_slope;
3614 AllpassN_helper<true>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3616 unit->m_feedbk = feedbk;
3617 unit->m_dsamp = dsamp;
3618 unit->m_delaytime = delaytime;
3619 unit->m_decaytime = decaytime;
3622 unit->m_iwrphase = iwrphase;
3624 unit->m_numoutput += inNumSamples;
3625 if (unit->m_numoutput >= bufSamples)
3626 SETCALC(BufAllpassN_next);
3629 template <bool checked>
3630 inline void BufAllpassN_perform_a(BufAllpassN *unit, int inNumSamples)
3632 BufFilterX_perform_a<AllpassN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassN_next_a);
3635 void BufAllpassN_next_a(BufAllpassN *unit, int inNumSamples)
3637 BufAllpassN_perform_a<false>(unit, inNumSamples);
3640 void BufAllpassN_next_a_z(BufAllpassN *unit, int inNumSamples)
3642 BufAllpassN_perform_a<true>(unit, inNumSamples);
3646 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3647 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3649 void BufAllpassL_Ctor(BufAllpassL *unit)
3651 BufFeedbackDelay_Reset(unit);
3652 if(INRATE(2) == calc_FullRate)
3653 SETCALC(BufAllpassL_next_a_z);
3654 else
3655 SETCALC(BufAllpassL_next_z);
3656 ZOUT0(0) = 0.f;
3659 template <bool checked>
3660 inline void BufAllpassL_perform(BufAllpassL *unit, int inNumSamples)
3662 BufFilterX_perform<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassL_next);
3665 void BufAllpassL_next(BufAllpassL *unit, int inNumSamples)
3667 BufAllpassL_perform<false>(unit, inNumSamples);
3670 void BufAllpassL_next_z(BufAllpassL *unit, int inNumSamples)
3672 BufAllpassL_perform<true>(unit, inNumSamples);
3675 template <bool checked>
3676 inline void BufAllpassL_perform_a(BufAllpassL *unit, int inNumSamples)
3678 BufFilterX_perform_a<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassL_next_a);
3681 void BufAllpassL_next_a(BufAllpassL *unit, int inNumSamples)
3683 BufAllpassL_perform_a<false>(unit, inNumSamples);
3686 void BufAllpassL_next_a_z(BufAllpassL *unit, int inNumSamples)
3688 BufAllpassL_perform_a<true>(unit, inNumSamples);
3692 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3693 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3695 void BufAllpassC_Ctor(BufAllpassC *unit)
3697 BufFeedbackDelay_Reset(unit);
3698 if(INRATE(2) == calc_FullRate)
3699 SETCALC(BufAllpassC_next_a_z);
3700 else
3701 SETCALC(BufAllpassC_next_z);
3702 ZOUT0(0) = 0.f;
3705 template <bool checked>
3706 inline void BufAllpassC_perform(BufAllpassC *unit, int inNumSamples)
3708 BufFilterX_perform<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassC_next);
3711 void BufAllpassC_next(BufAllpassC *unit, int inNumSamples)
3713 BufAllpassC_perform<false>(unit, inNumSamples);
3716 void BufAllpassC_next_z(BufAllpassC *unit, int inNumSamples)
3718 BufAllpassC_perform<true>(unit, inNumSamples);
3721 template <bool checked>
3722 inline void BufAllpassC_perform_a(BufAllpassC *unit, int inNumSamples)
3724 BufFilterX_perform_a<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassC_next_a);
3727 void BufAllpassC_next_a(BufAllpassC *unit, int inNumSamples)
3729 BufAllpassC_perform_a<false>(unit, inNumSamples);
3732 void BufAllpassC_next_a_z(BufAllpassC *unit, int inNumSamples)
3734 BufAllpassC_perform_a<true>(unit, inNumSamples);
3737 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3738 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3739 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3740 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3742 static bool DelayUnit_AllocDelayLine(DelayUnit *unit, const char * className)
3744 long delaybufsize = (long)ceil(unit->m_maxdelaytime * SAMPLERATE + 1.f);
3745 delaybufsize = delaybufsize + BUFLENGTH;
3746 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
3747 unit->m_fdelaylen = unit->m_idelaylen = delaybufsize;
3749 if (unit->m_dlybuf)
3750 RTFree(unit->mWorld, unit->m_dlybuf);
3751 unit->m_dlybuf = (float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
3753 if (unit->m_dlybuf == NULL) {
3754 SETCALC(ft->fClearUnitOutputs);
3755 ClearUnitOutputs(unit, 1);
3757 if(unit->mWorld->mVerbosity > -2)
3758 Print("Failed to allocate memory for %s ugen.\n", className);
3761 unit->m_mask = delaybufsize - 1;
3762 return (unit->m_dlybuf != NULL);
3765 template <typename Unit>
3766 static float CalcDelay(Unit *unit, float delaytime)
3768 float minDelay = Unit::minDelaySamples;
3769 float next_dsamp = delaytime * (float)SAMPLERATE;
3770 return sc_clip(next_dsamp, minDelay, unit->m_fdelaylen);
3773 template <typename Unit>
3774 static bool DelayUnit_Reset(Unit *unit, const char * className)
3776 unit->m_maxdelaytime = ZIN0(1);
3777 unit->m_delaytime = ZIN0(2);
3778 unit->m_dlybuf = 0;
3780 if (!DelayUnit_AllocDelayLine(unit, className))
3781 return false;
3783 unit->m_dsamp = CalcDelay(unit, unit->m_delaytime);
3785 unit->m_numoutput = 0;
3786 unit->m_iwrphase = 0;
3787 return true;
3791 void DelayUnit_Dtor(DelayUnit *unit)
3793 RTFree(unit->mWorld, unit->m_dlybuf);
3796 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3798 template <typename Unit>
3799 static bool FeedbackDelay_Reset(Unit *unit, const char * className)
3801 unit->m_decaytime = ZIN0(3);
3803 bool allocationSucessful = DelayUnit_Reset(unit, className);
3804 if (!allocationSucessful)
3805 return false;
3807 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
3808 return true;
3811 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3813 /* template function to generate delay ugen function, control-rate delay time */
3814 template <typename PerformClass,
3815 typename DelayX
3817 inline void DelayX_perform(DelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3819 float *out = ZOUT(0);
3820 const float *in = ZIN(0);
3821 float delaytime = ZIN0(2);
3823 float *dlybuf = unit->m_dlybuf;
3824 long iwrphase = unit->m_iwrphase;
3825 float dsamp = unit->m_dsamp;
3826 long mask = unit->m_mask;
3828 if (delaytime == unit->m_delaytime) {
3829 long idsamp = (long)dsamp;
3830 float frac = dsamp - idsamp;
3831 LOOP1(inNumSamples,
3832 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3834 } else {
3835 float next_dsamp = CalcDelay(unit, delaytime);
3836 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3838 LOOP1(inNumSamples,
3839 dsamp += dsamp_slope;
3840 long idsamp = (long)dsamp;
3841 float frac = dsamp - idsamp;
3842 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3844 unit->m_dsamp = dsamp;
3845 unit->m_delaytime = delaytime;
3848 unit->m_iwrphase = iwrphase;
3850 if (PerformClass::checked) {
3851 unit->m_numoutput += inNumSamples;
3852 if (unit->m_numoutput >= unit->m_idelaylen)
3853 unit->mCalcFunc = resetFunc;
3857 /* template function to generate delay ugen function, audio-rate delay time */
3858 template <typename PerformClass,
3859 typename DelayX
3861 inline void DelayX_perform_a(DelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3863 float *out = ZOUT(0);
3864 const float *in = ZIN(0);
3865 float * delaytime = ZIN(2);
3867 float *dlybuf = unit->m_dlybuf;
3868 long iwrphase = unit->m_iwrphase;
3869 long mask = unit->m_mask;
3871 LOOP1(inNumSamples,
3872 float dsamp = CalcDelay(unit, ZXP(delaytime));
3873 long idsamp = (long)dsamp;
3875 float frac = dsamp - idsamp;
3876 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3879 unit->m_iwrphase = iwrphase;
3881 if (PerformClass::checked)
3883 unit->m_numoutput += inNumSamples;
3884 if (unit->m_numoutput >= unit->m_idelaylen)
3885 unit->mCalcFunc = resetFunc;
3890 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3892 void Delay_next_0(DelayUnit *unit, int inNumSamples)
3894 float *out = OUT(0);
3895 const float *in = IN(0);
3897 memcpy(out, in, inNumSamples * sizeof(float));
3900 void Delay_next_0_nop(DelayUnit *unit, int inNumSamples)
3903 #ifdef NOVA_SIMD
3904 void Delay_next_0_nova(DelayUnit *unit, int inNumSamples)
3906 nova::copyvec_simd(OUT(0), IN(0), inNumSamples);
3908 #endif
3910 static bool DelayUnit_init_0(DelayUnit *unit)
3912 if (INRATE(2) == calc_ScalarRate && ZIN0(2) == 0) {
3913 if (ZIN(0) == ZOUT(0))
3914 SETCALC(Delay_next_0_nop);
3915 #ifdef NOVA_SIMD
3916 else if (!(BUFLENGTH & 15))
3917 SETCALC(Delay_next_0_nova);
3918 #endif
3919 else
3920 SETCALC(Delay_next_0);
3922 ZOUT0(0) = ZIN0(0);
3923 return true;
3924 } else
3925 return false;
3928 enum {
3929 initializationComplete,
3930 initializationIncomplete
3933 template <typename Delay>
3934 static int Delay_Ctor(Delay *unit, const char *className)
3936 bool allocationSucessful = DelayUnit_Reset(unit, className);
3937 if (!allocationSucessful)
3938 return initializationComplete;
3940 // optimize for a constant delay of zero
3941 if (DelayUnit_init_0(unit))
3942 return initializationComplete;
3943 return initializationIncomplete;
3946 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3948 void DelayN_Ctor(DelayN *unit)
3950 if (Delay_Ctor(unit, "DelayN") == initializationComplete)
3951 return;
3953 if (INRATE(2) == calc_FullRate)
3954 SETCALC(DelayN_next_a_z);
3955 else
3956 SETCALC(DelayN_next_z);
3957 ZOUT0(0) = 0.f;
3960 void DelayN_next(DelayN *unit, int inNumSamples)
3962 float *out = ZOUT(0);
3963 const float *in = ZIN(0);
3964 float delaytime = ZIN0(2);
3966 float *dlybuf = unit->m_dlybuf;
3967 long iwrphase = unit->m_iwrphase;
3968 float dsamp = unit->m_dsamp;
3969 long mask = unit->m_mask;
3971 //Print("DelayN_next %p %g %g %d %d\n", unit, delaytime, dsamp, mask, iwrphase);
3972 if (delaytime == unit->m_delaytime) {
3973 DelayN_delay_loop<false>(out, in, iwrphase, dsamp, mask, dlybuf, inNumSamples, unit->m_idelaylen);
3974 } else {
3975 float next_dsamp = CalcDelay(unit, delaytime);
3976 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3978 LOOP1(inNumSamples,
3979 dsamp += dsamp_slope;
3980 DelayN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask);
3982 unit->m_dsamp = dsamp;
3983 unit->m_delaytime = delaytime;
3986 unit->m_iwrphase = iwrphase;
3990 void DelayN_next_z(DelayN *unit, int inNumSamples)
3992 float *out = ZOUT(0);
3993 const float *in = ZIN(0);
3994 float delaytime = ZIN0(2);
3996 float *dlybuf = unit->m_dlybuf;
3997 long iwrphase = unit->m_iwrphase;
3998 float dsamp = unit->m_dsamp;
3999 long mask = unit->m_mask;
4001 if (delaytime == unit->m_delaytime) {
4002 DelayN_delay_loop<true>(out, in, iwrphase, dsamp, mask, dlybuf, inNumSamples, unit->m_idelaylen);
4003 } else {
4004 float next_dsamp = CalcDelay(unit, delaytime);
4005 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4007 LOOP1(inNumSamples,
4008 dsamp += dsamp_slope;
4009 DelayN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask);
4011 unit->m_dsamp = dsamp;
4012 unit->m_delaytime = delaytime;
4015 unit->m_iwrphase = iwrphase;
4017 unit->m_numoutput += inNumSamples;
4018 if (unit->m_numoutput >= unit->m_idelaylen)
4019 SETCALC(DelayN_next);
4022 template <bool checked>
4023 inline void DelayN_perform_a(DelayN *unit, int inNumSamples)
4025 DelayX_perform_a<DelayN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayN_next_a);
4028 void DelayN_next_a(DelayN *unit, int inNumSamples)
4030 DelayN_perform_a<false>(unit, inNumSamples);
4033 void DelayN_next_a_z(DelayN *unit, int inNumSamples)
4035 DelayN_perform_a<true>(unit, inNumSamples);
4039 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4041 void DelayL_Ctor(DelayL *unit)
4043 if (Delay_Ctor(unit, "DelayL") == initializationComplete)
4044 return;
4046 if (INRATE(2) == calc_FullRate)
4047 SETCALC(DelayL_next_a_z);
4048 else
4049 SETCALC(DelayL_next_z);
4050 ZOUT0(0) = 0.f;
4053 template <bool checked>
4054 inline void DelayL_perform(DelayL *unit, int inNumSamples)
4056 DelayX_perform<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayL_next);
4059 void DelayL_next(DelayL *unit, int inNumSamples)
4061 DelayL_perform<false>(unit, inNumSamples);
4064 void DelayL_next_z(DelayL *unit, int inNumSamples)
4066 DelayL_perform<true>(unit, inNumSamples);
4069 template <bool checked>
4070 inline void DelayL_perform_a(DelayL *unit, int inNumSamples)
4072 DelayX_perform_a<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayL_next_a);
4075 void DelayL_next_a(DelayL *unit, int inNumSamples)
4077 DelayL_perform_a<false>(unit, inNumSamples);
4080 void DelayL_next_a_z(DelayL *unit, int inNumSamples)
4082 DelayL_perform_a<true>(unit, inNumSamples);
4086 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4088 void DelayC_Ctor(DelayC *unit)
4090 if (Delay_Ctor(unit, "DelayC") == initializationComplete)
4091 return;
4093 if (INRATE(2) == calc_FullRate)
4094 SETCALC(DelayC_next_a_z);
4095 else
4096 SETCALC(DelayC_next_z);
4097 ZOUT0(0) = 0.f;
4100 template <bool checked>
4101 inline void DelayC_perform(DelayC *unit, int inNumSamples)
4103 DelayX_perform<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayC_next);
4106 void DelayC_next(DelayC *unit, int inNumSamples)
4108 DelayC_perform<false>(unit, inNumSamples);
4111 void DelayC_next_z(DelayC *unit, int inNumSamples)
4113 DelayC_perform<true>(unit, inNumSamples);
4117 template <bool checked>
4118 inline void DelayC_perform_a(DelayC *unit, int inNumSamples)
4120 DelayX_perform_a<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayC_next_a);
4123 void DelayC_next_a(DelayC *unit, int inNumSamples)
4125 DelayC_perform_a<false>(unit, inNumSamples);
4128 void DelayC_next_a_z(DelayC *unit, int inNumSamples)
4130 DelayC_perform_a<true>(unit, inNumSamples);
4133 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4134 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4136 template <typename PerformClass,
4137 typename BufCombX
4139 inline void FilterX_perform(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
4141 float *out = ZOUT(0);
4142 const float *in = ZIN(0);
4143 float delaytime = ZIN0(2);
4144 float decaytime = ZIN0(3);
4146 float *dlybuf = unit->m_dlybuf;
4147 long iwrphase = unit->m_iwrphase;
4148 float dsamp = unit->m_dsamp;
4149 float feedbk = unit->m_feedbk;
4150 long mask = unit->m_mask;
4152 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
4153 long idsamp = (long)dsamp;
4154 float frac = dsamp - idsamp;
4155 LOOP1(inNumSamples,
4156 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4158 } else {
4159 float next_dsamp = CalcDelay(unit, delaytime);
4160 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4162 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4163 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4165 LOOP1(inNumSamples,
4166 dsamp += dsamp_slope;
4167 feedbk += feedbk_slope;
4168 long idsamp = (long)dsamp;
4169 float frac = dsamp - idsamp;
4170 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4172 unit->m_feedbk = feedbk;
4173 unit->m_dsamp = dsamp;
4174 unit->m_delaytime = delaytime;
4175 unit->m_decaytime = decaytime;
4178 unit->m_iwrphase = iwrphase;
4180 if (PerformClass::checked) {
4181 unit->m_numoutput += inNumSamples;
4182 if (unit->m_numoutput >= unit->m_idelaylen)
4183 unit->mCalcFunc = resetFunc;
4187 template <typename PerformClass,
4188 typename CombX
4190 inline void FilterX_perform_a(CombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
4192 float *out = ZOUT(0);
4193 const float *in = ZIN(0);
4194 float * delaytime = ZIN(2);
4195 float decaytime = ZIN0(3);
4197 float *dlybuf = unit->m_dlybuf;
4198 long iwrphase = unit->m_iwrphase;
4199 float dsamp = unit->m_dsamp;
4200 float feedbk = unit->m_feedbk;
4201 long mask = unit->m_mask;
4203 LOOP1(inNumSamples,
4204 float del = ZXP(delaytime);
4205 float dsamp = CalcDelay(unit, del);
4206 float feedbk = sc_CalcFeedback(del, decaytime);
4208 long idsamp = (long)dsamp;
4209 float frac = dsamp - idsamp;
4210 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4213 unit->m_iwrphase = iwrphase;
4215 if (PerformClass::checked)
4217 unit->m_numoutput += inNumSamples;
4218 if (unit->m_numoutput >= unit->m_idelaylen)
4219 unit->mCalcFunc = resetFunc;
4223 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4225 void CombN_Ctor(CombN *unit)
4227 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombN");
4228 if (!allocationSucessful)
4229 return;
4231 if(INRATE(2) == calc_FullRate)
4232 SETCALC(CombN_next_a_z);
4233 else
4234 SETCALC(CombN_next_z);
4235 ZOUT0(0) = 0.f;
4238 void CombN_next(CombN *unit, int inNumSamples)
4240 float *out = ZOUT(0);
4241 const float *in = ZIN(0);
4242 float delaytime = ZIN0(2);
4243 float decaytime = ZIN0(3);
4245 float *dlybuf = unit->m_dlybuf;
4246 long iwrphase = unit->m_iwrphase;
4247 float dsamp = unit->m_dsamp;
4248 float feedbk = unit->m_feedbk;
4249 long mask = unit->m_mask;
4251 //postbuf("CombN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4252 if (delaytime == unit->m_delaytime) {
4253 long irdphase = iwrphase - (long)dsamp;
4254 float* dlybuf1 = dlybuf - ZOFF;
4255 float* dlyrd = dlybuf1 + (irdphase & mask);
4256 float* dlywr = dlybuf1 + (iwrphase & mask);
4257 float* dlyN = dlybuf1 + unit->m_idelaylen;
4258 if (decaytime == unit->m_decaytime) {
4259 long remain = inNumSamples;
4260 while (remain) {
4261 long rdspace = dlyN - dlyrd;
4262 long wrspace = dlyN - dlywr;
4263 long nsmps = sc_min(rdspace, wrspace);
4264 nsmps = sc_min(remain, nsmps);
4265 remain -= nsmps;
4266 LOOP(nsmps,
4267 float value = ZXP(dlyrd);
4268 ZXP(dlywr) = value * feedbk + ZXP(in);
4269 ZXP(out) = value;
4271 if (dlyrd == dlyN) dlyrd = dlybuf1;
4272 if (dlywr == dlyN) dlywr = dlybuf1;
4274 } else {
4275 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4276 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4277 long remain = inNumSamples;
4278 while (remain) {
4279 long rdspace = dlyN - dlyrd;
4280 long wrspace = dlyN - dlywr;
4281 long nsmps = sc_min(rdspace, wrspace);
4282 nsmps = sc_min(remain, nsmps);
4283 remain -= nsmps;
4285 LOOP(nsmps,
4286 float value = ZXP(dlyrd);
4287 ZXP(dlywr) = value * feedbk + ZXP(in);
4288 ZXP(out) = value;
4289 feedbk += feedbk_slope;
4291 if (dlyrd == dlyN) dlyrd = dlybuf1;
4292 if (dlywr == dlyN) dlywr = dlybuf1;
4294 unit->m_feedbk = feedbk;
4295 unit->m_decaytime = decaytime;
4297 iwrphase += inNumSamples;
4298 } else {
4299 float next_dsamp = CalcDelay(unit, delaytime);
4300 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4302 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4303 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4304 LOOP1(inNumSamples,
4305 dsamp += dsamp_slope;
4306 feedbk += feedbk_slope;
4307 CombN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4309 unit->m_feedbk = feedbk;
4310 unit->m_dsamp = dsamp;
4311 unit->m_delaytime = delaytime;
4312 unit->m_decaytime = decaytime;
4315 unit->m_iwrphase = iwrphase;
4319 void CombN_next_z(CombN *unit, int inNumSamples)
4321 float *out = ZOUT(0);
4322 const float *in = ZIN(0);
4323 float delaytime = ZIN0(2);
4324 float decaytime = ZIN0(3);
4326 float *dlybuf = unit->m_dlybuf;
4327 long iwrphase = unit->m_iwrphase;
4328 float dsamp = unit->m_dsamp;
4329 float feedbk = unit->m_feedbk;
4330 long mask = unit->m_mask;
4332 //postbuf("CombN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4333 if (delaytime == unit->m_delaytime) {
4334 long irdphase = iwrphase - (long)dsamp;
4335 float* dlybuf1 = dlybuf - ZOFF;
4336 float* dlyN = dlybuf1 + unit->m_idelaylen;
4337 if (decaytime == unit->m_decaytime) {
4338 long remain = inNumSamples;
4339 while (remain) {
4340 float* dlywr = dlybuf1 + (iwrphase & mask);
4341 float* dlyrd = dlybuf1 + (irdphase & mask);
4342 long rdspace = dlyN - dlyrd;
4343 long wrspace = dlyN - dlywr;
4344 long nsmps = sc_min(rdspace, wrspace);
4345 nsmps = sc_min(remain, nsmps);
4346 remain -= nsmps;
4347 if (irdphase < 0) {
4348 LOOP(nsmps,
4349 ZXP(dlywr) = ZXP(in);
4350 ZXP(out) = 0.f;
4352 } else {
4353 LOOP(nsmps,
4354 float value = ZXP(dlyrd);
4355 ZXP(dlywr) = value * feedbk + ZXP(in);
4356 ZXP(out) = value;
4359 iwrphase += nsmps;
4360 irdphase += nsmps;
4362 } else {
4363 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4364 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4365 long remain = inNumSamples;
4366 while (remain) {
4367 float* dlyrd = dlybuf1 + (irdphase & mask);
4368 float* dlywr = dlybuf1 + (iwrphase & mask);
4369 long rdspace = dlyN - dlyrd;
4370 long wrspace = dlyN - dlywr;
4371 long nsmps = sc_min(rdspace, wrspace);
4372 nsmps = sc_min(remain, nsmps);
4373 remain -= nsmps;
4375 if (irdphase < 0) {
4376 feedbk += nsmps * feedbk_slope;
4377 dlyrd += nsmps;
4378 LOOP(nsmps,
4379 ZXP(dlywr) = ZXP(in);
4380 ZXP(out) = 0.f;
4382 } else {
4383 LOOP(nsmps,
4384 float value = ZXP(dlyrd);
4385 ZXP(dlywr) = value * feedbk + ZXP(in);
4386 ZXP(out) = value;
4387 feedbk += feedbk_slope;
4390 iwrphase += nsmps;
4391 irdphase += nsmps;
4393 unit->m_feedbk = feedbk;
4394 unit->m_decaytime = decaytime;
4396 } else {
4398 float next_dsamp = CalcDelay(unit, delaytime);
4399 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4401 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4402 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4404 LOOP1(inNumSamples,
4405 dsamp += dsamp_slope;
4406 feedbk += feedbk_slope;
4407 CombN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4409 unit->m_feedbk = feedbk;
4410 unit->m_dsamp = dsamp;
4411 unit->m_delaytime = delaytime;
4412 unit->m_decaytime = decaytime;
4415 unit->m_iwrphase = iwrphase;
4417 unit->m_numoutput += inNumSamples;
4418 if (unit->m_numoutput >= unit->m_idelaylen)
4419 SETCALC(CombN_next);
4422 template <bool checked>
4423 inline void CombN_perform_a(CombN *unit, int inNumSamples)
4425 FilterX_perform_a<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombN_next_a);
4428 void CombN_next_a(CombN *unit, int inNumSamples)
4430 CombN_perform_a<false>(unit, inNumSamples);
4433 void CombN_next_a_z(CombN *unit, int inNumSamples)
4435 CombN_perform_a<true>(unit, inNumSamples);
4439 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4440 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4442 void CombL_Ctor(CombL *unit)
4444 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombL");
4445 if (!allocationSucessful)
4446 return;
4448 if(INRATE(2) == calc_FullRate)
4449 SETCALC(CombL_next_a_z);
4450 else
4451 SETCALC(CombL_next_z);
4452 ZOUT0(0) = 0.f;
4455 template <bool checked>
4456 inline void CombL_perform(CombL *unit, int inNumSamples)
4458 FilterX_perform<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombL_next);
4461 void CombL_next(CombL *unit, int inNumSamples)
4463 CombL_perform<false>(unit, inNumSamples);
4466 void CombL_next_z(CombL *unit, int inNumSamples)
4468 CombL_perform<true>(unit, inNumSamples);
4471 template <bool checked>
4472 inline void CombL_perform_a(CombL *unit, int inNumSamples)
4474 FilterX_perform_a<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombL_next_a);
4477 void CombL_next_a(CombL *unit, int inNumSamples)
4479 CombL_perform_a<false>(unit, inNumSamples);
4482 void CombL_next_a_z(CombL *unit, int inNumSamples)
4484 CombL_perform_a<true>(unit, inNumSamples);
4487 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4489 void CombC_Ctor(CombC *unit)
4491 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombC");
4492 if (!allocationSucessful)
4493 return;
4495 if(INRATE(2) == calc_FullRate)
4496 SETCALC(CombC_next_a_z);
4497 else
4498 SETCALC(CombC_next_z);
4499 ZOUT0(0) = 0.f;
4502 template <bool checked>
4503 inline void CombC_perform(CombC *unit, int inNumSamples)
4505 FilterX_perform<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombC_next);
4508 void CombC_next(CombC *unit, int inNumSamples)
4510 CombC_perform<false>(unit, inNumSamples);
4513 void CombC_next_z(CombC *unit, int inNumSamples)
4515 CombC_perform<true>(unit, inNumSamples);
4518 template <bool checked>
4519 inline void CombC_perform_a(CombC *unit, int inNumSamples)
4521 FilterX_perform_a<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombC_next_a);
4524 void CombC_next_a(CombC *unit, int inNumSamples)
4526 CombC_perform_a<false>(unit, inNumSamples);
4529 void CombC_next_a_z(CombC *unit, int inNumSamples)
4531 CombC_perform_a<true>(unit, inNumSamples);
4535 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4536 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4538 void AllpassN_Ctor(AllpassN *unit)
4540 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassN");
4541 if (!allocationSucessful)
4542 return;
4544 if(INRATE(2) == calc_FullRate)
4545 SETCALC(AllpassN_next_a_z);
4546 else
4547 SETCALC(AllpassN_next_z);
4548 ZOUT0(0) = 0.f;
4551 void AllpassN_next(AllpassN *unit, int inNumSamples)
4553 float *out = ZOUT(0);
4554 const float *in = ZIN(0);
4555 float delaytime = ZIN0(2);
4556 float decaytime = ZIN0(3);
4558 float *dlybuf = unit->m_dlybuf;
4559 long iwrphase = unit->m_iwrphase;
4560 float dsamp = unit->m_dsamp;
4561 float feedbk = unit->m_feedbk;
4562 long mask = unit->m_mask;
4564 //postbuf("AllpassN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4565 if (delaytime == unit->m_delaytime) {
4566 long irdphase = iwrphase - (long)dsamp;
4567 float* dlybuf1 = dlybuf - ZOFF;
4568 float* dlyrd = dlybuf1 + (irdphase & mask);
4569 float* dlywr = dlybuf1 + (iwrphase & mask);
4570 float* dlyN = dlybuf1 + unit->m_idelaylen;
4571 if (decaytime == unit->m_decaytime) {
4572 long remain = inNumSamples;
4573 while (remain) {
4574 long rdspace = dlyN - dlyrd;
4575 long wrspace = dlyN - dlywr;
4576 long nsmps = sc_min(rdspace, wrspace);
4577 nsmps = sc_min(remain, nsmps);
4578 remain -= nsmps;
4579 LOOP(nsmps,
4580 float value = ZXP(dlyrd);
4581 float dwr = value * feedbk + ZXP(in);
4582 ZXP(dlywr) = dwr;
4583 ZXP(out) = value - feedbk * dwr;
4585 if (dlyrd == dlyN) dlyrd = dlybuf1;
4586 if (dlywr == dlyN) dlywr = dlybuf1;
4588 } else {
4589 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4590 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4591 long remain = inNumSamples;
4592 while (remain) {
4593 long rdspace = dlyN - dlyrd;
4594 long wrspace = dlyN - dlywr;
4595 long nsmps = sc_min(rdspace, wrspace);
4596 nsmps = sc_min(remain, nsmps);
4597 remain -= nsmps;
4599 LOOP(nsmps,
4600 float value = ZXP(dlyrd);
4601 float dwr = value * feedbk + ZXP(in);
4602 ZXP(dlywr) = dwr;
4603 ZXP(out) = value - feedbk * dwr;
4604 feedbk += feedbk_slope;
4606 if (dlyrd == dlyN) dlyrd = dlybuf1;
4607 if (dlywr == dlyN) dlywr = dlybuf1;
4609 unit->m_feedbk = feedbk;
4610 unit->m_decaytime = decaytime;
4612 iwrphase += inNumSamples;
4613 } else {
4614 float next_dsamp = CalcDelay(unit, delaytime);
4615 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4617 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4618 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4619 LOOP1(inNumSamples,
4620 dsamp += dsamp_slope;
4621 feedbk += feedbk_slope;
4622 AllpassN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4624 unit->m_feedbk = feedbk;
4625 unit->m_dsamp = dsamp;
4626 unit->m_delaytime = delaytime;
4627 unit->m_decaytime = decaytime;
4630 unit->m_iwrphase = iwrphase;
4634 void AllpassN_next_z(AllpassN *unit, int inNumSamples)
4636 float *out = ZOUT(0);
4637 const float *in = ZIN(0);
4638 float delaytime = ZIN0(2);
4639 float decaytime = ZIN0(3);
4641 float *dlybuf = unit->m_dlybuf;
4642 long iwrphase = unit->m_iwrphase;
4643 float dsamp = unit->m_dsamp;
4644 float feedbk = unit->m_feedbk;
4645 long mask = unit->m_mask;
4647 //postbuf("AllpassN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4648 if (delaytime == unit->m_delaytime) {
4649 long irdphase = iwrphase - (long)dsamp;
4650 float* dlybuf1 = dlybuf - ZOFF;
4651 float* dlyN = dlybuf1 + unit->m_idelaylen;
4652 if (decaytime == unit->m_decaytime) {
4653 long remain = inNumSamples;
4654 while (remain) {
4655 float* dlywr = dlybuf1 + (iwrphase & mask);
4656 float* dlyrd = dlybuf1 + (irdphase & mask);
4657 long rdspace = dlyN - dlyrd;
4658 long wrspace = dlyN - dlywr;
4659 long nsmps = sc_min(rdspace, wrspace);
4660 nsmps = sc_min(remain, nsmps);
4661 remain -= nsmps;
4662 if (irdphase < 0) {
4663 feedbk = -feedbk;
4664 LOOP(nsmps,
4665 float dwr = ZXP(in);
4666 ZXP(dlywr) = dwr;
4667 ZXP(out) = feedbk * dwr;
4669 feedbk = -feedbk;
4670 } else {
4671 LOOP(nsmps,
4672 float x1 = ZXP(dlyrd);
4673 float dwr = x1 * feedbk + ZXP(in);
4674 ZXP(dlywr) = dwr;
4675 ZXP(out) = x1 - feedbk * dwr;
4678 iwrphase += nsmps;
4679 irdphase += nsmps;
4681 } else {
4682 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4683 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4684 long remain = inNumSamples;
4685 while (remain) {
4686 float* dlyrd = dlybuf1 + (irdphase & mask);
4687 float* dlywr = dlybuf1 + (iwrphase & mask);
4688 long rdspace = dlyN - dlyrd;
4689 long wrspace = dlyN - dlywr;
4690 long nsmps = sc_min(rdspace, wrspace);
4691 nsmps = sc_min(remain, nsmps);
4692 remain -= nsmps;
4694 if (irdphase < 0) {
4695 dlyrd += nsmps;
4696 LOOP(nsmps,
4697 float dwr = ZXP(in);
4698 ZXP(dlywr) = dwr;
4699 ZXP(out) = -feedbk * dwr;
4700 feedbk += feedbk_slope;
4702 } else {
4703 LOOP(nsmps,
4704 float x1 = ZXP(dlyrd);
4705 float dwr = x1 * feedbk + ZXP(in);
4706 ZXP(dlywr) = dwr;
4707 ZXP(out) = x1 - feedbk * dwr;
4708 feedbk += feedbk_slope;
4711 iwrphase += nsmps;
4712 irdphase += nsmps;
4714 unit->m_feedbk = feedbk;
4715 unit->m_decaytime = decaytime;
4717 } else {
4718 float next_dsamp = CalcDelay(unit, delaytime);
4719 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4721 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4722 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4724 LOOP1(inNumSamples,
4725 dsamp += dsamp_slope;
4726 feedbk += feedbk_slope;
4727 AllpassN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4729 unit->m_feedbk = feedbk;
4730 unit->m_dsamp = dsamp;
4731 unit->m_delaytime = delaytime;
4732 unit->m_decaytime = decaytime;
4735 unit->m_iwrphase = iwrphase;
4737 unit->m_numoutput += inNumSamples;
4738 if (unit->m_numoutput >= unit->m_idelaylen)
4739 SETCALC(AllpassN_next);
4742 template <bool checked>
4743 inline void AllpassN_perform_a(AllpassN *unit, int inNumSamples)
4745 FilterX_perform_a<AllpassN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassN_next_a);
4748 void AllpassN_next_a(AllpassN *unit, int inNumSamples)
4750 AllpassN_perform_a<false>(unit, inNumSamples);
4753 void AllpassN_next_a_z(AllpassN *unit, int inNumSamples)
4755 AllpassN_perform_a<true>(unit, inNumSamples);
4759 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4760 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4762 void AllpassL_Ctor(AllpassL *unit)
4764 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassL");
4765 if (!allocationSucessful)
4766 return;
4768 if(INRATE(2) == calc_FullRate)
4769 SETCALC(AllpassL_next_a_z);
4770 else
4771 SETCALC(AllpassL_next_z);
4772 ZOUT0(0) = 0.f;
4775 template <bool checked>
4776 inline void AllpassL_perform(AllpassL *unit, int inNumSamples)
4778 FilterX_perform<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassL_next);
4781 void AllpassL_next(AllpassL *unit, int inNumSamples)
4783 AllpassL_perform<false>(unit, inNumSamples);
4786 void AllpassL_next_z(AllpassL *unit, int inNumSamples)
4788 AllpassL_perform<true>(unit, inNumSamples);
4791 template <bool checked>
4792 inline void AllpassL_perform_a(AllpassL *unit, int inNumSamples)
4794 FilterX_perform_a<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassL_next_a);
4797 void AllpassL_next_a(AllpassL *unit, int inNumSamples)
4799 AllpassL_perform_a<false>(unit, inNumSamples);
4802 void AllpassL_next_a_z(AllpassL *unit, int inNumSamples)
4804 AllpassL_perform_a<true>(unit, inNumSamples);
4807 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4808 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4810 void AllpassC_Ctor(AllpassC *unit)
4812 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassC");
4813 if (!allocationSucessful)
4814 return;
4816 if(INRATE(2) == calc_FullRate)
4817 SETCALC(AllpassC_next_a_z);
4818 else
4819 SETCALC(AllpassC_next_z);
4820 ZOUT0(0) = 0.f;
4823 template <bool checked>
4824 inline void AllpassC_perform(AllpassC *unit, int inNumSamples)
4826 FilterX_perform<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassC_next);
4829 void AllpassC_next(AllpassC *unit, int inNumSamples)
4831 AllpassC_perform<false>(unit, inNumSamples);
4834 void AllpassC_next_z(AllpassC *unit, int inNumSamples)
4836 AllpassC_perform<true>(unit, inNumSamples);
4839 template <bool checked>
4840 inline void AllpassC_perform_a(AllpassC *unit, int inNumSamples)
4842 FilterX_perform_a<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassC_next_a);
4845 void AllpassC_next_a(AllpassC *unit, int inNumSamples)
4847 AllpassC_perform_a<false>(unit, inNumSamples);
4850 void AllpassC_next_a_z(AllpassC *unit, int inNumSamples)
4852 AllpassC_perform_a<true>(unit, inNumSamples);
4855 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4858 inline double sc_loop1(int32 in, int32 lo, int32 hi)
4860 // avoid the divide if possible
4861 if (in >= hi) {
4862 in -= hi;
4863 if (in < hi) return in;
4864 } else if (in < lo) {
4865 in += hi;
4866 if (in >= lo) return in;
4867 } else return in;
4869 int32 range = hi - lo;
4870 return lo + range * (in-lo) / range;
4873 #if NOTYET
4875 void SimpleLoopBuf_next_kk(SimpleLoopBuf *unit, int inNumSamples)
4877 float trig = ZIN0(1);
4878 double loopstart = (double)ZIN0(2);
4879 double loopend = (double)ZIN0(3);
4880 GET_BUF
4882 int numOutputs = unit->mNumOutputs;
4883 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
4884 return;
4887 loopend = sc_max(loopend, bufFrames);
4888 int32 phase = unit->m_phase;
4889 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
4890 unit->mDone = false;
4891 phase = (int32)ZIN0(2);
4893 unit->m_prevtrig = trig;
4894 for (int i=0; i<inNumSamples; ++i) {
4895 phase = sc_loop1(phase, loopstart, loopend);
4896 int32 iphase = (int32)phase;
4897 float* table1 = bufData + iphase * bufChannels;
4898 int32 index = 0;
4899 for (uint32 channel=0; channel<bufChannels; ++channel) {
4900 OUT(channel[i]) = table1[index++];
4903 phase++;
4905 unit->m_phase = phase;
4909 void SimpleLoopBuf_Ctor(SimpleLoopBuf *unit)
4911 SETCALC(SimpleLoopBuf_next_kk);
4913 unit->m_fbufnum = -1e9f;
4914 unit->m_prevtrig = 0.;
4915 unit->m_phase = ZIN0(2);
4917 ClearUnitOutputs(unit, 1);
4919 #endif
4921 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4924 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4926 #define GET_SCOPEBUF \
4927 float fbufnum = ZIN0(0); \
4928 if (fbufnum != unit->m_fbufnum) { \
4929 World *world = unit->mWorld; \
4930 if (!world->mNumSndBufs) { \
4931 ClearUnitOutputs(unit, inNumSamples); \
4932 return; \
4934 uint32 bufnum = (int)fbufnum; \
4935 if (bufnum >= world->mNumSndBufs) bufnum = 0; \
4936 unit->m_fbufnum = fbufnum; \
4937 unit->m_buf = world->mSndBufs + bufnum; \
4938 unit->m_bufupdates = world->mSndBufUpdates + bufnum; \
4940 SndBuf *buf = unit->m_buf; \
4941 LOCK_SNDBUF(buf); \
4942 SndBufUpdates *bufupdates = unit->m_bufupdates; \
4943 float *bufData __attribute__((__unused__)) = buf->data; \
4944 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
4945 uint32 bufFrames __attribute__((__unused__)) = buf->frames; \
4947 void ScopeOut_next(ScopeOut *unit, int inNumSamples)
4949 GET_SCOPEBUF
4951 if (!bufData) {
4952 unit->m_framepos = 0;
4953 return;
4956 SETUP_IN(1)
4958 uint32 framepos = unit->m_framepos;
4959 if (framepos >= bufFrames) {
4960 unit->m_framepos = 0;
4963 if (bufupdates->reads != bufupdates->writes) {
4964 unit->m_framepos += inNumSamples;
4965 return;
4968 bufData += framepos * bufChannels;
4970 int remain = (bufFrames - framepos), wrap = 0;
4972 if(inNumSamples <= remain) {
4973 remain = inNumSamples;
4974 wrap = 0;
4976 else
4977 wrap = inNumSamples - remain;
4979 if (bufChannels > 2) {
4980 for (int j=0; j<remain; ++j) {
4981 for (uint32 i=0; i<bufChannels; ++i) {
4982 *bufData++ = *++(in[i]);
4986 bufData = buf->data;
4988 for (int j=0; j<wrap; ++j) {
4989 for (uint32 i=0; i<bufChannels; ++i) {
4990 *bufData++ = *++(in[i]);
4993 } else if (bufChannels == 2) {
4994 float *in0 = in[0];
4995 float *in1 = in[1];
4996 for (int j=0; j<remain; ++j) {
4997 *bufData++ = *++in0;
4998 *bufData++ = *++in1;
5001 bufData = buf->data;
5003 for (int j=0; j<wrap; ++j) {
5004 *bufData++ = *++in0;
5005 *bufData++ = *++in1;
5007 } else {
5008 float *in0 = in[0];
5009 for (int j=0; j<remain; ++j) {
5010 *bufData++ = *++in0;
5013 bufData = buf->data;
5015 for (int j=0; j<wrap; ++j) {
5016 *bufData++ = *++in0;
5020 unit->m_framepos += inNumSamples;
5021 unit->m_framecount += inNumSamples;
5023 if (unit->m_framecount >= bufFrames) {
5024 bufupdates->writes++;
5025 unit->m_framecount = 0;
5031 void ScopeOut_Ctor(ScopeOut *unit)
5034 unit->m_fbufnum = -1e9;
5035 unit->m_framepos = 0;
5036 unit->m_framecount = 0;
5037 unit->mIn = 0;
5038 SETCALC(ScopeOut_next);
5041 void ScopeOut_Dtor(ScopeOut *unit)
5043 TAKEDOWN_IN
5046 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5048 struct ScopeOut2 : public Unit
5050 ScopeBufferHnd m_buffer;
5051 float **m_inBuffers;
5052 int m_maxPeriod;
5053 uint32 m_phase;
5057 void ScopeOut2_next(ScopeOut2 *unit, int inNumSamples)
5059 if( !unit->m_buffer ) return;
5061 const int inputOffset = 3;
5062 int numChannels = unit->mNumInputs - inputOffset;
5064 uint32 period = (uint32)ZIN0(2);
5065 uint32 framepos = unit->m_phase;
5067 period = std::max((uint32)inNumSamples, std::min(unit->m_buffer.maxFrames, period));
5069 if( framepos >= period ) framepos = 0;
5071 int remain = period - framepos, wrap = 0;
5073 if(inNumSamples <= remain)
5074 remain = inNumSamples;
5075 else
5076 wrap = inNumSamples - remain;
5078 for (int i = 0; i != numChannels; ++i) {
5079 float * inBuf = unit->m_buffer.channel_data(i);
5080 const float * in = IN(inputOffset + i);
5082 memcpy(inBuf + framepos, in, remain * sizeof(float));
5085 if(framepos + inNumSamples >= period)
5086 (*ft->fPushScopeBuffer)(unit->mWorld, unit->m_buffer, period);
5088 if (wrap) {
5089 for (int i = 0; i != numChannels; ++i) {
5090 float * inBuf = unit->m_buffer.channel_data(i);
5091 const float * in = IN(inputOffset + i);
5092 memcpy(inBuf, in + remain, wrap * sizeof(float));
5096 framepos += inNumSamples;
5097 if (framepos >= period)
5098 framepos = wrap;
5100 unit->m_phase = framepos;
5103 void ScopeOut2_Ctor(ScopeOut2 *unit)
5105 uint32 numChannels = unit->mNumInputs - 3;
5106 uint32 scopeNum = (uint32)ZIN0(0);
5107 uint32 maxFrames = (uint32)ZIN0(1);
5109 bool ok = (*ft->fGetScopeBuffer)(unit->mWorld, scopeNum, numChannels, maxFrames, unit->m_buffer);
5111 if( !ok ) {
5112 if( unit->mWorld->mVerbosity > -1 && !unit->mDone)
5113 Print("ScopeOut2: Requested scope buffer unavailable! (index: %d, channels: %d, size: %d)\n",
5114 scopeNum, numChannels, maxFrames);
5116 else {
5117 unit->m_phase = 0;
5120 SETCALC(ScopeOut2_next);
5123 void ScopeOut2_Dtor(ScopeOut2 *unit)
5125 if( unit->m_buffer )
5126 (*ft->fReleaseScopeBuffer)(unit->mWorld, unit->m_buffer);
5130 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5132 struct PitchShift : public Unit
5134 float *dlybuf;
5135 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5136 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5137 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5138 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5139 float fdelaylen, slope;
5140 long iwrphase, idelaylen, mask;
5141 long counter, stage, numoutput, framesize;
5144 void PitchShift_next(PitchShift *unit, int inNumSamples);
5145 void PitchShift_next(PitchShift *unit, int inNumSamples)
5147 float *out, *in, *dlybuf;
5148 float disppchratio, pchratio, pchratio1, value;
5149 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5150 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5151 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5152 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5153 float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, winsize, pchdisp, timedisp;
5154 long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp;
5155 long counter, stage, framesize;
5157 RGET
5159 out = ZOUT(0);
5160 in = ZIN(0);
5162 pchratio = ZIN0(2);
5163 winsize = ZIN0(1);
5164 pchdisp = ZIN0(3);
5165 timedisp = ZIN0(4);
5166 timedisp = sc_clip(timedisp, 0.f, winsize) * SAMPLERATE;
5168 dlybuf = unit->dlybuf;
5169 fdelaylen = unit->fdelaylen;
5170 idelaylen = unit->idelaylen;
5171 iwrphase = unit->iwrphase;
5173 counter = unit->counter;
5174 stage = unit->stage;
5175 mask = unit->mask;
5176 framesize = unit->framesize;
5178 dsamp1 = unit->dsamp1;
5179 dsamp2 = unit->dsamp2;
5180 dsamp3 = unit->dsamp3;
5181 dsamp4 = unit->dsamp4;
5183 dsamp1_slope = unit->dsamp1_slope;
5184 dsamp2_slope = unit->dsamp2_slope;
5185 dsamp3_slope = unit->dsamp3_slope;
5186 dsamp4_slope = unit->dsamp4_slope;
5188 ramp1 = unit->ramp1;
5189 ramp2 = unit->ramp2;
5190 ramp3 = unit->ramp3;
5191 ramp4 = unit->ramp4;
5193 ramp1_slope = unit->ramp1_slope;
5194 ramp2_slope = unit->ramp2_slope;
5195 ramp3_slope = unit->ramp3_slope;
5196 ramp4_slope = unit->ramp4_slope;
5198 slope = unit->slope;
5200 remain = inNumSamples;
5201 while (remain) {
5202 if (counter <= 0) {
5203 counter = framesize >> 2;
5204 unit->stage = stage = (stage + 1) & 3;
5205 disppchratio = pchratio;
5206 if (pchdisp != 0.f) {
5207 disppchratio += (pchdisp * frand2(s1,s2,s3));
5209 disppchratio = sc_clip(disppchratio, 0.f, 4.f);
5210 pchratio1 = disppchratio - 1.f;
5211 samp_slope = -pchratio1;
5212 startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
5213 startpos += (timedisp * frand(s1,s2,s3));
5214 switch(stage) {
5215 case 0 :
5216 unit->dsamp1_slope = dsamp1_slope = samp_slope;
5217 dsamp1 = startpos;
5218 ramp1 = 0.0;
5219 unit->ramp1_slope = ramp1_slope = slope;
5220 unit->ramp3_slope = ramp3_slope = -slope;
5221 break;
5222 case 1 :
5223 unit->dsamp2_slope = dsamp2_slope = samp_slope;
5224 dsamp2 = startpos;
5225 ramp2 = 0.0;
5226 unit->ramp2_slope = ramp2_slope = slope;
5227 unit->ramp4_slope = ramp4_slope = -slope;
5228 break;
5229 case 2 :
5230 unit->dsamp3_slope = dsamp3_slope = samp_slope;
5231 dsamp3 = startpos;
5232 ramp3 = 0.0;
5233 unit->ramp3_slope = ramp3_slope = slope;
5234 unit->ramp1_slope = ramp1_slope = -slope;
5235 break;
5236 case 3 :
5237 unit->dsamp4_slope = dsamp4_slope = samp_slope;
5238 dsamp4 = startpos;
5239 ramp4 = 0.0;
5240 unit->ramp2_slope = ramp2_slope = -slope;
5241 unit->ramp4_slope = ramp4_slope = slope;
5242 break;
5244 /*Print("%d %d %g %g %g %g %g %g %g %g %g %g %g %g\n",
5245 counter, stage, dsamp1_slope, dsamp2_slope, dsamp3_slope, dsamp4_slope,
5246 dsamp1, dsamp2, dsamp3, dsamp4,
5247 ramp1, ramp2, ramp3, ramp4);*/
5251 nsmps = sc_min(remain, counter);
5252 remain -= nsmps;
5253 counter -= nsmps;
5255 LOOP(nsmps,
5256 iwrphase = (iwrphase + 1) & mask;
5258 dsamp1 += dsamp1_slope;
5259 idsamp = (long)dsamp1;
5260 frac = dsamp1 - idsamp;
5261 irdphase = (iwrphase - idsamp) & mask;
5262 irdphaseb = (irdphase - 1) & mask;
5263 d1 = dlybuf[irdphase];
5264 d2 = dlybuf[irdphaseb];
5265 value = (d1 + frac * (d2 - d1)) * ramp1;
5266 ramp1 += ramp1_slope;
5268 dsamp2 += dsamp2_slope;
5269 idsamp = (long)dsamp2;
5270 frac = dsamp2 - idsamp;
5271 irdphase = (iwrphase - idsamp) & mask;
5272 irdphaseb = (irdphase - 1) & mask;
5273 d1 = dlybuf[irdphase];
5274 d2 = dlybuf[irdphaseb];
5275 value += (d1 + frac * (d2 - d1)) * ramp2;
5276 ramp2 += ramp2_slope;
5278 dsamp3 += dsamp3_slope;
5279 idsamp = (long)dsamp3;
5280 frac = dsamp3 - idsamp;
5281 irdphase = (iwrphase - idsamp) & mask;
5282 irdphaseb = (irdphase - 1) & mask;
5283 d1 = dlybuf[irdphase];
5284 d2 = dlybuf[irdphaseb];
5285 value += (d1 + frac * (d2 - d1)) * ramp3;
5286 ramp3 += ramp3_slope;
5288 dsamp4 += dsamp4_slope;
5289 idsamp = (long)dsamp4;
5290 frac = dsamp4 - idsamp;
5291 irdphase = (iwrphase - idsamp) & mask;
5292 irdphaseb = (irdphase - 1) & mask;
5293 d1 = dlybuf[irdphase];
5294 d2 = dlybuf[irdphaseb];
5295 value += (d1 + frac * (d2 - d1)) * ramp4;
5296 ramp4 += ramp4_slope;
5298 dlybuf[iwrphase] = ZXP(in);
5299 ZXP(out) = value *= 0.5;
5303 unit->counter = counter;
5305 unit->dsamp1 = dsamp1;
5306 unit->dsamp2 = dsamp2;
5307 unit->dsamp3 = dsamp3;
5308 unit->dsamp4 = dsamp4;
5310 unit->ramp1 = ramp1;
5311 unit->ramp2 = ramp2;
5312 unit->ramp3 = ramp3;
5313 unit->ramp4 = ramp4;
5315 unit->iwrphase = iwrphase;
5317 RPUT
5323 void PitchShift_next_z(PitchShift *unit, int inNumSamples);
5324 void PitchShift_next_z(PitchShift *unit, int inNumSamples)
5326 float *out, *in, *dlybuf;
5327 float disppchratio, pchratio, pchratio1, value;
5328 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5329 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5330 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5331 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5332 float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, winsize, pchdisp, timedisp;
5333 long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase;
5334 long mask, idsamp;
5335 long counter, stage, framesize, numoutput;
5337 RGET
5339 out = ZOUT(0);
5340 in = ZIN(0);
5341 pchratio = ZIN0(2);
5342 winsize = ZIN0(1);
5343 pchdisp = ZIN0(3);
5344 timedisp = ZIN0(4);
5345 timedisp = sc_clip(timedisp, 0.f, winsize) * SAMPLERATE;
5347 dlybuf = unit->dlybuf;
5348 fdelaylen = unit->fdelaylen;
5349 idelaylen = unit->idelaylen;
5350 iwrphase = unit->iwrphase;
5351 numoutput = unit->numoutput;
5353 counter = unit->counter;
5354 stage = unit->stage;
5355 mask = unit->mask;
5356 framesize = unit->framesize;
5358 dsamp1 = unit->dsamp1;
5359 dsamp2 = unit->dsamp2;
5360 dsamp3 = unit->dsamp3;
5361 dsamp4 = unit->dsamp4;
5363 dsamp1_slope = unit->dsamp1_slope;
5364 dsamp2_slope = unit->dsamp2_slope;
5365 dsamp3_slope = unit->dsamp3_slope;
5366 dsamp4_slope = unit->dsamp4_slope;
5368 ramp1 = unit->ramp1;
5369 ramp2 = unit->ramp2;
5370 ramp3 = unit->ramp3;
5371 ramp4 = unit->ramp4;
5373 ramp1_slope = unit->ramp1_slope;
5374 ramp2_slope = unit->ramp2_slope;
5375 ramp3_slope = unit->ramp3_slope;
5376 ramp4_slope = unit->ramp4_slope;
5378 slope = unit->slope;
5380 remain = inNumSamples;
5381 while (remain) {
5382 if (counter <= 0) {
5383 counter = framesize >> 2;
5384 unit->stage = stage = (stage + 1) & 3;
5385 disppchratio = pchratio;
5386 if (pchdisp != 0.f) {
5387 disppchratio += (pchdisp * frand2(s1,s2,s3));
5389 disppchratio = sc_clip(disppchratio, 0.f, 4.f);
5390 pchratio1 = disppchratio - 1.f;
5391 samp_slope = -pchratio1;
5392 startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
5393 startpos += (timedisp * frand(s1,s2,s3));
5394 switch(stage) {
5395 case 0 :
5396 unit->dsamp1_slope = dsamp1_slope = samp_slope;
5397 dsamp1 = startpos;
5398 ramp1 = 0.0;
5399 unit->ramp1_slope = ramp1_slope = slope;
5400 unit->ramp3_slope = ramp3_slope = -slope;
5401 break;
5402 case 1 :
5403 unit->dsamp2_slope = dsamp2_slope = samp_slope;
5404 dsamp2 = startpos;
5405 ramp2 = 0.0;
5406 unit->ramp2_slope = ramp2_slope = slope;
5407 unit->ramp4_slope = ramp4_slope = -slope;
5408 break;
5409 case 2 :
5410 unit->dsamp3_slope = dsamp3_slope = samp_slope;
5411 dsamp3 = startpos;
5412 ramp3 = 0.0;
5413 unit->ramp3_slope = ramp3_slope = slope;
5414 unit->ramp1_slope = ramp1_slope = -slope;
5415 break;
5416 case 3 :
5417 unit->dsamp4_slope = dsamp4_slope = samp_slope;
5418 dsamp4 = startpos;
5419 ramp4 = 0.0;
5420 unit->ramp2_slope = ramp2_slope = -slope;
5421 unit->ramp4_slope = ramp4_slope = slope;
5422 break;
5424 /*Print("z %d %d %g %g %g %g %g %g %g %g %g %g %g %g\n",
5425 counter, stage, dsamp1_slope, dsamp2_slope, dsamp3_slope, dsamp4_slope,
5426 dsamp1, dsamp2, dsamp3, dsamp4,
5427 ramp1, ramp2, ramp3, ramp4);*/
5429 nsmps = sc_min(remain, counter);
5430 remain -= nsmps;
5431 counter -= nsmps;
5433 while (nsmps--) {
5434 numoutput++;
5435 iwrphase = (iwrphase + 1) & mask;
5437 dsamp1 += dsamp1_slope;
5438 idsamp = (long)dsamp1;
5439 frac = dsamp1 - idsamp;
5440 irdphase = (iwrphase - idsamp) & mask;
5441 irdphaseb = (irdphase - 1) & mask;
5442 if (numoutput < idelaylen) {
5443 if (irdphase > iwrphase) {
5444 value = 0.f;
5445 } else if (irdphaseb > iwrphase) {
5446 d1 = dlybuf[irdphase];
5447 value = (d1 - frac * d1) * ramp1;
5448 } else {
5449 d1 = dlybuf[irdphase];
5450 d2 = dlybuf[irdphaseb];
5451 value = (d1 + frac * (d2 - d1)) * ramp1;
5453 } else {
5454 d1 = dlybuf[irdphase];
5455 d2 = dlybuf[irdphaseb];
5456 value = (d1 + frac * (d2 - d1)) * ramp1;
5458 ramp1 += ramp1_slope;
5460 dsamp2 += dsamp2_slope;
5461 idsamp = (long)dsamp2;
5462 frac = dsamp2 - idsamp;
5463 irdphase = (iwrphase - idsamp) & mask;
5464 irdphaseb = (irdphase - 1) & mask;
5465 if (numoutput < idelaylen) {
5466 if (irdphase > iwrphase) {
5467 //value += 0.f;
5468 } else if (irdphaseb > iwrphase) {
5469 d1 = dlybuf[irdphase];
5470 value += (d1 - frac * d1) * ramp2;
5471 } else {
5472 d1 = dlybuf[irdphase];
5473 d2 = dlybuf[irdphaseb];
5474 value += (d1 + frac * (d2 - d1)) * ramp2;
5476 } else {
5477 d1 = dlybuf[irdphase];
5478 d2 = dlybuf[irdphaseb];
5479 value += (d1 + frac * (d2 - d1)) * ramp2;
5481 ramp2 += ramp2_slope;
5483 dsamp3 += dsamp3_slope;
5484 idsamp = (long)dsamp3;
5485 frac = dsamp3 - idsamp;
5486 irdphase = (iwrphase - idsamp) & mask;
5487 irdphaseb = (irdphase - 1) & mask;
5488 if (numoutput < idelaylen) {
5489 if (irdphase > iwrphase) {
5490 //value += 0.f;
5491 } else if (irdphaseb > iwrphase) {
5492 d1 = dlybuf[irdphase];
5493 value += (d1 - frac * d1) * ramp3;
5494 } else {
5495 d1 = dlybuf[irdphase];
5496 d2 = dlybuf[irdphaseb];
5497 value += (d1 + frac * (d2 - d1)) * ramp3;
5499 } else {
5500 d1 = dlybuf[irdphase];
5501 d2 = dlybuf[irdphaseb];
5502 value += (d1 + frac * (d2 - d1)) * ramp3;
5504 ramp3 += ramp3_slope;
5506 dsamp4 += dsamp4_slope;
5507 idsamp = (long)dsamp4;
5508 frac = dsamp4 - idsamp;
5509 irdphase = (iwrphase - idsamp) & mask;
5510 irdphaseb = (irdphase - 1) & mask;
5512 if (numoutput < idelaylen) {
5513 if (irdphase > iwrphase) {
5514 //value += 0.f;
5515 } else if (irdphaseb > iwrphase) {
5516 d1 = dlybuf[irdphase];
5517 value += (d1 - frac * d1) * ramp4;
5518 } else {
5519 d1 = dlybuf[irdphase];
5520 d2 = dlybuf[irdphaseb];
5521 value += (d1 + frac * (d2 - d1)) * ramp4;
5523 } else {
5524 d1 = dlybuf[irdphase];
5525 d2 = dlybuf[irdphaseb];
5526 value += (d1 + frac * (d2 - d1)) * ramp4;
5528 ramp4 += ramp4_slope;
5530 dlybuf[iwrphase] = ZXP(in);
5531 ZXP(out) = value *= 0.5;
5535 unit->counter = counter;
5536 unit->stage = stage;
5537 unit->mask = mask;
5539 unit->dsamp1 = dsamp1;
5540 unit->dsamp2 = dsamp2;
5541 unit->dsamp3 = dsamp3;
5542 unit->dsamp4 = dsamp4;
5544 unit->ramp1 = ramp1;
5545 unit->ramp2 = ramp2;
5546 unit->ramp3 = ramp3;
5547 unit->ramp4 = ramp4;
5549 unit->numoutput = numoutput;
5550 unit->iwrphase = iwrphase;
5552 if (numoutput >= idelaylen) {
5553 SETCALC(PitchShift_next);
5556 RPUT
5560 void PitchShift_Ctor(PitchShift *unit);
5561 void PitchShift_Ctor(PitchShift *unit)
5563 long delaybufsize;
5564 float *out, *in, *dlybuf;
5565 float winsize, pchratio;
5566 float fdelaylen, slope;
5567 long framesize, last;
5569 out = ZOUT(0);
5570 in = ZIN(0);
5571 pchratio = ZIN0(2);
5572 winsize = ZIN0(1);
5574 delaybufsize = (long)ceil(winsize * SAMPLERATE * 3.f + 3.f);
5575 fdelaylen = delaybufsize - 3;
5577 delaybufsize = delaybufsize + BUFLENGTH;
5578 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
5579 dlybuf = (float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
5581 SETCALC(PitchShift_next_z);
5583 *dlybuf = ZIN0(0);
5584 ZOUT0(0) = 0.f;
5586 unit->dlybuf = dlybuf;
5587 unit->idelaylen = delaybufsize;
5588 unit->fdelaylen = fdelaylen;
5589 unit->iwrphase = 0;
5590 unit->numoutput = 0;
5591 unit->mask = last = (delaybufsize - 1);
5593 unit->framesize = framesize = ((long)(winsize * SAMPLERATE) + 2) & ~3;
5594 unit->slope = slope = 2.f / framesize;
5595 unit->stage = 3;
5596 unit->counter = framesize >> 2;
5597 unit->ramp1 = 0.5;
5598 unit->ramp2 = 1.0;
5599 unit->ramp3 = 0.5;
5600 unit->ramp4 = 0.0;
5602 unit->ramp1_slope = -slope;
5603 unit->ramp2_slope = -slope;
5604 unit->ramp3_slope = slope;
5605 unit->ramp4_slope = slope;
5607 dlybuf[last ] = 0.f; // put a few zeroes where we start the read heads
5608 dlybuf[last-1] = 0.f;
5609 dlybuf[last-2] = 0.f;
5611 unit->numoutput = 0;
5613 // start all read heads 2 samples behind the write head
5614 unit->dsamp1 = unit->dsamp2 = unit->dsamp3 = unit->dsamp4 = 2.f;
5615 // pch ratio is initially zero for the read heads
5616 unit->dsamp1_slope = unit->dsamp2_slope = unit->dsamp3_slope = unit->dsamp4_slope = 1.f;
5621 void PitchShift_Dtor(PitchShift *unit)
5623 RTFree(unit->mWorld, unit->dlybuf);
5629 typedef struct graintap1 {
5630 float pos, rate, level, slope, curve;
5631 long counter;
5632 struct graintap1 *next;
5633 } GrainTap1;
5635 #define MAXDGRAINS 32
5637 struct GrainTap : public Unit
5639 float m_fbufnum;
5640 SndBuf *m_buf;
5642 float fdelaylen;
5643 long bufsize, iwrphase;
5644 long nextTime;
5645 GrainTap1 grains[MAXDGRAINS];
5646 GrainTap1 *firstActive, *firstFree;
5650 // coefs: pos, rate, level, slope, curve, counter
5652 void GrainTap_next(GrainTap *unit, int inNumSamples);
5653 void GrainTap_next(GrainTap *unit, int inNumSamples)
5655 float *out, *out0;
5656 const float * dlybuf;
5657 float sdur, rdur, rdur2;
5658 float dsamp, dsamp_slope, fdelaylen, d1, d2, frac;
5659 float level, slope, curve;
5660 float maxpitch, pitch, maxtimedisp, timedisp, density;
5661 long remain, nsmps, irdphase, irdphaseb, iwrphase, iwrphase0;
5662 long idsamp, koffset;
5663 long counter;
5664 uint32 bufsize;
5665 GrainTap1 *grain, *prevGrain, *nextGrain;
5667 GET_BUF_SHARED
5669 RGET
5671 out0 = ZOUT(0);
5673 // bufnum, grainDur, pchRatio, pchDisp, timeDisp, overlap
5674 // 0 1 2 3 4 5
5676 density = ZIN0(5);
5677 density = sc_max(0.0001, density);
5679 bufsize = unit->bufsize;
5680 if (bufsize != bufSamples) {
5681 ClearUnitOutputs(unit, inNumSamples);
5682 return;
5685 dlybuf = bufData;
5686 fdelaylen = unit->fdelaylen;
5687 iwrphase0 = unit->iwrphase;
5689 // initialize buffer to zero
5690 out = out0;
5691 LOOP1(inNumSamples, ZXP(out) = 0.f;);
5693 // do all current grains
5694 prevGrain = NULL;
5695 grain = unit->firstActive;
5696 while (grain) {
5698 dsamp = grain->pos;
5699 dsamp_slope = grain->rate;
5700 level = grain->level;
5701 slope = grain->slope;
5702 curve = grain->curve;
5703 counter = grain->counter;
5705 nsmps = sc_min(counter, inNumSamples);
5706 iwrphase = iwrphase0;
5707 out = out0;
5708 LOOP(nsmps,
5709 dsamp += dsamp_slope;
5710 idsamp = (long)dsamp;
5711 frac = dsamp - idsamp;
5712 iwrphase = (iwrphase + 1) & mask;
5713 irdphase = (iwrphase - idsamp) & mask;
5714 irdphaseb = (irdphase - 1) & mask;
5715 d1 = dlybuf[irdphase];
5716 d2 = dlybuf[irdphaseb];
5717 ZXP(out) += (d1 + frac * (d2 - d1)) * level;
5718 level += slope;
5719 slope += curve;
5721 grain->pos = dsamp;
5722 grain->level = level;
5723 grain->slope = slope;
5724 grain->counter -= nsmps;
5726 nextGrain = grain->next;
5727 if (grain->counter <= 0) {
5728 // unlink from active list
5729 if (prevGrain) prevGrain->next = nextGrain;
5730 else unit->firstActive = nextGrain;
5732 // link onto free list
5733 grain->next = unit->firstFree;
5734 unit->firstFree = grain;
5735 } else {
5736 prevGrain = grain;
5738 grain = nextGrain;
5740 // start new grains
5741 remain = inNumSamples;
5742 while (unit->nextTime <= remain) {
5743 remain -= unit->nextTime;
5744 sdur = ZIN0(1) * SAMPLERATE;
5745 sdur = sc_max(sdur, 4.f);
5747 grain = unit->firstFree;
5748 if (grain) {
5749 unit->firstFree = grain->next;
5750 grain->next = unit->firstActive;
5751 unit->firstActive = grain;
5753 koffset = inNumSamples - remain;
5754 iwrphase = (iwrphase0 + koffset) & mask;
5756 grain->counter = (long)sdur;
5758 timedisp = ZIN0(4);
5759 timedisp = sc_max(timedisp, 0.f);
5760 timedisp = frand(s1,s2,s3) * timedisp * SAMPLERATE;
5762 pitch = ZIN0(2) + frand2(s1,s2,s3) * ZIN0(3);
5763 if (pitch >= 1.f) {
5764 maxpitch = 1.f + (fdelaylen/sdur);
5765 pitch = sc_min(pitch, maxpitch);
5767 dsamp_slope = 1.f - pitch;
5768 grain->rate = dsamp_slope;
5770 maxtimedisp = fdelaylen + sdur * dsamp_slope;
5771 timedisp = sc_min(timedisp, maxtimedisp);
5773 dsamp = BUFLENGTH + koffset + 2.f + timedisp - sdur * dsamp_slope;
5774 dsamp = sc_min(dsamp, fdelaylen);
5775 } else {
5776 maxpitch = -(1.f + (fdelaylen/sdur));
5777 pitch = sc_max(pitch, maxpitch);
5779 dsamp_slope = 1.f - pitch;
5780 grain->rate = dsamp_slope;
5782 maxtimedisp = fdelaylen - sdur * dsamp_slope;
5783 timedisp = sc_min(timedisp, maxtimedisp);
5785 dsamp = BUFLENGTH + koffset + 2.f + timedisp;
5786 dsamp = sc_min(dsamp, fdelaylen);
5789 grain->pos = dsamp;
5790 //postbuf("ds %g %g %g\n", dsamp_slope, dsamp, fdelaylen);
5792 rdur = 1.f / sdur;
5793 rdur2 = rdur * rdur;
5794 grain->level = level = 0.f;
5795 grain->slope = slope = 4.0 * (rdur - rdur2); // ampslope
5796 grain->curve = curve = -8.0 * rdur2; // ampcurve
5798 nsmps = remain;
5799 out = out0 + koffset;
5800 LOOP(nsmps,
5801 dsamp += dsamp_slope;
5802 idsamp = (long)dsamp;
5803 frac = dsamp - idsamp;
5804 iwrphase = (iwrphase + 1) & mask;
5805 irdphase = (iwrphase - idsamp) & mask;
5806 irdphaseb = (irdphase - 1) & mask;
5807 d1 = dlybuf[irdphase];
5808 d2 = dlybuf[irdphaseb];
5809 ZXP(out) += (d1 + frac * (d2 - d1)) * level;
5810 level += slope;
5811 slope += curve;
5813 grain->pos = dsamp;
5814 grain->level = level;
5815 grain->slope = slope;
5816 grain->counter -= nsmps;
5818 if (grain->counter <= 0) {
5819 // unlink from active list
5820 unit->firstActive = grain->next;
5822 // link onto free list
5823 grain->next = unit->firstFree;
5824 unit->firstFree = grain;
5827 unit->nextTime = (long)(sdur / density);
5828 if (unit->nextTime < 1) unit->nextTime = 1;
5830 /*if (grain == NULL) {
5831 postbuf("nextTime %d %g %g %p %p %p\n", unit->nextTime, sdur, density,
5832 grain, unit->firstActive, unit->firstFree);
5835 iwrphase = (iwrphase0 + BUFLENGTH) & mask;
5836 unit->nextTime -= remain;
5837 if (unit->nextTime < 0) unit->nextTime = 0;
5839 unit->iwrphase = iwrphase;
5841 RPUT
5845 void GrainTap_Ctor(GrainTap *unit);
5846 void GrainTap_Ctor(GrainTap *unit)
5848 float fdelaylen;
5849 float maxdelaytime;
5851 GET_BUF
5853 if (!ISPOWEROFTWO(bufSamples)) {
5854 Print("GrainTap buffer size not a power of two.\n");
5855 SETCALC(*ClearUnitOutputs);
5856 return;
5859 fdelaylen = bufSamples - 2 * BUFLENGTH - 3;
5860 maxdelaytime = fdelaylen * SAMPLEDUR;
5862 SETCALC(GrainTap_next);
5864 ZOUT0(0) = 0.f;
5866 unit->bufsize = bufSamples;
5867 unit->fdelaylen = fdelaylen;
5868 unit->iwrphase = 0;
5869 unit->nextTime = 0;
5870 for (int i=0; i<MAXDGRAINS-1; ++i) {
5871 unit->grains[i].next = unit->grains + (i + 1);
5873 unit->grains[MAXDGRAINS-1].next = NULL;
5874 unit->firstFree = unit->grains;
5875 unit->firstActive = NULL;
5881 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5884 #define GRAIN_BUF \
5885 const SndBuf *buf = bufs + bufnum; \
5886 LOCK_SNDBUF_SHARED(buf); \
5887 const float *bufData __attribute__((__unused__)) = buf->data; \
5888 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
5889 uint32 bufSamples __attribute__((__unused__)) = buf->samples; \
5890 uint32 bufFrames = buf->frames; \
5891 int guardFrame __attribute__((__unused__)) = bufFrames - 2; \
5894 inline float IN_AT(Unit* unit, int index, int offset)
5896 if (INRATE(index) == calc_FullRate) return IN(index)[offset];
5897 if (INRATE(index) == calc_DemandRate) return DEMANDINPUT_A(index, offset + 1);
5898 return ZIN0(index);
5901 inline double sc_gloop(double in, double hi)
5903 // avoid the divide if possible
5904 if (in >= hi) {
5905 in -= hi;
5906 if (in < hi) return in;
5907 } else if (in < 0.) {
5908 in += hi;
5909 if (in >= 0.) return in;
5910 } else return in;
5912 return in - hi * floor(in/hi);
5915 #define GRAIN_LOOP_BODY_4 \
5916 float amp = y1 * y1; \
5917 phase = sc_gloop(phase, loopMax); \
5918 int32 iphase = (int32)phase; \
5919 const float* table1 = bufData + iphase; \
5920 const float* table0 = table1 - 1; \
5921 const float* table2 = table1 + 1; \
5922 const float* table3 = table1 + 2; \
5923 if (iphase == 0) { \
5924 table0 += bufSamples; \
5925 } else if (iphase >= guardFrame) { \
5926 if (iphase == guardFrame) { \
5927 table3 -= bufSamples; \
5928 } else { \
5929 table2 -= bufSamples; \
5930 table3 -= bufSamples; \
5933 float fracphase = phase - (double)iphase; \
5934 float a = table0[0]; \
5935 float b = table1[0]; \
5936 float c = table2[0]; \
5937 float d = table3[0]; \
5938 float outval = amp * cubicinterp(fracphase, a, b, c, d); \
5939 ZXP(out1) += outval * pan1; \
5940 ZXP(out2) += outval * pan2; \
5941 double y0 = b1 * y1 - y2; \
5942 y2 = y1; \
5943 y1 = y0; \
5946 #define GRAIN_LOOP_BODY_2 \
5947 float amp = y1 * y1; \
5948 phase = sc_gloop(phase, loopMax); \
5949 int32 iphase = (int32)phase; \
5950 const float* table1 = bufData + iphase; \
5951 const float* table2 = table1 + 1; \
5952 if (iphase > guardFrame) { \
5953 table2 -= bufSamples; \
5955 float fracphase = phase - (double)iphase; \
5956 float b = table1[0]; \
5957 float c = table2[0]; \
5958 float outval = amp * (b + fracphase * (c - b)); \
5959 ZXP(out1) += outval * pan1; \
5960 ZXP(out2) += outval * pan2; \
5961 double y0 = b1 * y1 - y2; \
5962 y2 = y1; \
5963 y1 = y0; \
5966 #define GRAIN_LOOP_BODY_1 \
5967 float amp = y1 * y1; \
5968 phase = sc_gloop(phase, loopMax); \
5969 int32 iphase = (int32)phase; \
5970 float outval = amp * bufData[iphase]; \
5971 ZXP(out1) += outval * pan1; \
5972 ZXP(out2) += outval * pan2; \
5973 double y0 = b1 * y1 - y2; \
5974 y2 = y1; \
5975 y1 = y0; \
5978 void TGrains_next(TGrains *unit, int inNumSamples)
5980 float *trigin = IN(0);
5981 float prevtrig = unit->mPrevTrig;
5983 uint32 numOutputs = unit->mNumOutputs;
5984 ClearUnitOutputs(unit, inNumSamples);
5985 float *out[16];
5986 for (uint32 i=0; i<numOutputs; ++i) out[i] = ZOUT(i);
5988 World *world = unit->mWorld;
5989 SndBuf *bufs = world->mSndBufs;
5990 uint32 numBufs = world->mNumSndBufs;
5992 for (int i=0; i < unit->mNumActive; ) {
5993 Grain *grain = unit->mGrains + i;
5994 uint32 bufnum = grain->bufnum;
5996 GRAIN_BUF
5998 if (bufChannels != 1) {
5999 ++i;
6000 continue;
6003 double loopMax = (double)bufFrames;
6005 float pan1 = grain->pan1;
6006 float pan2 = grain->pan2;
6007 double rate = grain->rate;
6008 double phase = grain->phase;
6009 double b1 = grain->b1;
6010 double y1 = grain->y1;
6011 double y2 = grain->y2;
6013 uint32 chan1 = grain->chan;
6014 uint32 chan2 = chan1 + 1;
6015 if (chan2 >= numOutputs) chan2 = 0;
6017 float *out1 = out[chan1];
6018 float *out2 = out[chan2];
6019 //printf("B chan %d %d %p %p", chan1, chan2, out1, out2);
6021 int nsmps = sc_min(grain->counter, inNumSamples);
6022 if (grain->interp >= 4) {
6023 for (int j=0; j<nsmps; ++j) {
6024 GRAIN_LOOP_BODY_4;
6025 phase += rate;
6027 } else if (grain->interp >= 2) {
6028 for (int j=0; j<nsmps; ++j) {
6029 GRAIN_LOOP_BODY_2;
6030 phase += rate;
6032 } else {
6033 for (int j=0; j<nsmps; ++j) {
6034 GRAIN_LOOP_BODY_1;
6035 phase += rate;
6039 grain->phase = phase;
6040 grain->y1 = y1;
6041 grain->y2 = y2;
6043 grain->counter -= nsmps;
6044 if (grain->counter <= 0) {
6045 // remove grain
6046 *grain = unit->mGrains[--unit->mNumActive];
6047 } else ++i;
6050 int trigSamples = INRATE(0) == calc_FullRate ? inNumSamples : 1;
6052 for (int i=0; i<trigSamples; ++i) {
6053 float trig = trigin[i];
6055 if (trig > 0.f && prevtrig <= 0.f) {
6056 // start a grain
6057 if (unit->mNumActive+1 >= kMaxGrains) break;
6058 uint32 bufnum = (uint32)IN_AT(unit, 1, i);
6059 if (bufnum >= numBufs) continue;
6060 GRAIN_BUF
6062 if (bufChannels != 1) continue;
6064 float bufSampleRate = buf->samplerate;
6065 float bufRateScale = bufSampleRate * SAMPLEDUR;
6066 double loopMax = (double)bufFrames;
6068 Grain *grain = unit->mGrains + unit->mNumActive++;
6069 grain->bufnum = bufnum;
6071 double counter = floor(IN_AT(unit, 4, i) * SAMPLERATE);
6072 counter = sc_max(4., counter);
6073 grain->counter = (int)counter;
6075 double rate = grain->rate = IN_AT(unit, 2, i) * bufRateScale;
6076 double centerPhase = IN_AT(unit, 3, i) * bufSampleRate;
6077 double phase = centerPhase - 0.5 * counter * rate;
6079 float pan = IN_AT(unit, 5, i);
6080 float amp = IN_AT(unit, 6, i);
6081 grain->interp = (int)IN_AT(unit, 7, i);
6083 float panangle;
6084 if (numOutputs > 2) {
6085 pan = sc_wrap(pan * 0.5f, 0.f, 1.f);
6086 float cpan = numOutputs * pan + 0.5;
6087 float ipan = floor(cpan);
6088 float panfrac = cpan - ipan;
6089 panangle = panfrac * pi2_f;
6090 grain->chan = (int)ipan;
6091 if (grain->chan >= (int)numOutputs) grain->chan -= numOutputs;
6092 } else {
6093 grain->chan = 0;
6094 pan = sc_wrap(pan * 0.5f + 0.5f, 0.f, 1.f);
6095 panangle = pan * pi2_f;
6097 float pan1 = grain->pan1 = amp * cos(panangle);
6098 float pan2 = grain->pan2 = amp * sin(panangle);
6099 double w = pi / counter;
6100 double b1 = grain->b1 = 2. * cos(w);
6101 double y1 = sin(w);
6102 double y2 = 0.;
6104 uint32 chan1 = grain->chan;
6105 uint32 chan2 = chan1 + 1;
6106 if (chan2 >= numOutputs) chan2 = 0;
6108 float *out1 = out[chan1] + i;
6109 float *out2 = out[chan2] + i;
6111 int nsmps = sc_min(grain->counter, inNumSamples - i);
6112 if (grain->interp >= 4) {
6113 for (int j=0; j<nsmps; ++j) {
6114 GRAIN_LOOP_BODY_4;
6115 phase += rate;
6117 } else if (grain->interp >= 2) {
6118 for (int j=0; j<nsmps; ++j) {
6119 GRAIN_LOOP_BODY_2;
6120 phase += rate;
6122 } else {
6123 for (int j=0; j<nsmps; ++j) {
6124 GRAIN_LOOP_BODY_1;
6125 phase += rate;
6129 grain->phase = phase;
6130 grain->y1 = y1;
6131 grain->y2 = y2;
6133 grain->counter -= nsmps;
6134 if (grain->counter <= 0) {
6135 // remove grain
6136 *grain = unit->mGrains[--unit->mNumActive];
6139 prevtrig = trig;
6142 unit->mPrevTrig = prevtrig;
6145 void TGrains_Ctor(TGrains *unit)
6147 SETCALC(TGrains_next);
6149 unit->mNumActive = 0;
6150 unit->mPrevTrig = 0.;
6152 ClearUnitOutputs(unit, 1);
6156 ////////////////////////////////////////////////////////////////////////////////////////////////////////
6158 Pluck - Karplus-Strong
6160 void Pluck_Ctor(Pluck *unit)
6162 // FeedbackDelay_Reset(unit);
6163 float maxdelaytime = unit->m_maxdelaytime = IN0(2);
6164 float delaytime = unit->m_delaytime = IN0(3);
6165 unit->m_dlybuf = 0;
6166 bool allocationSucessful = DelayUnit_AllocDelayLine(unit, "Pluck");
6167 if (!allocationSucessful)
6168 return;
6170 unit->m_dsamp = CalcDelay(unit, unit->m_delaytime);
6172 unit->m_numoutput = 0;
6173 unit->m_iwrphase = 0;
6174 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
6176 if (INRATE(1) == calc_FullRate) {
6177 if(INRATE(5) == calc_FullRate){
6178 SETCALC(Pluck_next_aa_z);
6179 } else {
6180 SETCALC(Pluck_next_ak_z); //ak
6182 } else {
6183 if(INRATE(5) == calc_FullRate){
6184 SETCALC(Pluck_next_ka_z); //ka
6185 } else {
6186 SETCALC(Pluck_next_kk_z); //kk
6189 OUT0(0) = unit->m_lastsamp = 0.f;
6190 unit->m_prevtrig = 0.f;
6191 unit->m_inputsamps = 0;
6192 unit->m_coef = IN0(5);
6195 void Pluck_next_aa(Pluck *unit, int inNumSamples)
6197 float *out = OUT(0);
6198 float *in = IN(0);
6199 float *trig = IN(1);
6200 float delaytime = IN0(3);
6201 float decaytime = IN0(4);
6202 float *coef = IN(5);
6203 float lastsamp = unit->m_lastsamp;
6204 unsigned long inputsamps = unit->m_inputsamps;
6206 float *dlybuf = unit->m_dlybuf;
6207 long iwrphase = unit->m_iwrphase;
6208 float dsamp = unit->m_dsamp;
6209 float feedbk = unit->m_feedbk;
6210 long mask = unit->m_mask;
6211 float thisin, curtrig;
6212 float prevtrig = unit->m_prevtrig;
6214 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6215 long idsamp = (long)dsamp;
6216 float frac = dsamp - idsamp;
6217 for(int i = 0; i < inNumSamples; i++){
6218 curtrig = trig[i];
6219 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6220 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6222 prevtrig = curtrig;
6223 long irdphase1 = iwrphase - idsamp;
6224 long irdphase2 = irdphase1 - 1;
6225 long irdphase3 = irdphase1 - 2;
6226 long irdphase0 = irdphase1 + 1;
6227 if (inputsamps > 0) {
6228 thisin = in[i];
6229 --inputsamps;
6230 } else {
6231 thisin = 0.f;
6233 float d0 = dlybuf[irdphase0 & mask];
6234 float d1 = dlybuf[irdphase1 & mask];
6235 float d2 = dlybuf[irdphase2 & mask];
6236 float d3 = dlybuf[irdphase3 & mask];
6237 float value = cubicinterp(frac, d0, d1, d2, d3);
6238 float thiscoef = coef[i];
6239 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6240 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6241 out[i] = lastsamp = onepole;
6242 iwrphase++;
6244 } else {
6246 float next_dsamp = CalcDelay(unit, delaytime);
6247 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6249 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6250 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6252 for(int i = 0; i < inNumSamples; i++){
6253 curtrig = trig[i];
6254 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6255 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6257 prevtrig = curtrig;
6258 dsamp += dsamp_slope;
6259 long idsamp = (long)dsamp;
6260 float frac = dsamp - idsamp;
6261 long irdphase1 = iwrphase - idsamp;
6262 long irdphase2 = irdphase1 - 1;
6263 long irdphase3 = irdphase1 - 2;
6264 long irdphase0 = irdphase1 + 1;
6265 if (inputsamps > 0) {
6266 thisin = in[i];
6267 --inputsamps;
6268 } else {
6269 thisin = 0.f;
6271 float d0 = dlybuf[irdphase0 & mask];
6272 float d1 = dlybuf[irdphase1 & mask];
6273 float d2 = dlybuf[irdphase2 & mask];
6274 float d3 = dlybuf[irdphase3 & mask];
6275 float value = cubicinterp(frac, d0, d1, d2, d3);
6276 float thiscoef = coef[i];
6277 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6278 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6279 out[i] = lastsamp = onepole;
6280 feedbk += feedbk_slope;
6281 iwrphase++;
6283 unit->m_feedbk = feedbk;
6284 unit->m_dsamp = dsamp;
6285 unit->m_delaytime = delaytime;
6286 unit->m_decaytime = decaytime;
6289 unit->m_prevtrig = prevtrig;
6290 unit->m_inputsamps = inputsamps;
6291 unit->m_lastsamp = zapgremlins(lastsamp);
6292 unit->m_iwrphase = iwrphase;
6297 void Pluck_next_aa_z(Pluck *unit, int inNumSamples)
6299 float *out = OUT(0);
6300 float *in = IN(0);
6301 float *trig = IN(1);
6302 float delaytime = IN0(3);
6303 float decaytime = IN0(4);
6304 float *coef = IN(5);
6305 float lastsamp = unit->m_lastsamp;
6307 float *dlybuf = unit->m_dlybuf;
6308 long iwrphase = unit->m_iwrphase;
6309 float dsamp = unit->m_dsamp;
6310 float feedbk = unit->m_feedbk;
6311 long mask = unit->m_mask;
6312 float d0, d1, d2, d3;
6313 float thisin, curtrig;
6314 unsigned long inputsamps = unit->m_inputsamps;
6315 float prevtrig = unit->m_prevtrig;
6317 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6318 long idsamp = (long)dsamp;
6319 float frac = dsamp - idsamp;
6320 for(int i = 0; i < inNumSamples; i++){
6321 curtrig = trig[i];
6322 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6323 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6325 prevtrig = curtrig;
6326 long irdphase1 = iwrphase - idsamp;
6327 long irdphase2 = irdphase1 - 1;
6328 long irdphase3 = irdphase1 - 2;
6329 long irdphase0 = irdphase1 + 1;
6330 if (inputsamps > 0) {
6331 thisin = in[i];
6332 --inputsamps;
6333 } else {
6334 thisin = 0.f;
6336 if (irdphase0 < 0) {
6337 dlybuf[iwrphase & mask] = thisin;
6338 out[i] = 0.f;
6339 } else {
6340 if (irdphase1 < 0) {
6341 d1 = d2 = d3 = 0.f;
6342 d0 = dlybuf[irdphase0 & mask];
6343 } else if (irdphase2 < 0) {
6344 d1 = d2 = d3 = 0.f;
6345 d0 = dlybuf[irdphase0 & mask];
6346 d1 = dlybuf[irdphase1 & mask];
6347 } else if (irdphase3 < 0) {
6348 d3 = 0.f;
6349 d0 = dlybuf[irdphase0 & mask];
6350 d1 = dlybuf[irdphase1 & mask];
6351 d2 = dlybuf[irdphase2 & mask];
6352 } else {
6353 d0 = dlybuf[irdphase0 & mask];
6354 d1 = dlybuf[irdphase1 & mask];
6355 d2 = dlybuf[irdphase2 & mask];
6356 d3 = dlybuf[irdphase3 & mask];
6358 float value = cubicinterp(frac, d0, d1, d2, d3);
6359 float thiscoef = coef[i];
6360 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6361 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6362 out[i] = lastsamp = onepole;
6364 iwrphase++;
6366 } else {
6368 float next_dsamp = CalcDelay(unit, delaytime);
6369 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6371 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6372 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6374 for(int i = 0; i < inNumSamples; i++) {
6375 curtrig = trig[i];
6376 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6377 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6379 prevtrig = curtrig;
6380 dsamp += dsamp_slope;
6381 long idsamp = (long)dsamp;
6382 float frac = dsamp - idsamp;
6383 long irdphase1 = iwrphase - idsamp;
6384 long irdphase2 = irdphase1 - 1;
6385 long irdphase3 = irdphase1 - 2;
6386 long irdphase0 = irdphase1 + 1;
6387 if (inputsamps > 0) {
6388 thisin = in[i];
6389 --inputsamps;
6390 } else {
6391 thisin = 0.f;
6393 if (irdphase0 < 0) {
6394 dlybuf[iwrphase & mask] = thisin;
6395 out[i] = 0.f;
6396 } else {
6397 if (irdphase1 < 0) {
6398 d1 = d2 = d3 = 0.f;
6399 d0 = dlybuf[irdphase0 & mask];
6400 } else if (irdphase2 < 0) {
6401 d1 = d2 = d3 = 0.f;
6402 d0 = dlybuf[irdphase0 & mask];
6403 d1 = dlybuf[irdphase1 & mask];
6404 } else if (irdphase3 < 0) {
6405 d3 = 0.f;
6406 d0 = dlybuf[irdphase0 & mask];
6407 d1 = dlybuf[irdphase1 & mask];
6408 d2 = dlybuf[irdphase2 & mask];
6409 } else {
6410 d0 = dlybuf[irdphase0 & mask];
6411 d1 = dlybuf[irdphase1 & mask];
6412 d2 = dlybuf[irdphase2 & mask];
6413 d3 = dlybuf[irdphase3 & mask];
6415 float value = cubicinterp(frac, d0, d1, d2, d3);
6416 float thiscoef = coef[i];
6417 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6418 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6419 out[i] = lastsamp = onepole;
6421 feedbk += feedbk_slope;
6422 iwrphase++;
6424 unit->m_feedbk = feedbk;
6425 unit->m_dsamp = dsamp;
6426 unit->m_delaytime = delaytime;
6427 unit->m_decaytime = decaytime;
6430 unit->m_inputsamps = inputsamps;
6431 unit->m_prevtrig = prevtrig;
6432 unit->m_lastsamp = zapgremlins(lastsamp);
6433 unit->m_iwrphase = iwrphase;
6435 unit->m_numoutput += inNumSamples;
6436 if (unit->m_numoutput >= unit->m_idelaylen) {
6437 SETCALC(Pluck_next_aa);
6441 void Pluck_next_kk(Pluck *unit, int inNumSamples)
6443 float *out = OUT(0);
6444 float *in = IN(0);
6445 float trig = IN0(1);
6446 float delaytime = IN0(3);
6447 float decaytime = IN0(4);
6448 float coef = IN0(5);
6449 float lastsamp = unit->m_lastsamp;
6450 unsigned long inputsamps = unit->m_inputsamps;
6452 float *dlybuf = unit->m_dlybuf;
6453 long iwrphase = unit->m_iwrphase;
6454 float dsamp = unit->m_dsamp;
6455 float feedbk = unit->m_feedbk;
6456 long mask = unit->m_mask;
6457 float thisin;
6459 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6460 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6462 unit->m_prevtrig = trig;
6464 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6465 long idsamp = (long)dsamp;
6466 float frac = dsamp - idsamp;
6468 for(int i = 0; i < inNumSamples; i++){
6469 long irdphase1 = iwrphase - idsamp;
6470 long irdphase2 = irdphase1 - 1;
6471 long irdphase3 = irdphase1 - 2;
6472 long irdphase0 = irdphase1 + 1;
6473 if (inputsamps > 0) {
6474 thisin = in[i];
6475 --inputsamps;
6476 } else {
6477 thisin = 0.f;
6479 float d0 = dlybuf[irdphase0 & mask];
6480 float d1 = dlybuf[irdphase1 & mask];
6481 float d2 = dlybuf[irdphase2 & mask];
6482 float d3 = dlybuf[irdphase3 & mask];
6483 float value = cubicinterp(frac, d0, d1, d2, d3);
6484 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6485 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6486 out[i] = lastsamp = onepole; //value;
6487 iwrphase++;
6489 } else {
6491 float next_dsamp = CalcDelay(unit, delaytime);
6492 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6494 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6495 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6497 float curcoef = unit->m_coef;
6498 float coef_slope = CALCSLOPE(coef, curcoef);
6500 for(int i = 0; i < inNumSamples; i++){
6501 dsamp += dsamp_slope;
6502 long idsamp = (long)dsamp;
6503 float frac = dsamp - idsamp;
6504 long irdphase1 = iwrphase - idsamp;
6505 long irdphase2 = irdphase1 - 1;
6506 long irdphase3 = irdphase1 - 2;
6507 long irdphase0 = irdphase1 + 1;
6508 if (inputsamps > 0) {
6509 thisin = in[i];
6510 --inputsamps;
6511 } else {
6512 thisin = 0.f;
6514 float d0 = dlybuf[irdphase0 & mask];
6515 float d1 = dlybuf[irdphase1 & mask];
6516 float d2 = dlybuf[irdphase2 & mask];
6517 float d3 = dlybuf[irdphase3 & mask];
6518 float value = cubicinterp(frac, d0, d1, d2, d3);
6519 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6520 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6521 out[i] = lastsamp = onepole; //value;
6522 feedbk += feedbk_slope;
6523 curcoef += coef_slope;
6524 iwrphase++;
6526 unit->m_feedbk = feedbk;
6527 unit->m_coef = coef;
6528 unit->m_dsamp = dsamp;
6529 unit->m_delaytime = delaytime;
6530 unit->m_decaytime = decaytime;
6533 unit->m_inputsamps = inputsamps;
6534 unit->m_lastsamp = zapgremlins(lastsamp);
6535 unit->m_iwrphase = iwrphase;
6540 void Pluck_next_kk_z(Pluck *unit, int inNumSamples)
6542 float *out = OUT(0);
6543 float *in = IN(0);
6544 float trig = IN0(1);
6545 float delaytime = IN0(3);
6546 float decaytime = IN0(4);
6547 float coef = IN0(5);
6548 float lastsamp = unit->m_lastsamp;
6550 float *dlybuf = unit->m_dlybuf;
6551 long iwrphase = unit->m_iwrphase;
6552 float dsamp = unit->m_dsamp;
6553 float feedbk = unit->m_feedbk;
6554 long mask = unit->m_mask;
6555 float d0, d1, d2, d3;
6556 float thisin;
6557 unsigned long inputsamps = unit->m_inputsamps;
6559 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6560 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6562 unit->m_prevtrig = trig;
6564 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6565 long idsamp = (long)dsamp;
6566 float frac = dsamp - idsamp;
6567 for(int i = 0; i < inNumSamples; i++){
6569 long irdphase1 = iwrphase - idsamp;
6570 long irdphase2 = irdphase1 - 1;
6571 long irdphase3 = irdphase1 - 2;
6572 long irdphase0 = irdphase1 + 1;
6573 if (inputsamps > 0) {
6574 thisin = in[i];
6575 --inputsamps;
6576 } else {
6577 thisin = 0.f;
6579 if (irdphase0 < 0) {
6580 dlybuf[iwrphase & mask] = thisin;
6581 out[i] = 0.f;
6582 } else {
6583 if (irdphase1 < 0) {
6584 d1 = d2 = d3 = 0.f;
6585 d0 = dlybuf[irdphase0 & mask];
6586 } else if (irdphase2 < 0) {
6587 d1 = d2 = d3 = 0.f;
6588 d0 = dlybuf[irdphase0 & mask];
6589 d1 = dlybuf[irdphase1 & mask];
6590 } else if (irdphase3 < 0) {
6591 d3 = 0.f;
6592 d0 = dlybuf[irdphase0 & mask];
6593 d1 = dlybuf[irdphase1 & mask];
6594 d2 = dlybuf[irdphase2 & mask];
6595 } else {
6596 d0 = dlybuf[irdphase0 & mask];
6597 d1 = dlybuf[irdphase1 & mask];
6598 d2 = dlybuf[irdphase2 & mask];
6599 d3 = dlybuf[irdphase3 & mask];
6601 float value = cubicinterp(frac, d0, d1, d2, d3);
6602 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6603 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6604 out[i] = lastsamp = onepole; //value;
6606 iwrphase++;
6608 } else {
6610 float next_dsamp = CalcDelay(unit, delaytime);
6611 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6613 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6614 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6616 float curcoef = unit->m_coef;
6617 float coef_slope = CALCSLOPE(coef, curcoef);
6619 for(int i = 0; i < inNumSamples; i++) {
6620 dsamp += dsamp_slope;
6621 long idsamp = (long)dsamp;
6622 float frac = dsamp - idsamp;
6623 long irdphase1 = iwrphase - idsamp;
6624 long irdphase2 = irdphase1 - 1;
6625 long irdphase3 = irdphase1 - 2;
6626 long irdphase0 = irdphase1 + 1;
6627 if (inputsamps > 0) {
6628 thisin = in[i];
6629 --inputsamps;
6630 } else {
6631 thisin = 0.f;
6633 if (irdphase0 < 0) {
6634 dlybuf[iwrphase & mask] = thisin;
6635 out[i] = 0.f;
6636 } else {
6637 if (irdphase1 < 0) {
6638 d1 = d2 = d3 = 0.f;
6639 d0 = dlybuf[irdphase0 & mask];
6640 } else if (irdphase2 < 0) {
6641 d1 = d2 = d3 = 0.f;
6642 d0 = dlybuf[irdphase0 & mask];
6643 d1 = dlybuf[irdphase1 & mask];
6644 } else if (irdphase3 < 0) {
6645 d3 = 0.f;
6646 d0 = dlybuf[irdphase0 & mask];
6647 d1 = dlybuf[irdphase1 & mask];
6648 d2 = dlybuf[irdphase2 & mask];
6649 } else {
6650 d0 = dlybuf[irdphase0 & mask];
6651 d1 = dlybuf[irdphase1 & mask];
6652 d2 = dlybuf[irdphase2 & mask];
6653 d3 = dlybuf[irdphase3 & mask];
6655 float value = cubicinterp(frac, d0, d1, d2, d3);
6656 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6657 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6658 out[i] = lastsamp = onepole; //value;
6660 feedbk += feedbk_slope;
6661 curcoef += coef_slope;
6662 iwrphase++;
6664 unit->m_feedbk = feedbk;
6665 unit->m_dsamp = dsamp;
6666 unit->m_delaytime = delaytime;
6667 unit->m_decaytime = decaytime;
6668 unit->m_coef = coef;
6671 unit->m_inputsamps = inputsamps;
6672 unit->m_lastsamp = zapgremlins(lastsamp);
6673 unit->m_iwrphase = iwrphase;
6675 unit->m_numoutput += inNumSamples;
6676 if (unit->m_numoutput >= unit->m_idelaylen) {
6677 SETCALC(Pluck_next_kk);
6681 void Pluck_next_ak(Pluck *unit, int inNumSamples)
6683 float *out = OUT(0);
6684 float *in = IN(0);
6685 float *trig = IN(1);
6686 float delaytime = IN0(3);
6687 float decaytime = IN0(4);
6688 float coef = IN0(5);
6689 float lastsamp = unit->m_lastsamp;
6690 unsigned long inputsamps = unit->m_inputsamps;
6692 float *dlybuf = unit->m_dlybuf;
6693 long iwrphase = unit->m_iwrphase;
6694 float dsamp = unit->m_dsamp;
6695 float feedbk = unit->m_feedbk;
6696 long mask = unit->m_mask;
6697 float thisin, curtrig;
6698 float prevtrig = unit->m_prevtrig;
6700 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6701 long idsamp = (long)dsamp;
6702 float frac = dsamp - idsamp;
6703 for(int i = 0; i < inNumSamples; i++){
6704 curtrig = trig[i];
6705 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6706 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6708 prevtrig = curtrig;
6709 long irdphase1 = iwrphase - idsamp;
6710 long irdphase2 = irdphase1 - 1;
6711 long irdphase3 = irdphase1 - 2;
6712 long irdphase0 = irdphase1 + 1;
6713 if (inputsamps > 0) {
6714 thisin = in[i];
6715 --inputsamps;
6716 } else {
6717 thisin = 0.f;
6719 float d0 = dlybuf[irdphase0 & mask];
6720 float d1 = dlybuf[irdphase1 & mask];
6721 float d2 = dlybuf[irdphase2 & mask];
6722 float d3 = dlybuf[irdphase3 & mask];
6723 float value = cubicinterp(frac, d0, d1, d2, d3);
6724 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6725 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6726 out[i] = lastsamp = onepole;
6727 iwrphase++;
6729 } else {
6731 float next_dsamp = CalcDelay(unit, delaytime);
6732 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6734 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6735 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6737 float curcoef = unit->m_coef;
6738 float coef_slope = CALCSLOPE(coef, curcoef);
6740 for(int i = 0; i < inNumSamples; i++){
6741 curtrig = trig[i];
6742 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6743 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6745 prevtrig = curtrig;
6746 dsamp += dsamp_slope;
6747 long idsamp = (long)dsamp;
6748 float frac = dsamp - idsamp;
6749 long irdphase1 = iwrphase - idsamp;
6750 long irdphase2 = irdphase1 - 1;
6751 long irdphase3 = irdphase1 - 2;
6752 long irdphase0 = irdphase1 + 1;
6753 if (inputsamps > 0) {
6754 thisin = in[i];
6755 --inputsamps;
6756 } else {
6757 thisin = 0.f;
6759 float d0 = dlybuf[irdphase0 & mask];
6760 float d1 = dlybuf[irdphase1 & mask];
6761 float d2 = dlybuf[irdphase2 & mask];
6762 float d3 = dlybuf[irdphase3 & mask];
6763 float value = cubicinterp(frac, d0, d1, d2, d3);
6764 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6765 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6766 out[i] = lastsamp = onepole;
6767 feedbk += feedbk_slope;
6768 curcoef += coef_slope;
6769 iwrphase++;
6771 unit->m_feedbk = feedbk;
6772 unit->m_dsamp = dsamp;
6773 unit->m_delaytime = delaytime;
6774 unit->m_decaytime = decaytime;
6775 unit->m_coef = coef;
6778 unit->m_prevtrig = prevtrig;
6779 unit->m_inputsamps = inputsamps;
6780 unit->m_lastsamp = zapgremlins(lastsamp);
6781 unit->m_iwrphase = iwrphase;
6786 void Pluck_next_ak_z(Pluck *unit, int inNumSamples)
6788 float *out = OUT(0);
6789 float *in = IN(0);
6790 float *trig = IN(1);
6791 float delaytime = IN0(3);
6792 float decaytime = IN0(4);
6793 float coef = IN0(5);
6794 float lastsamp = unit->m_lastsamp;
6796 float *dlybuf = unit->m_dlybuf;
6797 long iwrphase = unit->m_iwrphase;
6798 float dsamp = unit->m_dsamp;
6799 float feedbk = unit->m_feedbk;
6800 long mask = unit->m_mask;
6801 float d0, d1, d2, d3;
6802 float thisin, curtrig;
6803 unsigned long inputsamps = unit->m_inputsamps;
6804 float prevtrig = unit->m_prevtrig;
6806 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6807 long idsamp = (long)dsamp;
6808 float frac = dsamp - idsamp;
6809 for(int i = 0; i < inNumSamples; i++){
6810 curtrig = trig[i];
6811 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6812 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6814 prevtrig = curtrig;
6815 long irdphase1 = iwrphase - idsamp;
6816 long irdphase2 = irdphase1 - 1;
6817 long irdphase3 = irdphase1 - 2;
6818 long irdphase0 = irdphase1 + 1;
6819 if (inputsamps > 0) {
6820 thisin = in[i];
6821 --inputsamps;
6822 } else {
6823 thisin = 0.f;
6825 if (irdphase0 < 0) {
6826 dlybuf[iwrphase & mask] = thisin;
6827 out[i] = 0.f;
6828 } else {
6829 if (irdphase1 < 0) {
6830 d1 = d2 = d3 = 0.f;
6831 d0 = dlybuf[irdphase0 & mask];
6832 } else if (irdphase2 < 0) {
6833 d1 = d2 = d3 = 0.f;
6834 d0 = dlybuf[irdphase0 & mask];
6835 d1 = dlybuf[irdphase1 & mask];
6836 } else if (irdphase3 < 0) {
6837 d3 = 0.f;
6838 d0 = dlybuf[irdphase0 & mask];
6839 d1 = dlybuf[irdphase1 & mask];
6840 d2 = dlybuf[irdphase2 & mask];
6841 } else {
6842 d0 = dlybuf[irdphase0 & mask];
6843 d1 = dlybuf[irdphase1 & mask];
6844 d2 = dlybuf[irdphase2 & mask];
6845 d3 = dlybuf[irdphase3 & mask];
6847 float value = cubicinterp(frac, d0, d1, d2, d3);
6848 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6849 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6850 out[i] = lastsamp = onepole;
6852 iwrphase++;
6854 } else {
6856 float next_dsamp = CalcDelay(unit, delaytime);
6857 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6859 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6860 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6862 float curcoef = unit->m_coef;
6863 float coef_slope = CALCSLOPE(coef, curcoef);
6865 for(int i = 0; i < inNumSamples; i++) {
6866 curtrig = trig[i];
6867 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6868 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6870 prevtrig = curtrig;
6871 dsamp += dsamp_slope;
6872 long idsamp = (long)dsamp;
6873 float frac = dsamp - idsamp;
6874 long irdphase1 = iwrphase - idsamp;
6875 long irdphase2 = irdphase1 - 1;
6876 long irdphase3 = irdphase1 - 2;
6877 long irdphase0 = irdphase1 + 1;
6878 if (inputsamps > 0) {
6879 thisin = in[i];
6880 --inputsamps;
6881 } else {
6882 thisin = 0.f;
6884 if (irdphase0 < 0) {
6885 dlybuf[iwrphase & mask] = thisin;
6886 out[i] = 0.f;
6887 } else {
6888 if (irdphase1 < 0) {
6889 d1 = d2 = d3 = 0.f;
6890 d0 = dlybuf[irdphase0 & mask];
6891 } else if (irdphase2 < 0) {
6892 d1 = d2 = d3 = 0.f;
6893 d0 = dlybuf[irdphase0 & mask];
6894 d1 = dlybuf[irdphase1 & mask];
6895 } else if (irdphase3 < 0) {
6896 d3 = 0.f;
6897 d0 = dlybuf[irdphase0 & mask];
6898 d1 = dlybuf[irdphase1 & mask];
6899 d2 = dlybuf[irdphase2 & mask];
6900 } else {
6901 d0 = dlybuf[irdphase0 & mask];
6902 d1 = dlybuf[irdphase1 & mask];
6903 d2 = dlybuf[irdphase2 & mask];
6904 d3 = dlybuf[irdphase3 & mask];
6906 float value = cubicinterp(frac, d0, d1, d2, d3);
6907 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6908 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6909 out[i] = lastsamp = onepole;
6911 feedbk += feedbk_slope;
6912 curcoef +=coef_slope;
6913 iwrphase++;
6915 unit->m_feedbk = feedbk;
6916 unit->m_dsamp = dsamp;
6917 unit->m_delaytime = delaytime;
6918 unit->m_decaytime = decaytime;
6919 unit->m_coef = coef;
6922 unit->m_inputsamps = inputsamps;
6923 unit->m_prevtrig = prevtrig;
6924 unit->m_lastsamp = zapgremlins(lastsamp);
6925 unit->m_iwrphase = iwrphase;
6927 unit->m_numoutput += inNumSamples;
6928 if (unit->m_numoutput >= unit->m_idelaylen) {
6929 SETCALC(Pluck_next_ak);
6934 void Pluck_next_ka(Pluck *unit, int inNumSamples)
6936 float *out = OUT(0);
6937 float *in = IN(0);
6938 float trig = IN0(1);
6939 float delaytime = IN0(3);
6940 float decaytime = IN0(4);
6941 float *coef = IN(5);
6942 float lastsamp = unit->m_lastsamp;
6943 unsigned long inputsamps = unit->m_inputsamps;
6945 float *dlybuf = unit->m_dlybuf;
6946 long iwrphase = unit->m_iwrphase;
6947 float dsamp = unit->m_dsamp;
6948 float feedbk = unit->m_feedbk;
6949 long mask = unit->m_mask;
6950 float thisin;
6952 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6953 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6955 unit->m_prevtrig = trig;
6957 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6958 long idsamp = (long)dsamp;
6959 float frac = dsamp - idsamp;
6960 for(int i = 0; i < inNumSamples; i++){
6961 long irdphase1 = iwrphase - idsamp;
6962 long irdphase2 = irdphase1 - 1;
6963 long irdphase3 = irdphase1 - 2;
6964 long irdphase0 = irdphase1 + 1;
6965 if (inputsamps > 0) {
6966 thisin = in[i];
6967 --inputsamps;
6968 } else {
6969 thisin = 0.f;
6971 float d0 = dlybuf[irdphase0 & mask];
6972 float d1 = dlybuf[irdphase1 & mask];
6973 float d2 = dlybuf[irdphase2 & mask];
6974 float d3 = dlybuf[irdphase3 & mask];
6975 float value = cubicinterp(frac, d0, d1, d2, d3);
6976 float thiscoef = coef[i];
6977 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6978 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6979 out[i] = lastsamp = onepole;
6980 iwrphase++;
6982 } else {
6984 float next_dsamp = CalcDelay(unit, delaytime);
6985 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6987 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6988 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6990 for(int i = 0; i < inNumSamples; i++){
6991 dsamp += dsamp_slope;
6992 long idsamp = (long)dsamp;
6993 float frac = dsamp - idsamp;
6994 long irdphase1 = iwrphase - idsamp;
6995 long irdphase2 = irdphase1 - 1;
6996 long irdphase3 = irdphase1 - 2;
6997 long irdphase0 = irdphase1 + 1;
6998 if (inputsamps > 0) {
6999 thisin = in[i];
7000 --inputsamps;
7001 } else {
7002 thisin = 0.f;
7004 float d0 = dlybuf[irdphase0 & mask];
7005 float d1 = dlybuf[irdphase1 & mask];
7006 float d2 = dlybuf[irdphase2 & mask];
7007 float d3 = dlybuf[irdphase3 & mask];
7008 float value = cubicinterp(frac, d0, d1, d2, d3);
7009 float thiscoef = coef[i];
7010 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7011 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7012 out[i] = lastsamp = onepole;
7013 feedbk += feedbk_slope;
7014 iwrphase++;
7016 unit->m_feedbk = feedbk;
7017 unit->m_dsamp = dsamp;
7018 unit->m_delaytime = delaytime;
7019 unit->m_decaytime = decaytime;
7022 unit->m_inputsamps = inputsamps;
7023 unit->m_lastsamp = zapgremlins(lastsamp);
7024 unit->m_iwrphase = iwrphase;
7029 void Pluck_next_ka_z(Pluck *unit, int inNumSamples)
7031 float *out = OUT(0);
7032 float *in = IN(0);
7033 float trig = IN0(1);
7034 float delaytime = IN0(3);
7035 float decaytime = IN0(4);
7036 float *coef = IN(5);
7037 float lastsamp = unit->m_lastsamp;
7039 float *dlybuf = unit->m_dlybuf;
7040 long iwrphase = unit->m_iwrphase;
7041 float dsamp = unit->m_dsamp;
7042 float feedbk = unit->m_feedbk;
7043 long mask = unit->m_mask;
7044 float d0, d1, d2, d3;
7045 float thisin;
7046 unsigned long inputsamps = unit->m_inputsamps;
7048 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
7049 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
7052 unit->m_prevtrig = trig;
7054 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
7055 long idsamp = (long)dsamp;
7056 float frac = dsamp - idsamp;
7057 for(int i = 0; i < inNumSamples; i++){
7058 long irdphase1 = iwrphase - idsamp;
7059 long irdphase2 = irdphase1 - 1;
7060 long irdphase3 = irdphase1 - 2;
7061 long irdphase0 = irdphase1 + 1;
7062 if (inputsamps > 0) {
7063 thisin = in[i];
7064 --inputsamps;
7065 } else {
7066 thisin = 0.f;
7068 if (irdphase0 < 0) {
7069 dlybuf[iwrphase & mask] = thisin;
7070 out[i] = 0.f;
7071 } else {
7072 if (irdphase1 < 0) {
7073 d1 = d2 = d3 = 0.f;
7074 d0 = dlybuf[irdphase0 & mask];
7075 } else if (irdphase2 < 0) {
7076 d1 = d2 = d3 = 0.f;
7077 d0 = dlybuf[irdphase0 & mask];
7078 d1 = dlybuf[irdphase1 & mask];
7079 } else if (irdphase3 < 0) {
7080 d3 = 0.f;
7081 d0 = dlybuf[irdphase0 & mask];
7082 d1 = dlybuf[irdphase1 & mask];
7083 d2 = dlybuf[irdphase2 & mask];
7084 } else {
7085 d0 = dlybuf[irdphase0 & mask];
7086 d1 = dlybuf[irdphase1 & mask];
7087 d2 = dlybuf[irdphase2 & mask];
7088 d3 = dlybuf[irdphase3 & mask];
7090 float value = cubicinterp(frac, d0, d1, d2, d3);
7091 float thiscoef = coef[i];
7092 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7093 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7094 out[i] = lastsamp = onepole;
7096 iwrphase++;
7098 } else {
7100 float next_dsamp = CalcDelay(unit, delaytime);
7101 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
7103 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
7104 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
7106 for(int i = 0; i < inNumSamples; i++) {
7107 dsamp += dsamp_slope;
7108 long idsamp = (long)dsamp;
7109 float frac = dsamp - idsamp;
7110 long irdphase1 = iwrphase - idsamp;
7111 long irdphase2 = irdphase1 - 1;
7112 long irdphase3 = irdphase1 - 2;
7113 long irdphase0 = irdphase1 + 1;
7114 if (inputsamps > 0) {
7115 thisin = in[i];
7116 --inputsamps;
7117 } else {
7118 thisin = 0.f;
7120 if (irdphase0 < 0) {
7121 dlybuf[iwrphase & mask] = thisin;
7122 out[i] = 0.f;
7123 } else {
7124 if (irdphase1 < 0) {
7125 d1 = d2 = d3 = 0.f;
7126 d0 = dlybuf[irdphase0 & mask];
7127 } else if (irdphase2 < 0) {
7128 d1 = d2 = d3 = 0.f;
7129 d0 = dlybuf[irdphase0 & mask];
7130 d1 = dlybuf[irdphase1 & mask];
7131 } else if (irdphase3 < 0) {
7132 d3 = 0.f;
7133 d0 = dlybuf[irdphase0 & mask];
7134 d1 = dlybuf[irdphase1 & mask];
7135 d2 = dlybuf[irdphase2 & mask];
7136 } else {
7137 d0 = dlybuf[irdphase0 & mask];
7138 d1 = dlybuf[irdphase1 & mask];
7139 d2 = dlybuf[irdphase2 & mask];
7140 d3 = dlybuf[irdphase3 & mask];
7142 float value = cubicinterp(frac, d0, d1, d2, d3);
7143 float thiscoef = coef[i];
7144 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7145 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7146 out[i] = lastsamp = onepole;
7148 feedbk += feedbk_slope;
7149 iwrphase++;
7151 unit->m_feedbk = feedbk;
7152 unit->m_dsamp = dsamp;
7153 unit->m_delaytime = delaytime;
7154 unit->m_decaytime = decaytime;
7157 unit->m_inputsamps = inputsamps;
7158 unit->m_lastsamp = zapgremlins(lastsamp);
7159 unit->m_iwrphase = iwrphase;
7161 unit->m_numoutput += inNumSamples;
7162 if (unit->m_numoutput >= unit->m_idelaylen) {
7163 SETCALC(Pluck_next_ka);
7168 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7171 #define DELTAP_BUF \
7172 World *world = unit->mWorld;\
7173 if (bufnum >= world->mNumSndBufs) { \
7174 int localBufNum = bufnum - world->mNumSndBufs; \
7175 Graph *parent = unit->mParent; \
7176 if(localBufNum <= parent->localBufNum) { \
7177 unit->m_buf = parent->mLocalSndBufs + localBufNum; \
7178 } else { \
7179 bufnum = 0; \
7180 unit->m_buf = world->mSndBufs + bufnum; \
7182 } else { \
7183 unit->m_buf = world->mSndBufs + bufnum; \
7185 SndBuf *buf = unit->m_buf; \
7186 float *bufData __attribute__((__unused__)) = buf->data; \
7187 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
7188 uint32 bufSamples = buf->samples; \
7189 uint32 bufFrames = buf->frames; \
7190 int guardFrame __attribute__((__unused__)) = bufFrames - 2; \
7191 double loopMax = (double)bufSamples;
7193 #define CHECK_DELTAP_BUF \
7194 if ((!bufData) || (bufChannels != 1)) { \
7195 unit->mDone = true; \
7196 ClearUnitOutputs(unit, inNumSamples); \
7197 return; \
7201 static void DelTapWr_first(DelTapWr *unit, int inNumSamples)
7203 float fbufnum = IN0(0);
7204 uint32 bufnum = (uint32)fbufnum;
7205 float* in = IN(1);
7206 float* out = OUT(0);
7208 uint32 phase = unit->m_phase;
7210 DELTAP_BUF
7211 CHECK_DELTAP_BUF
7213 // zero out the buffer!
7214 #ifdef NOVA_SIMD
7215 if (nova::vec<float>::is_aligned(bufData)) {
7216 uint32 unroll = bufSamples & (~(nova::vec<float>::size - 1));
7217 nova::zerovec_simd(bufData, unroll);
7219 uint32 remain = bufSamples - unroll;
7220 Clear(remain, bufData + unroll);
7221 } else
7222 Clear(bufSamples, bufData);
7223 #else
7224 Clear(bufSamples, bufData);
7225 #endif
7227 out[0] = (float)phase;
7228 bufData[phase] = in[0];
7229 phase++;
7230 if(phase == bufSamples)
7231 phase -= bufSamples;
7233 unit->m_phase = phase;
7236 void DelTapWr_Ctor(DelTapWr *unit)
7238 if (BUFLENGTH & 15)
7239 SETCALC(DelTapWr_next);
7240 else
7241 SETCALC(DelTapWr_next_simd);
7242 unit->m_phase = 0;
7243 unit->m_fbufnum = -1e9f;
7244 DelTapWr_first(unit, 1);
7247 template <bool simd>
7248 static inline void DelTapWr_perform(DelTapWr *unit, int inNumSamples)
7250 float fbufnum = IN0(0);
7251 uint32 bufnum = (uint32)fbufnum;
7252 const float* in = ZIN(1);
7253 float* out = ZOUT(0);
7254 uint32 * phase_out = (uint32*)out;
7256 uint32 phase = unit->m_phase;
7258 DELTAP_BUF
7259 CHECK_DELTAP_BUF
7261 LOCK_SNDBUF(buf);
7262 int buf_remain = (int)(bufSamples - phase);
7263 if (inNumSamples < buf_remain)
7265 /* fast-path */
7266 #ifdef NOVA_SIMD
7267 if (simd)
7268 nova::copyvec_an_simd(bufData+phase, IN(1), inNumSamples);
7269 else
7270 #endif
7271 Copy(inNumSamples, bufData + phase, IN(1));
7272 LOOP1 (inNumSamples,
7273 ZXP(phase_out) = phase++;
7275 } else {
7276 LOOP1 (inNumSamples,
7277 bufData[phase] = ZXP(in);
7278 ZXP(phase_out) = phase++;
7279 if(phase == bufSamples)
7280 phase -= bufSamples;
7284 unit->m_phase = phase;
7287 void DelTapWr_next(DelTapWr *unit, int inNumSamples)
7289 DelTapWr_perform<false>(unit, inNumSamples);
7292 void DelTapWr_next_simd(DelTapWr *unit, int inNumSamples)
7294 DelTapWr_perform<true>(unit, inNumSamples);
7298 #define SETUP_TAPDELK \
7299 float delTime = unit->m_delTime; \
7300 float newDelTime = IN0(2) * (float)SAMPLERATE; \
7301 float delTimeInc = CALCSLOPE(newDelTime, delTime); \
7302 float * fPhaseIn = IN(1); \
7303 uint32 * iPhaseIn = (uint32*)fPhaseIn; \
7304 uint32 phaseIn = *iPhaseIn; \
7305 float fbufnum = IN0(0); \
7306 uint32 bufnum = (uint32)fbufnum; \
7307 float* out = ZOUT(0); \
7309 #define SETUP_TAPDELA \
7310 float* delTime = ZIN(2); \
7311 float * fPhaseIn = IN(1); \
7312 uint32 * iPhaseIn = (uint32*)fPhaseIn; \
7313 uint32 phaseIn = *iPhaseIn; \
7314 float fbufnum = IN0(0); \
7315 uint32 bufnum = (uint32)fbufnum; \
7316 float* out = ZOUT(0); \
7318 void DelTapRd_Ctor(DelTapRd *unit)
7320 unit->m_fbufnum = -1e9f;
7321 unit->m_delTime = IN0(2) * SAMPLERATE;
7322 int interp = (int)IN0(3);
7323 if (INRATE(2) == calc_FullRate) {
7324 if (interp == 2)
7325 SETCALC(DelTapRd_next2_a);
7326 else if (interp == 4)
7327 SETCALC(DelTapRd_next4_a);
7328 else
7329 SETCALC(DelTapRd_next1_a);
7330 } else {
7331 if (interp == 2)
7332 SETCALC(DelTapRd_next2_k);
7333 else if (interp == 4)
7334 SETCALC(DelTapRd_next4_k);
7335 else
7336 if (BUFLENGTH & 15)
7337 SETCALC(DelTapRd_next1_k);
7338 else {
7339 SETCALC(DelTapRd_next1_k_simd);
7340 DelTapRd_next1_k(unit, 1);
7341 return;
7344 (unit->mCalcFunc)(unit, 1);
7348 void DelTapRd_next1_a(DelTapRd *unit, int inNumSamples)
7350 SETUP_TAPDELA
7351 DELTAP_BUF
7352 CHECK_DELTAP_BUF
7354 LOCK_SNDBUF_SHARED(buf);
7355 LOOP1(inNumSamples,
7356 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7357 double phase = phaseIn - curDelTimeSamps;
7358 if(phase < 0.) phase += loopMax;
7359 if(phase >=loopMax) phase -= loopMax;
7360 int32 iphase = (int32)phase;
7361 ZXP(out) = bufData[iphase];
7362 phaseIn += 1.;
7366 template <bool simd>
7367 inline void DelTapRd_perform1_k(DelTapRd *unit, int inNumSamples)
7369 SETUP_TAPDELK
7370 DELTAP_BUF
7371 CHECK_DELTAP_BUF
7372 float * zout = ZOUT(0);
7374 LOCK_SNDBUF_SHARED(buf);
7375 if (delTime == newDelTime)
7377 double phase = (double)phaseIn - delTime;
7378 int32 iphase = (int32)phase;
7379 if ( (iphase >= 0) // lower bound
7380 && iphase + inNumSamples < (bufSamples - 1)) //upper bound
7382 #ifdef NOVA_SIMD
7383 if (simd)
7384 nova::copyvec_na_simd(OUT(0), bufData + iphase, inNumSamples);
7385 else
7386 #endif
7387 Copy(inNumSamples, OUT(0), bufData + iphase);
7389 else
7390 LOOP1(inNumSamples,
7391 if(iphase < 0) iphase += bufSamples;
7392 if(iphase >= bufSamples) iphase -= bufSamples;
7393 ZXP(zout) = bufData[iphase];
7394 ++iphase;
7396 } else {
7397 LOOP1(inNumSamples,
7398 double phase = (double)phaseIn - delTime;
7399 if(phase < 0.) phase += loopMax;
7400 if(phase >=loopMax) phase -= loopMax;
7401 int32 iphase = (int32)phase;
7402 ZXP(zout) = bufData[iphase];
7403 delTime += delTimeInc;
7404 ++phaseIn;
7406 unit->m_delTime = delTime;
7410 void DelTapRd_next1_k(DelTapRd *unit, int inNumSamples)
7412 DelTapRd_perform1_k<false>(unit, inNumSamples);
7415 void DelTapRd_next1_k_simd(DelTapRd *unit, int inNumSamples)
7417 DelTapRd_perform1_k<true>(unit, inNumSamples);
7420 void DelTapRd_next2_k(DelTapRd *unit, int inNumSamples)
7422 SETUP_TAPDELK
7423 DELTAP_BUF
7424 CHECK_DELTAP_BUF
7426 int32 iloopMax = (int32)bufSamples;
7428 LOCK_SNDBUF_SHARED(buf);
7430 if (delTime == newDelTime)
7432 double phase = (double)phaseIn - delTime;
7433 double dphase;
7434 float fracphase = std::modf(phase, &dphase);
7435 int32 iphase = (int32)dphase;
7437 if ( (phase >= 0) // lower bound
7438 && phase + inNumSamples < (loopMax - 2)) //upper bound
7440 LOOP1(inNumSamples,
7441 int32 iphase1 = iphase + 1;
7442 float b = bufData[iphase];
7443 float c = bufData[iphase1];
7444 ZXP(out) = (b + fracphase * (c - b));
7445 iphase += 1;
7447 } else {
7448 LOOP1(inNumSamples,
7449 if(iphase < 0) iphase += iloopMax;
7450 else if(iphase >= bufSamples) phase -= iloopMax;
7451 int32 iphase1 = iphase + 1;
7452 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7453 float b = bufData[iphase];
7454 float c = bufData[iphase1];
7455 ZXP(out) = (b + fracphase * (c - b));
7456 ++iphase;
7459 } else {
7460 LOOP1(inNumSamples,
7461 double phase = (double)phaseIn - delTime;
7462 if(phase < 0.) phase += loopMax;
7463 if(phase >= loopMax) phase -= loopMax;
7464 int32 iphase = (int32)phase;
7465 int32 iphase1 = iphase + 1;
7466 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7467 float fracphase = phase - (double)iphase;
7468 float b = bufData[iphase];
7469 float c = bufData[iphase1];
7470 ZXP(out) = (b + fracphase * (c - b));
7471 delTime += delTimeInc;
7472 ++phaseIn;
7474 unit->m_delTime = delTime;
7478 void DelTapRd_next2_a(DelTapRd *unit, int inNumSamples)
7480 SETUP_TAPDELA
7481 DELTAP_BUF
7482 CHECK_DELTAP_BUF
7484 int32 iloopMax = (int32)bufSamples;
7486 LOCK_SNDBUF_SHARED(buf);
7487 LOOP1(inNumSamples,
7488 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7489 double phase = (double)phaseIn - curDelTimeSamps;
7490 if(phase < 0.) phase += loopMax;
7491 if(phase >= loopMax) phase -= loopMax;
7492 int32 iphase = (int32)phase;
7493 int32 iphase1 = iphase + 1;
7494 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7495 float fracphase = phase - (double)iphase;
7496 float b = bufData[iphase];
7497 float c = bufData[iphase1];
7498 ZXP(out) = (b + fracphase * (c - b));
7499 ++phaseIn;
7503 void DelTapRd_next4_k(DelTapRd *unit, int inNumSamples)
7505 SETUP_TAPDELK
7506 DELTAP_BUF
7507 CHECK_DELTAP_BUF
7509 int32 iloopMax = (int32)loopMax;
7511 LOCK_SNDBUF_SHARED(buf);
7514 if (delTime == newDelTime)
7516 double phase = (double)phaseIn - delTime;
7517 double dphase;
7518 float fracphase = std::modf(phase, &dphase);
7519 int32 iphase = (int32)dphase;
7521 if ( (iphase >= 1) // lower bound
7522 && iphase + inNumSamples < (iloopMax - 4)) //upper bound
7524 LOOP1(inNumSamples,
7525 int32 iphase0 = iphase - 1;
7526 int32 iphase1 = iphase + 1;
7527 int32 iphase2 = iphase + 2;
7529 float a = bufData[iphase0];
7530 float b = bufData[iphase];
7531 float c = bufData[iphase1];
7532 float d = bufData[iphase2];
7533 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7534 ++iphase;
7536 } else {
7537 LOOP1(inNumSamples,
7538 if(iphase < 0) iphase += iloopMax;
7539 else if(iphase >= iloopMax) iphase -= iloopMax;
7540 int32 iphase0 = iphase - 1;
7541 int32 iphase1 = iphase + 1;
7542 int32 iphase2 = iphase + 2;
7544 if(iphase0 < 0) iphase0 += iloopMax;
7545 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7546 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7548 float a = bufData[iphase0];
7549 float b = bufData[iphase];
7550 float c = bufData[iphase1];
7551 float d = bufData[iphase2];
7552 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7553 ++iphase;
7556 } else {
7557 LOOP1(inNumSamples,
7558 double phase = (double)phaseIn - delTime;
7559 double dphase;
7560 float fracphase = std::modf(phase, &dphase);
7561 int32 iphase = (int32)dphase;
7563 if(iphase < 0.) iphase += iloopMax;
7564 if(iphase >= iloopMax) iphase -= iloopMax;
7565 int32 iphase0 = iphase - 1;
7566 int32 iphase1 = iphase + 1;
7567 int32 iphase2 = iphase + 2;
7569 if(iphase0 < 0) iphase0 += iloopMax;
7570 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7571 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7573 float a = bufData[iphase0];
7574 float b = bufData[iphase];
7575 float c = bufData[iphase1];
7576 float d = bufData[iphase2];
7577 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7578 delTime += delTimeInc;
7579 ++phaseIn;
7581 unit->m_delTime = delTime;
7585 void DelTapRd_next4_a(DelTapRd *unit, int inNumSamples)
7587 SETUP_TAPDELA
7588 DELTAP_BUF
7589 CHECK_DELTAP_BUF
7591 int32 iloopMax = (int32)loopMax;
7593 LOCK_SNDBUF_SHARED(buf);
7594 LOOP1(inNumSamples,
7595 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7596 double phase = (double)phaseIn - curDelTimeSamps;
7597 if(phase < 0.) phase += loopMax;
7598 if(phase >= loopMax) phase -= loopMax;
7599 int32 iphase = (int32)phase;
7600 int32 iphase0 = iphase - 1;
7601 int32 iphase1 = iphase + 1;
7602 int32 iphase2 = iphase + 2;
7604 if(iphase0 < 0) iphase0 += iloopMax;
7605 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7606 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7608 float fracphase = phase - (double)iphase;
7609 float a = bufData[iphase0];
7610 float b = bufData[iphase];
7611 float c = bufData[iphase1];
7612 float d = bufData[iphase2];
7613 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7614 ++phaseIn;
7619 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7622 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7624 PluginLoad(Delay)
7626 ft = inTable;
7628 #define DefineInfoUnit(name) \
7629 (*ft->fDefineUnit)(#name, sizeof(Unit), (UnitCtorFunc)&name##_Ctor, 0, 0);
7631 DefineInfoUnit(ControlRate);
7632 DefineInfoUnit(SampleRate);
7633 DefineInfoUnit(SampleDur);
7634 DefineInfoUnit(ControlDur);
7635 DefineInfoUnit(SubsampleOffset);
7636 DefineInfoUnit(RadiansPerSample);
7637 DefineInfoUnit(NumInputBuses);
7638 DefineInfoUnit(NumOutputBuses);
7639 DefineInfoUnit(NumAudioBuses);
7640 DefineInfoUnit(NumControlBuses);
7641 DefineInfoUnit(NumBuffers);
7642 DefineInfoUnit(NumRunningSynths);
7644 #define DefineBufInfoUnit(name) \
7645 (*ft->fDefineUnit)(#name, sizeof(BufInfoUnit), (UnitCtorFunc)&name##_Ctor, 0, 0);
7647 DefineBufInfoUnit(BufSampleRate);
7648 DefineBufInfoUnit(BufRateScale);
7649 DefineBufInfoUnit(BufSamples);
7650 DefineBufInfoUnit(BufFrames);
7651 DefineBufInfoUnit(BufChannels);
7652 DefineBufInfoUnit(BufDur);
7654 DefineSimpleCantAliasUnit(PlayBuf);
7655 #if NOTYET
7656 DefineSimpleUnit(SimpleLoopBuf);
7657 #endif
7658 DefineDtorUnit(RecordBuf);
7659 DefineSimpleUnit(BufRd);
7660 DefineSimpleUnit(BufWr);
7661 DefineDtorUnit(Pitch);
7663 DefineSimpleUnit(BufDelayN);
7664 DefineSimpleUnit(BufDelayL);
7665 DefineSimpleUnit(BufDelayC);
7666 DefineSimpleUnit(BufCombN);
7667 DefineSimpleUnit(BufCombL);
7668 DefineSimpleUnit(BufCombC);
7669 DefineSimpleUnit(BufAllpassN);
7670 DefineSimpleUnit(BufAllpassL);
7671 DefineSimpleUnit(BufAllpassC);
7673 #define DefineDelayUnit(name) \
7674 (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
7675 (UnitDtorFunc)&DelayUnit_Dtor, 0);
7677 DefineDelayUnit(DelayN);
7678 DefineDelayUnit(DelayL);
7679 DefineDelayUnit(DelayC);
7680 DefineDelayUnit(CombN);
7681 DefineDelayUnit(CombL);
7682 DefineDelayUnit(CombC);
7683 DefineDelayUnit(AllpassN);
7684 DefineDelayUnit(AllpassL);
7685 DefineDelayUnit(AllpassC);
7687 DefineDtorUnit(PitchShift);
7688 DefineSimpleUnit(GrainTap);
7689 DefineSimpleCantAliasUnit(TGrains);
7690 DefineDtorUnit(ScopeOut);
7691 DefineDtorUnit(ScopeOut2);
7692 DefineDelayUnit(Pluck);
7694 DefineSimpleUnit(DelTapWr);
7695 DefineSimpleUnit(DelTapRd);
7697 DefineDtorUnit(LocalBuf);
7698 DefineSimpleUnit(MaxLocalBufs);
7699 DefineSimpleUnit(SetBuf);
7700 DefineSimpleUnit(ClearBuf);
7703 //////////////////////////////////////////////////////////////////////////////////////////////////