Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / plugins / DelayUGens.cpp
blob71c83b7acb56642a258ee79f32e66d29a251829e
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 long 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 maxBufNum = (int)(IN0(0) + .5f);
740 if(!parent->localMaxBufNum) {
741 parent->mLocalSndBufs = (SndBuf*)RTAlloc(unit->mWorld, maxBufNum * sizeof(SndBuf));
742 #ifdef SUPERNOVA
743 for (int i = 0; i != maxBufNum; ++i)
744 new(&parent->mLocalSndBufs[i]) SndBuf();
745 #endif
746 parent->localMaxBufNum = maxBufNum;
747 } else {
748 printf("warning: MaxLocalBufs - maximum number of local buffers is already declared (%i) and must remain unchanged.\n", parent->localMaxBufNum);
753 //////////////////////////////////////////////////////////////////////////////////////////////////
755 void SetBuf_Ctor(SetBuf *unit)
757 OUT0(0) = 0.f;
758 CTOR_GET_BUF
759 if (!buf || !buf->data) {
760 if(unit->mWorld->mVerbosity > -2){
761 Print("SetBuf: no valid buffer\n");
763 return;
766 int offset = (int)IN0(1);
767 int numArgs = (int)IN0(2);
768 int end = sc_min(buf->samples, numArgs + offset);
770 int j = 3;
771 for(int i=offset; i<end; ++j, ++i) {
772 buf->data[i] = IN0(j);
777 //////////////////////////////////////////////////////////////////////////////////////////////////
779 void ClearBuf_Ctor(ClearBuf *unit)
781 OUT0(0) = 0.f;
782 CTOR_GET_BUF
784 if (!buf || !buf->data) {
785 if(unit->mWorld->mVerbosity > -2){
786 Print("ClearBuf: no valid buffer\n");
788 return;
791 Clear(buf->samples, buf->data);
795 ////////////////////////////////////////////////////////////////////////////////////////////////////////
797 inline double sc_loop(Unit *unit, double in, double hi, int loop)
799 // avoid the divide if possible
800 if (in >= hi) {
801 if (!loop) {
802 unit->mDone = true;
803 return hi;
805 in -= hi;
806 if (in < hi) return in;
807 } else if (in < 0.) {
808 if (!loop) {
809 unit->mDone = true;
810 return 0.;
812 in += hi;
813 if (in >= 0.) return in;
814 } else return in;
816 return in - hi * floor(in/hi);
819 #define CHECK_BUF \
820 if (!bufData) { \
821 unit->mDone = true; \
822 ClearUnitOutputs(unit, inNumSamples); \
823 return; \
826 static inline bool checkBuffer(Unit * unit, const float * bufData, uint32 bufChannels,
827 uint32 expectedChannels, int inNumSamples)
829 if (!bufData)
830 goto handle_failure;
832 if (expectedChannels > bufChannels) {
833 if(unit->mWorld->mVerbosity > -1 && !unit->mDone)
834 Print("Buffer UGen channel mismatch: expected %i, yet buffer has %i channels\n",
835 expectedChannels, bufChannels);
836 goto handle_failure;
838 return true;
840 handle_failure:
841 unit->mDone = true;
842 ClearUnitOutputs(unit, inNumSamples);
843 return false;
846 #define SETUP_IN(offset) \
847 uint32 numInputs = unit->mNumInputs - (uint32)offset; \
848 if (numInputs != bufChannels) { \
849 if(unit->mWorld->mVerbosity > -1 && !unit->mDone){ \
850 Print("buffer-writing UGen channel mismatch: numInputs %i, yet buffer has %i channels\n", numInputs, bufChannels); \
852 unit->mDone = true; \
853 ClearUnitOutputs(unit, inNumSamples); \
854 return; \
856 if(!unit->mIn){ \
857 unit->mIn = (float**)RTAlloc(unit->mWorld, numInputs * sizeof(float*)); \
858 if (unit->mIn == NULL) { \
859 unit->mDone = true; \
860 ClearUnitOutputs(unit, inNumSamples); \
861 return; \
864 float **in = unit->mIn; \
865 for (uint32 i=0; i<numInputs; ++i) { \
866 in[i] = ZIN(i+offset); \
869 #define TAKEDOWN_IN \
870 if(unit->mIn){ \
871 RTFree(unit->mWorld, unit->mIn); \
875 #define LOOP_BODY_4(SAMPLE_INDEX) \
876 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
877 int32 iphase = (int32)phase; \
878 const float* table1 = bufData + iphase * bufChannels; \
879 const float* table0 = table1 - bufChannels; \
880 const float* table2 = table1 + bufChannels; \
881 const float* table3 = table2 + bufChannels; \
882 if (iphase == 0) { \
883 if (loop) { \
884 table0 += bufSamples; \
885 } else { \
886 table0 += bufChannels; \
888 } else if (iphase >= guardFrame) { \
889 if (iphase == guardFrame) { \
890 if (loop) { \
891 table3 -= bufSamples; \
892 } else { \
893 table3 -= bufChannels; \
895 } else { \
896 if (loop) { \
897 table2 -= bufSamples; \
898 table3 -= bufSamples; \
899 } else { \
900 table2 -= bufChannels; \
901 table3 -= 2 * bufChannels; \
905 int32 index = 0; \
906 float fracphase = phase - (double)iphase; \
907 for (uint32 channel=0; channel<numOutputs; ++channel) { \
908 float a = table0[index]; \
909 float b = table1[index]; \
910 float c = table2[index]; \
911 float d = table3[index]; \
912 OUT(channel)[SAMPLE_INDEX] = cubicinterp(fracphase, a, b, c, d); \
913 index++; \
916 #define LOOP_BODY_2(SAMPLE_INDEX) \
917 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
918 int32 iphase = (int32)phase; \
919 const float* table1 = bufData + iphase * bufChannels; \
920 const float* table2 = table1 + bufChannels; \
921 if (iphase > guardFrame) { \
922 if (loop) { \
923 table2 -= bufSamples; \
924 } else { \
925 table2 -= bufChannels; \
928 int32 index = 0; \
929 float fracphase = phase - (double)iphase; \
930 for (uint32 channel=0; channel<numOutputs; ++channel) { \
931 float b = table1[index]; \
932 float c = table2[index]; \
933 OUT(channel)[SAMPLE_INDEX] = b + fracphase * (c - b); \
934 index++; \
937 #define LOOP_BODY_1(SAMPLE_INDEX) \
938 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
939 int32 iphase = (int32)phase; \
940 const float* table1 = bufData + iphase * bufChannels; \
941 int32 index = 0; \
942 for (uint32 channel=0; channel<numOutputs; ++channel) { \
943 OUT(channel)[SAMPLE_INDEX] = table1[index++]; \
947 void PlayBuf_Ctor(PlayBuf *unit)
949 if (INRATE(1) == calc_FullRate) {
950 if (INRATE(2) == calc_FullRate) {
951 SETCALC(PlayBuf_next_aa);
952 } else {
953 SETCALC(PlayBuf_next_ak);
955 } else {
956 if (INRATE(2) == calc_FullRate) {
957 SETCALC(PlayBuf_next_ka);
958 } else {
959 SETCALC(PlayBuf_next_kk);
963 unit->m_fbufnum = -1e9f;
964 unit->m_prevtrig = 0.;
965 unit->m_phase = ZIN0(3);
967 ClearUnitOutputs(unit, 1);
970 void PlayBuf_next_aa(PlayBuf *unit, int inNumSamples)
972 float *ratein = ZIN(1);
973 float *trigin = ZIN(2);
974 int32 loop = (int32)ZIN0(4);
976 float fbufnum = ZIN0(0);
977 if (fbufnum != unit->m_fbufnum) {
978 uint32 bufnum = (int)fbufnum;
979 World *world = unit->mWorld;
980 if (bufnum >= world->mNumSndBufs) bufnum = 0;
981 unit->m_fbufnum = fbufnum;
982 unit->m_buf = world->mSndBufs + bufnum;
984 const SndBuf *buf = unit->m_buf;
985 ACQUIRE_SNDBUF_SHARED(buf);
986 const float *bufData __attribute__((__unused__)) = buf->data;
987 uint32 bufChannels __attribute__((__unused__)) = buf->channels;
988 uint32 bufSamples __attribute__((__unused__)) = buf->samples;
989 uint32 bufFrames = buf->frames;
990 int mask __attribute__((__unused__)) = buf->mask;
991 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
993 int numOutputs = unit->mNumOutputs;
994 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
995 return;
997 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
998 double phase = unit->m_phase;
999 float prevtrig = unit->m_prevtrig;
1001 for (int i=0; i<inNumSamples; ++i) {
1002 float trig = ZXP(trigin);
1003 if (trig > 0.f && prevtrig <= 0.f) {
1004 unit->mDone = false;
1005 phase = ZIN0(3);
1007 prevtrig = trig;
1009 LOOP_BODY_4(i)
1011 phase += ZXP(ratein);
1013 RELEASE_SNDBUF_SHARED(buf);
1015 if(unit->mDone)
1016 DoneAction((int)ZIN0(5), unit);
1017 unit->m_phase = phase;
1018 unit->m_prevtrig = prevtrig;
1021 void PlayBuf_next_ak(PlayBuf *unit, int inNumSamples)
1023 float *ratein = ZIN(1);
1024 float trig = ZIN0(2);
1025 int32 loop = (int32)ZIN0(4);
1027 float fbufnum = ZIN0(0);
1028 if (fbufnum != unit->m_fbufnum) {
1029 uint32 bufnum = (int)fbufnum;
1030 World *world = unit->mWorld;
1031 if (bufnum >= world->mNumSndBufs) bufnum = 0;
1032 unit->m_fbufnum = fbufnum;
1033 unit->m_buf = world->mSndBufs + bufnum;
1035 const SndBuf *buf = unit->m_buf;
1036 ACQUIRE_SNDBUF_SHARED(buf);
1037 const float *bufData __attribute__((__unused__)) = buf->data;
1038 uint32 bufChannels __attribute__((__unused__)) = buf->channels;
1039 uint32 bufSamples __attribute__((__unused__)) = buf->samples;
1040 uint32 bufFrames = buf->frames;
1041 int mask __attribute__((__unused__)) = buf->mask;
1042 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
1044 int numOutputs = unit->mNumOutputs;
1045 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1046 return;
1048 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1049 double phase = unit->m_phase;
1050 if(phase == -1.) phase = bufFrames;
1051 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1052 unit->mDone = false;
1053 phase = ZIN0(3);
1055 unit->m_prevtrig = trig;
1056 for (int i=0; i<inNumSamples; ++i) {
1058 LOOP_BODY_4(i)
1060 phase += ZXP(ratein);
1062 RELEASE_SNDBUF_SHARED(buf);
1063 if(unit->mDone)
1064 DoneAction((int)ZIN0(5), unit);
1065 unit->m_phase = phase;
1068 void PlayBuf_next_kk(PlayBuf *unit, int inNumSamples)
1070 float rate = ZIN0(1);
1071 float trig = ZIN0(2);
1072 int32 loop = (int32)ZIN0(4);
1074 GET_BUF_SHARED
1075 int numOutputs = unit->mNumOutputs;
1076 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1077 return;
1079 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1080 double phase = unit->m_phase;
1081 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1082 unit->mDone = false;
1083 phase = ZIN0(3);
1085 unit->m_prevtrig = trig;
1086 for (int i=0; i<inNumSamples; ++i) {
1087 LOOP_BODY_4(i)
1089 phase += rate;
1091 if(unit->mDone)
1092 DoneAction((int)ZIN0(5), unit);
1093 unit->m_phase = phase;
1096 void PlayBuf_next_ka(PlayBuf *unit, int inNumSamples)
1098 float rate = ZIN0(1);
1099 float *trigin = ZIN(2);
1100 int32 loop = (int32)ZIN0(4);
1102 GET_BUF_SHARED
1103 int numOutputs = unit->mNumOutputs;
1104 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1105 return;
1107 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1108 double phase = unit->m_phase;
1109 float prevtrig = unit->m_prevtrig;
1110 for (int i=0; i<inNumSamples; ++i) {
1111 float trig = ZXP(trigin);
1112 if (trig > 0.f && prevtrig <= 0.f) {
1113 unit->mDone = false;
1114 if (INRATE(3) == calc_FullRate) phase = IN(3)[i];
1115 else phase = ZIN0(3);
1117 prevtrig = trig;
1119 LOOP_BODY_4(i)
1121 phase += rate;
1123 if(unit->mDone)
1124 DoneAction((int)ZIN0(5), unit);
1125 unit->m_phase = phase;
1126 unit->m_prevtrig = prevtrig;
1130 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1132 void BufRd_Ctor(BufRd *unit)
1134 int interp = (int)ZIN0(3);
1135 switch (interp) {
1136 case 1 : SETCALC(BufRd_next_1); break;
1137 case 2 : SETCALC(BufRd_next_2); break;
1138 default : SETCALC(BufRd_next_4); break;
1141 unit->m_fbufnum = -1e9f;
1143 BufRd_next_1(unit, 1);
1146 void BufRd_next_4(BufRd *unit, int inNumSamples)
1148 float *phasein = ZIN(1);
1149 int32 loop = (int32)ZIN0(2);
1151 GET_BUF_SHARED
1152 uint32 numOutputs = unit->mNumOutputs;
1153 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1154 return;
1156 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1158 for (int i=0; i<inNumSamples; ++i) {
1159 double phase = ZXP(phasein);
1160 LOOP_BODY_4(i)
1164 void BufRd_next_2(BufRd *unit, int inNumSamples)
1166 float *phasein = ZIN(1);
1167 int32 loop = (int32)ZIN0(2);
1169 GET_BUF_SHARED
1170 uint32 numOutputs = unit->mNumOutputs;
1171 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1172 return;
1174 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1176 for (int i=0; i<inNumSamples; ++i) {
1177 double phase = ZXP(phasein);
1178 LOOP_BODY_2(i)
1182 void BufRd_next_1(BufRd *unit, int inNumSamples)
1184 float *phasein = ZIN(1);
1185 int32 loop = (int32)ZIN0(2);
1187 GET_BUF_SHARED
1188 uint32 numOutputs = unit->mNumOutputs;
1189 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1190 return;
1192 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1194 for (int i=0; i<inNumSamples; ++i) {
1195 double phase = ZXP(phasein);
1196 LOOP_BODY_1(i)
1200 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1202 void BufWr_Ctor(BufWr *unit)
1204 SETCALC(BufWr_next);
1206 unit->m_fbufnum = -1e9f;
1208 ClearUnitOutputs(unit, 1);
1211 void BufWr_next(BufWr *unit, int inNumSamples)
1213 float *phasein = ZIN(1);
1214 int32 loop = (int32)ZIN0(2);
1216 GET_BUF
1217 uint32 numInputChannels = unit->mNumInputs - 3;
1218 if (!checkBuffer(unit, bufData, bufChannels, numInputChannels, inNumSamples))
1219 return;
1221 double loopMax = (double)(bufFrames - (loop ? 0 : 1));
1223 for (int32 k=0; k<inNumSamples; ++k) {
1224 double phase = sc_loop((Unit*)unit, ZXP(phasein), loopMax, loop);
1225 int32 iphase = (int32)phase;
1226 float* table0 = bufData + iphase * bufChannels;
1227 for (uint32 channel=0; channel<numInputChannels; ++channel)
1228 table0[channel] = IN(channel+3)[k];
1232 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1234 //bufnum=0, offset=0.0, recLevel=1.0, preLevel=0.0, run=1.0, loop=1.0, trigger=1.0
1236 void RecordBuf_Ctor(RecordBuf *unit)
1239 uint32 numInputs = unit->mNumInputs - 8;
1240 unit->m_fbufnum = -1e9f;
1241 unit->mIn = 0;
1242 unit->m_writepos = (int32)ZIN0(1) * numInputs;
1243 unit->m_recLevel = ZIN0(2);
1244 unit->m_preLevel = ZIN0(3);
1246 if (INRATE(2) == calc_ScalarRate && INRATE(3) == calc_ScalarRate
1247 && unit->m_recLevel == 1.0 && unit->m_preLevel == 0.0)
1249 SETCALC(RecordBuf_next_10);
1250 } else {
1251 SETCALC(RecordBuf_next);
1254 ClearUnitOutputs(unit, 1);
1257 void RecordBuf_Dtor(RecordBuf *unit)
1259 TAKEDOWN_IN
1262 void RecordBuf_next(RecordBuf *unit, int inNumSamples)
1264 //printf("RecordBuf_next\n");
1265 GET_BUF
1266 CHECK_BUF
1267 SETUP_IN(8)
1269 float recLevel = ZIN0(2);
1270 float preLevel = ZIN0(3);
1271 float run = ZIN0(4);
1272 int32 loop = (int32)ZIN0(5);
1273 float trig = ZIN0(6);
1274 //printf("loop %d run %g\n", loop, run);
1276 int32 writepos = unit->m_writepos;
1278 float recLevel_slope = CALCSLOPE(recLevel, unit->m_recLevel);
1279 float preLevel_slope = CALCSLOPE(preLevel, unit->m_preLevel);
1281 /* reset recLevel and preLevel to use the previous value ... bug fix */
1282 recLevel = unit->m_recLevel;
1283 preLevel = unit->m_preLevel;
1285 if (loop) {
1286 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1287 unit->mDone = false;
1288 writepos = (int32)ZIN0(1) * bufChannels;
1290 if (writepos < 0) writepos = bufSamples - bufChannels;
1291 else if (writepos >= (int32)bufSamples) writepos = 0;
1292 if (run > 0.f) {
1293 if (bufChannels == 1) {
1294 for (int32 k=0; k<inNumSamples; ++k) {
1295 float* table0 = bufData + writepos;
1296 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1297 writepos += 1;
1298 if (writepos >= (int32)bufSamples) writepos = 0;
1300 recLevel += recLevel_slope;
1301 preLevel += preLevel_slope;
1303 } else if (bufChannels == 2 && numInputs == 2) {
1304 for (int32 k=0; k<inNumSamples; ++k) {
1305 float* table0 = bufData + writepos;
1306 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1307 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1308 writepos += 2;
1309 if (writepos >= (int32)bufSamples) writepos = 0;
1311 recLevel += recLevel_slope;
1312 preLevel += preLevel_slope;
1314 } else {
1315 for (int32 k=0; k<inNumSamples; ++k) {
1316 float* table0 = bufData + writepos;
1317 for (uint32 i=0; i<numInputs; ++i) {
1318 float *samp = table0 + i;
1319 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1321 writepos += bufChannels;
1322 if (writepos >= (int32)bufSamples) writepos = 0;
1324 recLevel += recLevel_slope;
1325 preLevel += preLevel_slope;
1328 } else if (run < 0.f) {
1329 if (bufChannels == 1) {
1330 for (int32 k=0; k<inNumSamples; ++k) {
1331 float* table0 = bufData + writepos;
1332 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1333 writepos -= 1;
1334 if (writepos < 0) writepos = bufSamples - bufChannels;
1336 recLevel += recLevel_slope;
1337 preLevel += preLevel_slope;
1339 } else if (bufChannels == 2 && numInputs == 2) {
1340 for (int32 k=0; k<inNumSamples; ++k) {
1341 float* table0 = bufData + writepos;
1342 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1343 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1344 writepos -= 2;
1345 if (writepos < 0) writepos = bufSamples - bufChannels;
1347 recLevel += recLevel_slope;
1348 preLevel += preLevel_slope;
1350 } else {
1351 for (int32 k=0; k<inNumSamples; ++k) {
1352 float* table0 = bufData + writepos;
1353 for (uint32 i=0; i<numInputs; ++i) {
1354 float *samp = table0 + i;
1355 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1357 writepos -= bufChannels;
1358 if (writepos < 0) writepos = bufSamples - bufChannels;
1360 recLevel += recLevel_slope;
1361 preLevel += preLevel_slope;
1365 } else {
1366 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1367 unit->mDone = false;
1368 writepos = (int32)ZIN0(1) * bufChannels;
1370 if (run > 0.f) {
1371 int nsmps = bufSamples - writepos;
1372 nsmps = sc_clip(nsmps, 0, inNumSamples);
1373 if (bufChannels == 1) {
1374 for (int32 k=0; k<nsmps; ++k) {
1375 float* table0 = bufData + writepos;
1376 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1377 writepos += 1;
1379 recLevel += recLevel_slope;
1380 preLevel += preLevel_slope;
1382 } else if (bufChannels == 2 && numInputs == 2) {
1383 for (int32 k=0; k<nsmps; ++k) {
1384 float* table0 = bufData + writepos;
1385 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1386 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1387 writepos += 2;
1389 recLevel += recLevel_slope;
1390 preLevel += preLevel_slope;
1392 } else {
1393 for (int32 k=0; k<nsmps; ++k) {
1394 float* table0 = bufData + writepos;
1395 for (uint32 i=0; i<numInputs; ++i) {
1396 float *samp = table0 + i;
1397 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1399 writepos += bufChannels;
1401 recLevel += recLevel_slope;
1402 preLevel += preLevel_slope;
1405 } else if (run < 0.f) {
1406 int nsmps = writepos;
1407 nsmps = sc_clip(nsmps, 0, inNumSamples);
1408 if (bufChannels == 1) {
1409 for (int32 k=0; k<inNumSamples; ++k) {
1410 float* table0 = bufData + writepos;
1411 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1412 writepos -= bufChannels;
1414 recLevel += recLevel_slope;
1415 preLevel += preLevel_slope;
1417 } else if (bufChannels == 2 && numInputs == 2) {
1418 for (int32 k=0; k<inNumSamples; ++k) {
1419 float* table0 = bufData + writepos;
1420 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1421 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1422 writepos -= bufChannels;
1424 recLevel += recLevel_slope;
1425 preLevel += preLevel_slope;
1427 } else {
1428 for (int32 k=0; k<inNumSamples; ++k) {
1429 float* table0 = bufData + writepos;
1430 for (uint32 i=0; i<numInputs; ++i) {
1431 float *samp = table0 + i;
1432 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1434 writepos -= bufChannels;
1436 recLevel += recLevel_slope;
1437 preLevel += preLevel_slope;
1441 if (writepos >= (int32)bufSamples){
1442 unit->mDone = true;
1443 DoneAction(IN0(7), unit);
1446 unit->m_prevtrig = trig;
1447 unit->m_writepos = writepos;
1448 unit->m_recLevel = recLevel;
1449 unit->m_preLevel = preLevel;
1452 void RecordBuf_next_10(RecordBuf *unit, int inNumSamples)
1454 // printf("RecordBuf_next_10\n");
1455 GET_BUF
1456 CHECK_BUF
1457 SETUP_IN(8)
1459 float run = ZIN0(4);
1460 int32 loop = (int32)ZIN0(5);
1461 float trig = ZIN0(6);
1462 //printf("loop %d run %g\n", loop, run);
1464 int32 writepos = unit->m_writepos;
1466 if (loop) {
1467 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1468 unit->mDone = false;
1469 writepos = (int32)ZIN0(1) * bufChannels;
1471 if (writepos < 0) writepos = bufSamples - bufChannels;
1472 else if (writepos >= (int32)bufSamples) writepos = 0;
1473 if (run > 0.f) {
1474 if (bufChannels == 1) {
1475 for (int32 k=0; k<inNumSamples; ++k) {
1476 float* table0 = bufData + writepos;
1477 table0[0] = *++(in[0]);
1478 writepos += 1;
1479 if (writepos >= (int32)bufSamples) writepos = 0;
1481 } else if (bufChannels == 2) {
1482 for (int32 k=0; k<inNumSamples; ++k) {
1483 float* table0 = bufData + writepos;
1484 table0[0] = *++(in[0]);
1485 table0[1] = *++(in[1]);
1486 writepos += 2;
1487 if (writepos >= (int32)bufSamples) writepos = 0;
1489 } else {
1490 for (int32 k=0; k<inNumSamples; ++k) {
1491 float* table0 = bufData + writepos;
1492 for (uint32 i=0; i<bufChannels; ++i) {
1493 float *samp = table0 + i;
1494 *samp = *++(in[i]);
1496 writepos += bufChannels;
1497 if (writepos >= (int32)bufSamples) writepos = 0;
1500 } else if (run < 0.f) {
1501 if (bufChannels == 1) {
1502 for (int32 k=0; k<inNumSamples; ++k) {
1503 float* table0 = bufData + writepos;
1504 table0[0] = *++(in[0]);
1505 writepos -= 1;
1506 if (writepos < 0) writepos = bufSamples - bufChannels;
1508 } else if (bufChannels == 2) {
1509 for (int32 k=0; k<inNumSamples; ++k) {
1510 float* table0 = bufData + writepos;
1511 table0[0] = *++(in[0]);
1512 table0[1] = *++(in[1]);
1513 writepos -= 2;
1514 if (writepos < 0) writepos = bufSamples - bufChannels;
1516 } else {
1517 for (int32 k=0; k<inNumSamples; ++k) {
1518 float* table0 = bufData + writepos;
1519 for (uint32 i=0; i<bufChannels; ++i) {
1520 float *samp = table0 + i;
1521 *samp = *++(in[i]);
1523 writepos -= bufChannels;
1524 if (writepos < 0) writepos = bufSamples - bufChannels;
1528 } else {
1529 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1530 unit->mDone = false;
1531 writepos = (int32)ZIN0(1) * bufChannels;
1533 if (run > 0.f) {
1534 int nsmps = bufSamples - writepos;
1535 nsmps = sc_clip(nsmps, 0, inNumSamples);
1536 if (bufChannels == 1) {
1537 for (int32 k=0; k<nsmps; ++k) {
1538 float* table0 = bufData + writepos;
1539 table0[0] = *++(in[0]);
1540 writepos += 1;
1542 } else if (bufChannels == 2) {
1543 for (int32 k=0; k<nsmps; ++k) {
1544 float* table0 = bufData + writepos;
1545 table0[0] = *++(in[0]);
1546 table0[1] = *++(in[1]);
1547 writepos += 2;
1548 if (writepos >= (int32)bufSamples) writepos = (int32)bufSamples - 2; // added by jrhb
1550 } else {
1551 for (int32 k=0; k<nsmps; ++k) {
1552 float* table0 = bufData + writepos;
1553 for (uint32 i=0; i<bufChannels; ++i) {
1554 float *samp = table0 + i;
1555 *samp = *++(in[i]);
1557 writepos += bufChannels;
1558 if (writepos >= (int32)bufSamples) writepos = (int32)bufSamples - bufChannels; // added by jrhb
1561 } else if (run < 0.f) {
1562 int nsmps = writepos;
1563 nsmps = sc_clip(nsmps, 0, inNumSamples);
1564 if (bufChannels == 1) {
1565 for (int32 k=0; k<inNumSamples; ++k) {
1566 float* table0 = bufData + writepos;
1567 table0[0] = *++(in[0]);
1568 writepos -= 1;
1570 } else if (bufChannels == 2) {
1571 for (int32 k=0; k<inNumSamples; ++k) {
1572 float* table0 = bufData + writepos;
1573 table0[0] = *++(in[0]);
1574 table0[1] = *++(in[1]);
1575 writepos -= 2;
1577 } else {
1578 for (int32 k=0; k<inNumSamples; ++k) {
1579 float* table0 = bufData + writepos;
1580 for (uint32 i=0; i<bufChannels; ++i) {
1581 float *samp = table0 + i;
1582 *samp = *++(in[i]);
1584 writepos -= bufChannels;
1588 if (writepos >= (int32)bufSamples){
1589 unit->mDone = true;
1590 DoneAction(IN0(7), unit);
1593 unit->m_prevtrig = trig;
1594 unit->m_writepos = writepos;
1598 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1600 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1604 static float insertMedian(float* values, int* ages, int size, float value)
1606 int pos=-1;
1608 // keeps a sorted list of the previous n=size values
1609 // the oldest is removed and the newest is inserted.
1610 // values between the oldest and the newest are shifted over by one.
1612 // values and ages are both arrays that are 'size' int.
1613 // the median value is always values[size>>1]
1615 int last = size - 1;
1616 // find oldest bin and age the other bins.
1617 for (int i=0; i<size; ++i) {
1618 if (ages[i] == last) { // is it the oldest bin ?
1619 pos = i;
1620 } else {
1621 ages[i]++; // age the bin
1624 // move values to fill in place of the oldest and make a space for the newest
1625 // search lower if value is too small for the open space
1626 while (pos != 0 && value < values[pos-1]) {
1627 values[pos] = values[pos-1];
1628 ages[pos] = ages[pos-1];
1629 pos--;
1631 // search higher if value is too big for the open space
1632 while (pos != last && value > values[pos+1]) {
1633 values[pos] = values[pos+1];
1634 ages[pos] = ages[pos+1];
1635 pos++;
1637 values[pos] = value;
1638 ages[pos] = 0; // this is the newest bin, age = 0
1639 return values[size>>1];
1642 static void initMedian(float* values, int* ages, int size, float value)
1644 // initialize the arrays with the first value
1645 for (int i=0; i<size; ++i) {
1646 values[i] = value;
1647 ages[i] = i;
1654 enum {
1655 kPitchIn,
1656 kPitchInitFreq,
1657 kPitchMinFreq,
1658 kPitchMaxFreq,
1659 kPitchExecFreq,
1660 kPitchMaxBins,
1661 kPitchMedian,
1662 kPitchAmpThreshold,
1663 kPitchPeakThreshold,
1664 kPitchDownsamp,
1665 kPitchGetClarity
1668 void Pitch_Ctor(Pitch *unit)
1670 unit->m_freq = ZIN0(kPitchInitFreq);
1671 unit->m_minfreq = ZIN0(kPitchMinFreq);
1672 unit->m_maxfreq = ZIN0(kPitchMaxFreq);
1674 float execfreq = ZIN0(kPitchExecFreq);
1675 execfreq = sc_clip(execfreq, unit->m_minfreq, unit->m_maxfreq);
1677 int maxbins = (int)ZIN0(kPitchMaxBins);
1678 unit->m_maxlog2bins = LOG2CEIL(maxbins);
1680 unit->m_medianSize = sc_clip((int)ZIN0(0), 0, kMAXMEDIANSIZE); // (int)ZIN0(kPitchMedian);
1681 unit->m_ampthresh = ZIN0(kPitchAmpThreshold);
1682 unit->m_peakthresh = ZIN0(kPitchPeakThreshold);
1684 int downsamp = (int)ZIN0(kPitchDownsamp);
1686 if (INRATE(kPitchIn) == calc_FullRate) {
1687 SETCALC(Pitch_next_a);
1688 unit->m_downsamp = sc_clip(downsamp, 1, unit->mWorld->mFullRate.mBufLength);
1689 unit->m_srate = FULLRATE / (float)unit->m_downsamp;
1690 } else {
1691 SETCALC(Pitch_next_k);
1692 unit->m_downsamp = sc_max(downsamp, 1);
1693 unit->m_srate = FULLRATE / (float) (unit->mWorld->mFullRate.mBufLength*unit->m_downsamp);
1696 unit->m_minperiod = (long)(unit->m_srate / unit->m_maxfreq);
1697 unit->m_maxperiod = (long)(unit->m_srate / unit->m_minfreq);
1699 unit->m_execPeriod = (int)(unit->m_srate / execfreq);
1700 unit->m_execPeriod = sc_max(unit->m_execPeriod, unit->mWorld->mFullRate.mBufLength);
1702 unit->m_size = sc_max(unit->m_maxperiod << 1, unit->m_execPeriod);
1704 unit->m_buffer = (float*)RTAlloc(unit->mWorld, unit->m_size * sizeof(float));
1706 unit->m_index = 0;
1707 unit->m_readp = 0;
1708 unit->m_hasfreq = 0.f;
1710 initMedian(unit->m_values, unit->m_ages, unit->m_medianSize, unit->m_freq);
1712 unit->m_getClarity = ZIN0(kPitchGetClarity) > 0.f;
1714 ZOUT0(0) = 0.f;
1715 ZOUT0(1) = 0.f;
1718 void Pitch_Dtor(Pitch *unit)
1720 RTFree(unit->mWorld, unit->m_buffer);
1723 void Pitch_next_a(Pitch *unit, int inNumSamples)
1725 bool foundPeak;
1727 float* in = ZIN(kPitchIn);
1728 uint32 size = unit->m_size;
1729 uint32 index = unit->m_index;
1730 int downsamp = unit->m_downsamp;
1731 int readp = unit->m_readp;
1732 int ksamps = unit->mWorld->mFullRate.mBufLength;
1734 float *bufData = unit->m_buffer;
1736 float freq = unit->m_freq;
1737 float hasfreq = unit->m_hasfreq;
1738 //printf("> %d %d readp %d ksamps %d ds %d\n", index, size, readp, ksamps, downsamp);
1739 do {
1740 float z = in[readp];
1741 bufData[index++] = z;
1742 readp += downsamp;
1744 if (index >= size) {
1745 float ampthresh = unit->m_ampthresh;
1746 bool ampok = false;
1748 hasfreq = 0.f; // assume failure
1750 int minperiod = unit->m_minperiod;
1751 int maxperiod = unit->m_maxperiod;
1752 //float maxamp = 0.f;
1753 // check for amp threshold
1754 for (int j = 0; j < maxperiod; ++j) {
1755 if (fabs(bufData[j]) >= ampthresh) {
1756 ampok = true;
1757 break;
1759 //if (fabs(bufData[j]) > maxamp) maxamp = fabs(bufData[j]);
1761 //printf("ampok %d maxperiod %d maxamp %g\n", ampok, maxperiod, maxamp);
1763 // if amplitude is too small then don't even look for pitch
1764 float ampsum;
1765 if (ampok) {
1766 int maxlog2bins = unit->m_maxlog2bins;
1767 int octave;
1768 // calculate the zero lag value and compute the threshold based on that
1769 float zerolagval = 0.f;
1770 for (int j = 0; j < maxperiod; ++j) {
1771 zerolagval += bufData[j] * bufData[j];
1773 float threshold = zerolagval * unit->m_peakthresh;
1775 // skip until drop below threshold
1776 int binstep, peakbinstep = 0;
1777 int i;
1778 for (i = 1; i <= maxperiod; i += binstep) {
1779 // compute sum of one lag
1780 ampsum = 0.f;
1781 for (int j = 0; j < maxperiod; ++j) {
1782 ampsum += bufData[i+j] * bufData[j];
1784 if (ampsum < threshold) break;
1786 octave = LOG2CEIL(i);
1787 if (octave <= maxlog2bins) {
1788 binstep = 1;
1789 } else {
1790 binstep = 1L << (octave - maxlog2bins);
1793 int startperiod = i;
1794 int period = startperiod;
1795 //printf("startperiod %d\n", startperiod);
1797 // find the first peak
1798 float maxsum = threshold;
1799 foundPeak = false;
1800 for (i = startperiod; i <= maxperiod; i += binstep) {
1801 if (i >= minperiod) {
1802 ampsum = 0.f;
1803 for (int j = 0; j < maxperiod; ++j) {
1804 ampsum += bufData[i+j] * bufData[j];
1806 if (ampsum > threshold) {
1807 if (ampsum > maxsum) {
1808 foundPeak = true;
1809 maxsum = ampsum;
1810 peakbinstep = binstep;
1811 period = i;
1813 } else if (foundPeak) break;
1815 octave = LOG2CEIL(i);
1816 if (octave <= maxlog2bins) {
1817 binstep = 1;
1818 } else {
1819 binstep = 1L << (octave - maxlog2bins);
1823 //printf("found %d thr %g maxs %g per %d bs %d\n", foundPeak, threshold, maxsum, period, peakbinstep);
1824 if (foundPeak) {
1825 float prevampsum, nextampsum;
1827 // find amp sums immediately surrounding max
1828 prevampsum = 0.f;
1829 if (period > 0) {
1830 i = period - 1;
1831 for (int j = 0; j < maxperiod; ++j) {
1832 prevampsum += bufData[i+j] * bufData[j];
1836 nextampsum = 0.f;
1837 if (period < maxperiod) {
1838 i = period + 1;
1839 for (int j = 0; j < maxperiod; ++j) {
1840 nextampsum += bufData[i+j] * bufData[j];
1844 //printf("prevnext %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1845 // not on a peak yet. This can happen if binstep > 1
1846 while (prevampsum > maxsum && period > 0) {
1847 nextampsum = maxsum;
1848 maxsum = prevampsum;
1849 period--;
1850 i = period - 1;
1851 prevampsum = 0.f;
1852 for (int j = 0; j < maxperiod; ++j) {
1853 prevampsum += bufData[i+j] * bufData[j];
1855 //printf("slide left %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1857 while (nextampsum > maxsum && period < maxperiod) {
1858 prevampsum = maxsum;
1859 maxsum = nextampsum;
1860 period++;
1861 i = period + 1;
1862 nextampsum = 0.f;
1863 for (int j = 0; j < maxperiod; ++j) {
1864 nextampsum += bufData[i+j] * bufData[j];
1866 //printf("slide right %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1869 // make a fractional period
1870 float beta = 0.5f * (nextampsum - prevampsum);
1871 float gamma = 2.f * maxsum - nextampsum - prevampsum;
1872 float fperiod = (float)period + (beta/gamma);
1874 // calculate frequency
1875 float tempfreq = unit->m_srate / fperiod;
1877 //printf("freq %g %g / %g %g %g %d\n", tempfreq, unit->m_srate, fperiod,
1878 // unit->m_minfreq, unit->m_maxfreq,
1879 // tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq);
1881 if (tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq) {
1882 freq = tempfreq;
1884 // median filter
1885 if (unit->m_medianSize > 1) {
1886 freq = insertMedian(unit->m_values, unit->m_ages, unit->m_medianSize, freq);
1888 if(unit->m_getClarity)
1889 hasfreq = maxsum / zerolagval; // "clarity" measure is normalised size of first peak
1890 else
1891 hasfreq = 1.f;
1893 startperiod = (ksamps+downsamp-1)/downsamp;
1896 }/* else {
1897 printf("amp too low \n");
1900 // shift buffer for next fill
1901 int execPeriod = unit->m_execPeriod;
1902 int interval = size - execPeriod;
1903 //printf("interval %d sz %d ep %d\n", interval, size, execPeriod);
1904 for (int i = 0; i < interval; i++) {
1905 bufData[i] = bufData[i + execPeriod];
1907 index = interval;
1909 } while (readp < ksamps);
1911 ZOUT0(0) = freq;
1912 ZOUT0(1) = hasfreq;
1913 unit->m_readp = readp - ksamps;
1914 unit->m_index = index;
1915 unit->m_freq = freq;
1916 unit->m_hasfreq = hasfreq;
1920 // control rate pitch tracking (nescivi 11/2008)
1921 void Pitch_next_k(Pitch *unit, int inNumSamples)
1923 bool foundPeak;
1925 float in = ZIN0(kPitchIn); // one sample, current input
1926 uint32 size = unit->m_size;
1927 uint32 index = unit->m_index;
1928 int downsamp = unit->m_downsamp;
1929 int readp = unit->m_readp;
1930 // int ksamps = unit->mWorld->mFullRate.mBufLength;
1932 float *bufData = unit->m_buffer;
1934 float freq = unit->m_freq;
1935 float hasfreq = unit->m_hasfreq;
1936 // printf("> %d %d readp %d downsamp %d exec %d\n", index, size, readp, downsamp, unit->m_execPeriod);
1937 readp++;
1938 if ( readp == downsamp ){
1939 // do {
1940 // float z = in[readp];
1941 float z = in;
1942 bufData[index++] = z;
1943 readp = 0;
1944 // readp += downsamp;
1946 if (index >= size) {
1947 float ampthresh = unit->m_ampthresh;
1948 bool ampok = false;
1950 hasfreq = 0.f; // assume failure
1952 int minperiod = unit->m_minperiod;
1953 int maxperiod = unit->m_maxperiod;
1954 //float maxamp = 0.f;
1955 // check for amp threshold
1956 for (int j = 0; j < maxperiod; ++j) {
1957 if (fabs(bufData[j]) >= ampthresh) {
1958 ampok = true;
1959 break;
1961 //if (fabs(bufData[j]) > maxamp) maxamp = fabs(bufData[j]);
1963 //printf("ampok %d maxperiod %d maxamp %g\n", ampok, maxperiod, maxamp);
1965 // if amplitude is too small then don't even look for pitch
1966 float ampsum;
1967 if (ampok) {
1968 int maxlog2bins = unit->m_maxlog2bins;
1969 int octave;
1970 // calculate the zero lag value and compute the threshold based on that
1971 float zerolagval = 0.f;
1972 for (int j = 0; j < maxperiod; ++j) {
1973 zerolagval += bufData[j] * bufData[j];
1975 float threshold = zerolagval * unit->m_peakthresh;
1977 // skip until drop below threshold
1978 int binstep, peakbinstep = 0;
1979 int i;
1980 for (i = 1; i <= maxperiod; i += binstep) {
1981 // compute sum of one lag
1982 ampsum = 0.f;
1983 for (int j = 0; j < maxperiod; ++j) {
1984 ampsum += bufData[i+j] * bufData[j];
1986 if (ampsum < threshold) break;
1988 octave = LOG2CEIL(i);
1989 if (octave <= maxlog2bins) {
1990 binstep = 1;
1991 } else {
1992 binstep = 1L << (octave - maxlog2bins);
1995 int startperiod = i;
1996 int period = startperiod;
1997 //printf("startperiod %d\n", startperiod);
1999 // find the first peak
2000 float maxsum = threshold;
2001 foundPeak = false;
2002 for (i = startperiod; i <= maxperiod; i += binstep) {
2003 if (i >= minperiod) {
2004 ampsum = 0.f;
2005 for (int j = 0; j < maxperiod; ++j) {
2006 ampsum += bufData[i+j] * bufData[j];
2008 if (ampsum > threshold) {
2009 if (ampsum > maxsum) {
2010 foundPeak = true;
2011 maxsum = ampsum;
2012 peakbinstep = binstep;
2013 period = i;
2015 } else if (foundPeak) break;
2017 octave = LOG2CEIL(i);
2018 if (octave <= maxlog2bins) {
2019 binstep = 1;
2020 } else {
2021 binstep = 1L << (octave - maxlog2bins);
2025 //printf("found %d thr %g maxs %g per %d bs %d\n", foundPeak, threshold, maxsum, period, peakbinstep);
2026 if (foundPeak) {
2027 float prevampsum, nextampsum;
2029 // find amp sums immediately surrounding max
2030 prevampsum = 0.f;
2031 if (period > 0) {
2032 i = period - 1;
2033 for (int j = 0; j < maxperiod; ++j) {
2034 prevampsum += bufData[i+j] * bufData[j];
2038 nextampsum = 0.f;
2039 if (period < maxperiod) {
2040 i = period + 1;
2041 for (int j = 0; j < maxperiod; ++j) {
2042 nextampsum += bufData[i+j] * bufData[j];
2046 //printf("prevnext %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2047 // not on a peak yet. This can happen if binstep > 1
2048 while (prevampsum > maxsum && period > 0) {
2049 nextampsum = maxsum;
2050 maxsum = prevampsum;
2051 period--;
2052 i = period - 1;
2053 prevampsum = 0.f;
2054 for (int j = 0; j < maxperiod; ++j) {
2055 prevampsum += bufData[i+j] * bufData[j];
2057 //printf("slide left %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2059 while (nextampsum > maxsum && period < maxperiod) {
2060 prevampsum = maxsum;
2061 maxsum = nextampsum;
2062 period++;
2063 i = period + 1;
2064 nextampsum = 0.f;
2065 for (int j = 0; j < maxperiod; ++j) {
2066 nextampsum += bufData[i+j] * bufData[j];
2068 //printf("slide right %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2071 // make a fractional period
2072 float beta = 0.5 * (nextampsum - prevampsum);
2073 float gamma = 2.0 * maxsum - nextampsum - prevampsum;
2074 float fperiod = (float)period + (beta/gamma);
2076 // calculate frequency
2077 float tempfreq = unit->m_srate / fperiod;
2079 //printf("freq %g %g / %g %g %g %d\n", tempfreq, unit->m_srate, fperiod,
2080 // unit->m_minfreq, unit->m_maxfreq,
2081 // tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq);
2083 if (tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq) {
2084 freq = tempfreq;
2086 // median filter
2087 if (unit->m_medianSize > 1) {
2088 freq = insertMedian(unit->m_values, unit->m_ages, unit->m_medianSize, freq);
2090 if(unit->m_getClarity)
2091 hasfreq = maxsum / zerolagval; // "clarity" measure is normalised size of first peak
2092 else
2093 hasfreq = 1.f;
2095 // nescivi: not sure about this one?
2096 startperiod = 1; // (ksamps+downsamp-1)/downsamp;
2099 }/* else {
2100 printf("amp too low \n");
2103 // shift buffer for next fill
2104 int execPeriod = unit->m_execPeriod;
2105 int interval = size - execPeriod;
2106 //printf("interval %d sz %d ep %d\n", interval, size, execPeriod);
2107 for (int i = 0; i < interval; i++) {
2108 bufData[i] = bufData[i + execPeriod];
2110 index = interval;
2113 //while (readp < ksamps);
2115 ZOUT0(0) = freq;
2116 ZOUT0(1) = hasfreq;
2117 // unit->m_readp = readp - ksamps;
2118 unit->m_readp = readp;
2119 unit->m_index = index;
2120 unit->m_freq = freq;
2121 unit->m_hasfreq = hasfreq;
2124 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2127 #if 0
2128 void DelayUnit_AllocDelayLine(DelayUnit *unit)
2130 long delaybufsize = (long)ceil(unit->m_maxdelaytime * SAMPLERATE + 1.f);
2131 delaybufsize = delaybufsize + BUFLENGTH;
2132 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
2133 unit->m_fdelaylen = unit->m_idelaylen = delaybufsize;
2135 RTFree(unit->mWorld, unit->m_dlybuf);
2136 int size = delaybufsize * sizeof(float);
2137 //Print("->RTAlloc %d\n", size);
2138 unit->m_dlybuf = (float*)RTAlloc(unit->mWorld, size);
2139 //Print("<-RTAlloc %p\n", unit->m_dlybuf);
2140 unit->m_mask = delaybufsize - 1;
2142 #endif
2145 template <typename Unit>
2146 static float BufCalcDelay(const Unit * unit, int bufSamples, float delayTime)
2148 float minDelay = Unit::minDelaySamples;
2149 return sc_clip(delayTime * (float)SAMPLERATE, minDelay, (float)(PREVIOUSPOWEROFTWO(bufSamples))-1);
2152 template <typename Unit>
2153 static void BufDelayUnit_Reset(Unit *unit)
2155 //Print("->DelayUnit_Reset\n");
2156 //unit->m_maxdelaytime = ZIN0(1);
2157 unit->m_delaytime = ZIN0(2);
2158 //Print("unit->m_delaytime %g\n", unit->m_delaytime);
2159 //unit->m_dlybuf = 0;
2160 unit->m_fbufnum = -1e9f;
2162 //DelayUnit_AllocDelayLine(unit);
2163 //Print("->GET_BUF\n");
2164 GET_BUF
2165 //Print("<-GET_BUF\n");
2166 unit->m_dsamp = BufCalcDelay(unit, bufSamples, unit->m_delaytime);
2167 unit->m_numoutput = 0;
2168 unit->m_iwrphase = 0;
2171 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2173 template <typename Unit>
2174 static void BufFeedbackDelay_Reset(Unit *unit)
2176 BufDelayUnit_Reset(unit);
2178 unit->m_decaytime = ZIN0(3);
2179 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
2182 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2184 namespace {
2186 /* helper classes for delay functionality */
2187 template <bool Checked = false>
2188 struct DelayN_helper
2190 static const bool checked = false;
2192 static inline void perform(const float *& in, float *& out, float * bufData,
2193 long & iwrphase, long idsamp, long mask)
2195 long irdphase = iwrphase - idsamp;
2196 bufData[iwrphase & mask] = ZXP(in);
2197 ZXP(out) = bufData[irdphase & mask];
2198 iwrphase++;
2201 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2202 static inline void perform(const float *& in, float *& out, float * bufData,
2203 long & iwrphase, long idsamp, float frac, long mask)
2205 perform(in, out, bufData, iwrphase, idsamp, mask);
2209 template <>
2210 struct DelayN_helper<true>
2212 static const bool checked = true;
2214 static inline void perform(const float *& in, float *& out, float * bufData,
2215 long & iwrphase, long idsamp, long mask)
2217 long irdphase = iwrphase - idsamp;
2219 bufData[iwrphase & mask] = ZXP(in);
2220 if (irdphase < 0)
2221 ZXP(out) = 0.f;
2222 else
2223 ZXP(out) = bufData[irdphase & mask];
2225 iwrphase++;
2228 static inline void perform(const float *& in, float *& out, float * bufData,
2229 long & iwrphase, long idsamp, float frac, long mask)
2231 perform(in, out, bufData, iwrphase, idsamp, mask);
2235 template <bool initializing>
2236 static inline void DelayN_delay_loop(float * out, const float * in, long & iwrphase, float dsamp, long mask,
2237 float * dlybuf, int inNumSamples, int idelaylen)
2239 long irdphase = iwrphase - (long)dsamp;
2240 float* dlybuf1 = dlybuf - ZOFF;
2241 float* dlyrd = dlybuf1 + (irdphase & mask);
2242 float* dlywr = dlybuf1 + (iwrphase & mask);
2243 float* dlyN = dlybuf1 + idelaylen;
2244 long remain = inNumSamples;
2245 while (remain) {
2246 long rdspace = dlyN - dlyrd;
2247 long wrspace = dlyN - dlywr;
2248 if (initializing) {
2249 long nsmps = sc_min(rdspace, wrspace);
2250 nsmps = sc_min(remain, nsmps);
2251 remain -= nsmps;
2252 if (irdphase < 0) {
2253 if ((dlywr - dlyrd) > nsmps) {
2254 #ifdef NOVA_SIMD
2255 if ((nsmps & (nova::vec<float>::size - 1)) == 0) {
2256 nova::copyvec_nn_simd(dlywr + ZOFF, in + ZOFF, nsmps);
2257 nova::zerovec_na_simd(out + ZOFF, nsmps);
2258 } else
2259 #endif
2261 ZCopy(nsmps, dlywr, in);
2262 ZClear(nsmps, out);
2264 out += nsmps;
2265 in += nsmps;
2266 dlyrd += nsmps;
2267 dlywr += nsmps;
2268 } else
2269 LOOP(nsmps,
2270 ZXP(dlywr) = ZXP(in);
2271 ZXP(out) = 0.f;
2273 } else {
2274 LOOP(nsmps,
2275 ZXP(dlywr) = ZXP(in);
2276 ZXP(out) = ZXP(dlyrd);
2279 irdphase += nsmps;
2280 if (dlyrd == dlyN) dlyrd = dlybuf1;
2281 if (dlywr == dlyN) dlywr = dlybuf1;
2283 else {
2284 long nsmps = sc_min(rdspace, wrspace);
2285 nsmps = sc_min(remain, nsmps);
2286 remain -= nsmps;
2288 if (std::abs((float)(dlyrd - dlywr)) > nsmps) {
2289 #ifdef NOVA_SIMD
2290 if ((nsmps & 15) == 0) {
2291 nova::copyvec_nn_simd(dlywr + ZOFF, in + ZOFF, nsmps);
2292 nova::copyvec_nn_simd(out + ZOFF, dlyrd + ZOFF, nsmps);
2293 } else
2294 #endif
2296 ZCopy(nsmps, dlywr, in);
2297 ZCopy(nsmps, out, dlyrd);
2299 out += nsmps;
2300 in += nsmps;
2301 dlyrd += nsmps;
2302 dlywr += nsmps;
2303 } else
2304 LOOP(nsmps,
2305 ZXP(dlywr) = ZXP(in);
2306 ZXP(out) = ZXP(dlyrd);
2308 if (dlyrd == dlyN) dlyrd = dlybuf1;
2309 if (dlywr == dlyN) dlywr = dlybuf1;
2312 iwrphase += inNumSamples;
2316 template <bool Checked = false>
2317 struct DelayL_helper
2319 static const bool checked = false;
2321 static inline void perform(const float *& in, float *& out, float * bufData,
2322 long & iwrphase, long idsamp, float frac, long mask)
2324 bufData[iwrphase & mask] = ZXP(in);
2325 long irdphase = iwrphase - idsamp;
2326 long irdphaseb = irdphase - 1;
2327 float d1 = bufData[irdphase & mask];
2328 float d2 = bufData[irdphaseb & mask];
2329 ZXP(out) = lininterp(frac, d1, d2);
2330 iwrphase++;
2334 template <>
2335 struct DelayL_helper<true>
2337 static const bool checked = true;
2339 static inline void perform(const float *& in, float *& out, float * bufData,
2340 long & iwrphase, long idsamp, float frac, long mask)
2342 bufData[iwrphase & mask] = ZXP(in);
2343 long irdphase = iwrphase - idsamp;
2344 long irdphaseb = irdphase - 1;
2346 if (irdphase < 0) {
2347 ZXP(out) = 0.f;
2348 } else if (irdphaseb < 0) {
2349 float d1 = bufData[irdphase & mask];
2350 ZXP(out) = d1 - frac * d1;
2351 } else {
2352 float d1 = bufData[irdphase & mask];
2353 float d2 = bufData[irdphaseb & mask];
2354 ZXP(out) = lininterp(frac, d1, d2);
2356 iwrphase++;
2360 template <bool Checked = false>
2361 struct DelayC_helper
2363 static const bool checked = false;
2365 static inline void perform(const float *& in, float *& out, float * bufData,
2366 long & iwrphase, long idsamp, float frac, long mask)
2368 bufData[iwrphase & mask] = ZXP(in);
2369 long irdphase1 = iwrphase - idsamp;
2370 long irdphase2 = irdphase1 - 1;
2371 long irdphase3 = irdphase1 - 2;
2372 long irdphase0 = irdphase1 + 1;
2373 float d0 = bufData[irdphase0 & mask];
2374 float d1 = bufData[irdphase1 & mask];
2375 float d2 = bufData[irdphase2 & mask];
2376 float d3 = bufData[irdphase3 & mask];
2377 ZXP(out) = cubicinterp(frac, d0, d1, d2, d3);
2378 iwrphase++;
2382 template <>
2383 struct DelayC_helper<true>
2385 static const bool checked = true;
2387 static inline void perform(const float *& in, float *& out, float * bufData,
2388 long & iwrphase, long idsamp, float frac, long mask)
2390 long irdphase1 = iwrphase - idsamp;
2391 long irdphase2 = irdphase1 - 1;
2392 long irdphase3 = irdphase1 - 2;
2393 long irdphase0 = irdphase1 + 1;
2395 bufData[iwrphase & mask] = ZXP(in);
2396 if (irdphase0 < 0) {
2397 ZXP(out) = 0.f;
2398 } else {
2399 float d0, d1, d2, d3;
2400 if (irdphase1 < 0) {
2401 d1 = d2 = d3 = 0.f;
2402 d0 = bufData[irdphase0 & mask];
2403 } else if (irdphase2 < 0) {
2404 d1 = d2 = d3 = 0.f;
2405 d0 = bufData[irdphase0 & mask];
2406 d1 = bufData[irdphase1 & mask];
2407 } else if (irdphase3 < 0) {
2408 d3 = 0.f;
2409 d0 = bufData[irdphase0 & mask];
2410 d1 = bufData[irdphase1 & mask];
2411 d2 = bufData[irdphase2 & mask];
2412 } else {
2413 d0 = bufData[irdphase0 & mask];
2414 d1 = bufData[irdphase1 & mask];
2415 d2 = bufData[irdphase2 & mask];
2416 d3 = bufData[irdphase3 & mask];
2418 ZXP(out) = cubicinterp(frac, d0, d1, d2, d3);
2420 iwrphase++;
2424 template <bool Checked = false>
2425 struct CombN_helper
2427 static const bool checked = false;
2429 static inline void perform(const float *& in, float *& out, float * bufData,
2430 long & iwrphase, long idsamp, long mask, float feedbk)
2432 long irdphase = iwrphase - idsamp;
2433 float value = bufData[irdphase & mask];
2434 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2435 ZXP(out) = value;
2436 ++iwrphase;
2439 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2440 static inline void perform(const float *& in, float *& out, float * bufData,
2441 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2443 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2447 template <>
2448 struct CombN_helper<true>
2450 static const bool checked = true;
2452 static inline void perform(const float *& in, float *& out, float * bufData,
2453 long & iwrphase, long idsamp, long mask, float feedbk)
2455 long irdphase = iwrphase - idsamp;
2457 if (irdphase < 0) {
2458 bufData[iwrphase & mask] = ZXP(in);
2459 ZXP(out) = 0.f;
2460 } else {
2461 float value = bufData[irdphase & mask];
2462 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2463 ZXP(out) = value;
2466 iwrphase++;
2469 static inline void perform(const float *& in, float *& out, float * bufData,
2470 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2472 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2476 template <bool Checked = false>
2477 struct CombL_helper
2479 static const bool checked = false;
2481 static inline void perform(const float *& in, float *& out, float * bufData,
2482 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2484 long irdphase = iwrphase - idsamp;
2485 long irdphaseb = irdphase - 1;
2486 float d1 = bufData[irdphase & mask];
2487 float d2 = bufData[irdphaseb & mask];
2488 float value = lininterp(frac, d1, d2);
2489 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2490 ZXP(out) = value;
2491 iwrphase++;
2495 template <>
2496 struct CombL_helper<true>
2498 static const bool checked = true;
2500 static inline void perform(const float *& in, float *& out, float * bufData,
2501 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2503 long irdphase = iwrphase - idsamp;
2504 long irdphaseb = irdphase - 1;
2506 float zin = ZXP(in);
2507 if (irdphase < 0) {
2508 bufData[iwrphase & mask] = zin;
2509 ZXP(out) = 0.f;
2510 } else if (irdphaseb < 0) {
2511 float d1 = bufData[irdphase & mask];
2512 float value = d1 - frac * d1;
2513 bufData[iwrphase & mask] = zin + feedbk * value;
2514 ZXP(out) = value;
2515 } else {
2516 float d1 = bufData[irdphase & mask];
2517 float d2 = bufData[irdphaseb & mask];
2518 float value = lininterp(frac, d1, d2);
2519 bufData[iwrphase & mask] = zin + feedbk * value;
2520 ZXP(out) = value;
2522 iwrphase++;
2526 template <bool Checked = false>
2527 struct CombC_helper
2529 static const bool checked = false;
2531 static inline void perform(const float *& in, float *& out, float * bufData,
2532 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2534 long irdphase1 = iwrphase - idsamp;
2535 long irdphase2 = irdphase1 - 1;
2536 long irdphase3 = irdphase1 - 2;
2537 long irdphase0 = irdphase1 + 1;
2538 float d0 = bufData[irdphase0 & mask];
2539 float d1 = bufData[irdphase1 & mask];
2540 float d2 = bufData[irdphase2 & mask];
2541 float d3 = bufData[irdphase3 & mask];
2542 float value = cubicinterp(frac, d0, d1, d2, d3);
2543 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2544 ZXP(out) = value;
2545 iwrphase++;
2549 template <>
2550 struct CombC_helper<true>
2552 static const bool checked = true;
2554 static inline void perform(const float *& in, float *& out, float * bufData,
2555 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2557 long irdphase1 = iwrphase - idsamp;
2558 long irdphase2 = irdphase1 - 1;
2559 long irdphase3 = irdphase1 - 2;
2560 long irdphase0 = irdphase1 + 1;
2562 if (irdphase0 < 0) {
2563 bufData[iwrphase & mask] = ZXP(in);
2564 ZXP(out) = 0.f;
2565 } else {
2566 float d0, d1, d2, d3;
2567 if (irdphase1 < 0) {
2568 d1 = d2 = d3 = 0.f;
2569 d0 = bufData[irdphase0 & mask];
2570 } else if (irdphase2 < 0) {
2571 d1 = d2 = d3 = 0.f;
2572 d0 = bufData[irdphase0 & mask];
2573 d1 = bufData[irdphase1 & mask];
2574 } else if (irdphase3 < 0) {
2575 d3 = 0.f;
2576 d0 = bufData[irdphase0 & mask];
2577 d1 = bufData[irdphase1 & mask];
2578 d2 = bufData[irdphase2 & mask];
2579 } else {
2580 d0 = bufData[irdphase0 & mask];
2581 d1 = bufData[irdphase1 & mask];
2582 d2 = bufData[irdphase2 & mask];
2583 d3 = bufData[irdphase3 & mask];
2585 float value = cubicinterp(frac, d0, d1, d2, d3);
2586 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2587 ZXP(out) = value;
2589 iwrphase++;
2593 template <bool Checked = false>
2594 struct AllpassN_helper
2596 static const bool checked = false;
2598 static inline void perform(const float *& in, float *& out, float * bufData,
2599 long & iwrphase, long idsamp, long mask, float feedbk)
2601 long irdphase = iwrphase - idsamp;
2602 float value = bufData[irdphase & mask];
2603 float dwr = value * feedbk + ZXP(in);
2604 bufData[iwrphase & mask] = dwr;
2605 ZXP(out) = value - feedbk * dwr;
2606 ++iwrphase;
2609 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2610 static inline void perform(const float *& in, float *& out, float * bufData,
2611 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2613 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2617 template <>
2618 struct AllpassN_helper<true>
2620 static const bool checked = true;
2622 static inline void perform(const float *& in, float *& out, float * bufData,
2623 long & iwrphase, long idsamp, long mask, float feedbk)
2625 long irdphase = iwrphase - idsamp;
2627 if (irdphase < 0) {
2628 float dwr = ZXP(in);
2629 bufData[iwrphase & mask] = dwr;
2630 ZXP(out) = -feedbk * dwr;
2631 } else {
2632 float value = bufData[irdphase & mask];
2633 float dwr = feedbk * value + ZXP(in);
2634 bufData[iwrphase & mask] = dwr;
2635 ZXP(out) = value - feedbk * dwr;
2637 ++iwrphase;
2640 static inline void perform(const float *& in, float *& out, float * bufData,
2641 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2643 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2647 template <bool Checked = false>
2648 struct AllpassL_helper
2650 static const bool checked = false;
2652 static inline void perform(const float *& in, float *& out, float * bufData,
2653 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2655 long irdphase = iwrphase - idsamp;
2656 long irdphaseb = irdphase - 1;
2657 float d1 = bufData[irdphase & mask];
2658 float d2 = bufData[irdphaseb & mask];
2659 float value = lininterp(frac, d1, d2);
2660 float dwr = ZXP(in) + feedbk * value;
2661 bufData[iwrphase & mask] = dwr;
2662 ZXP(out) = value - feedbk * dwr;
2663 iwrphase++;
2667 template <>
2668 struct AllpassL_helper<true>
2670 static const bool checked = true;
2672 static inline void perform(const float *& in, float *& out, float * bufData,
2673 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2675 long irdphase = iwrphase - idsamp;
2676 long irdphaseb = irdphase - 1;
2678 float zin = ZXP(in);
2679 if (irdphase < 0) {
2680 bufData[iwrphase & mask] = zin;
2681 ZXP(out) = - feedbk * zin;
2682 } else if (irdphaseb < 0) {
2683 float d1 = bufData[irdphase & mask];
2684 float value = d1 - frac * d1;
2685 float dwr = zin + feedbk * value;
2686 bufData[iwrphase & mask] = dwr;
2687 ZXP(out) = value - feedbk * dwr;
2688 } else {
2689 float d1 = bufData[irdphase & mask];
2690 float d2 = bufData[irdphaseb & mask];
2691 float value = lininterp(frac, d1, d2);
2692 float dwr = zin + feedbk * value;
2693 bufData[iwrphase & mask] = dwr;
2694 ZXP(out) = value - feedbk * dwr;
2696 iwrphase++;
2700 template <bool Checked = false>
2701 struct AllpassC_helper
2703 static const bool checked = false;
2705 static inline void perform(const float *& in, float *& out, float * bufData,
2706 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2708 long irdphase1 = iwrphase - idsamp;
2709 long irdphase2 = irdphase1 - 1;
2710 long irdphase3 = irdphase1 - 2;
2711 long irdphase0 = irdphase1 + 1;
2712 float d0 = bufData[irdphase0 & mask];
2713 float d1 = bufData[irdphase1 & mask];
2714 float d2 = bufData[irdphase2 & mask];
2715 float d3 = bufData[irdphase3 & mask];
2716 float value = cubicinterp(frac, d0, d1, d2, d3);
2717 float dwr = ZXP(in) + feedbk * value;
2718 bufData[iwrphase & mask] = dwr;
2719 ZXP(out) = value - feedbk * dwr;
2720 iwrphase++;
2724 template <>
2725 struct AllpassC_helper<true>
2727 static const bool checked = true;
2729 static inline void perform(const float *& in, float *& out, float * bufData,
2730 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2732 long irdphase1 = iwrphase - idsamp;
2733 long irdphase2 = irdphase1 - 1;
2734 long irdphase3 = irdphase1 - 2;
2735 long irdphase0 = irdphase1 + 1;
2737 if (irdphase0 < 0) {
2738 bufData[iwrphase & mask] = ZXP(in);
2739 ZXP(out) = 0.f;
2740 } else {
2741 float d0, d1, d2, d3;
2742 if (irdphase1 < 0) {
2743 d1 = d2 = d3 = 0.f;
2744 d0 = bufData[irdphase0 & mask];
2745 } else if (irdphase2 < 0) {
2746 d1 = d2 = d3 = 0.f;
2747 d0 = bufData[irdphase0 & mask];
2748 d1 = bufData[irdphase1 & mask];
2749 } else if (irdphase3 < 0) {
2750 d3 = 0.f;
2751 d0 = bufData[irdphase0 & mask];
2752 d1 = bufData[irdphase1 & mask];
2753 d2 = bufData[irdphase2 & mask];
2754 } else {
2755 d0 = bufData[irdphase0 & mask];
2756 d1 = bufData[irdphase1 & mask];
2757 d2 = bufData[irdphase2 & mask];
2758 d3 = bufData[irdphase3 & mask];
2760 float value = cubicinterp(frac, d0, d1, d2, d3);
2761 float dwr = ZXP(in) + feedbk * value;
2762 bufData[iwrphase & mask] = dwr;
2763 ZXP(out) = value - feedbk * dwr;
2765 iwrphase++;
2771 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2773 /* template function to generate buffer-based delay ugen function, control-rate delay time */
2774 template <typename PerformClass,
2775 typename BufDelayX
2777 inline void BufDelayX_perform(BufDelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
2779 float *out = ZOUT(0);
2780 const float *in = ZIN(1);
2781 float delaytime = ZIN0(2);
2783 GET_BUF
2784 CHECK_BUF
2785 long iwrphase = unit->m_iwrphase;
2786 float dsamp = unit->m_dsamp;
2788 if (delaytime == unit->m_delaytime) {
2789 long idsamp = (long)dsamp;
2790 float frac = dsamp - idsamp;
2791 LOOP1(inNumSamples,
2792 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2794 } else {
2795 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2796 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2798 LOOP1(inNumSamples,
2799 dsamp += dsamp_slope;
2800 long idsamp = (long)dsamp;
2801 float frac = dsamp - idsamp;
2802 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2804 unit->m_dsamp = dsamp;
2805 unit->m_delaytime = delaytime;
2808 unit->m_iwrphase = iwrphase;
2810 if (PerformClass::checked) {
2811 unit->m_numoutput += inNumSamples;
2812 if (unit->m_numoutput >= bufSamples)
2813 unit->mCalcFunc = resetFunc;
2818 /* template function to generate buffer-based delay ugen function, audio-rate delay time */
2819 template <typename PerformClass,
2820 typename BufDelayX
2822 inline void BufDelayX_perform_a(BufDelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
2824 float *out = ZOUT(0);
2825 const float *in = ZIN(1);
2826 float * delaytime = ZIN(2);
2828 GET_BUF
2829 CHECK_BUF
2830 long iwrphase = unit->m_iwrphase;
2832 LOOP1(inNumSamples,
2833 float dsamp = BufCalcDelay(unit, bufSamples, ZXP(delaytime));
2834 long idsamp = (long)dsamp;
2836 float frac = dsamp - idsamp;
2837 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2840 unit->m_iwrphase = iwrphase;
2842 if (PerformClass::checked)
2844 unit->m_numoutput += inNumSamples;
2845 if (unit->m_numoutput >= bufSamples)
2846 unit->mCalcFunc = resetFunc;
2850 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2852 void BufDelayN_Ctor(BufDelayN *unit)
2854 if(INRATE(2) == calc_FullRate)
2855 SETCALC(BufDelayN_next_a_z);
2856 else
2857 SETCALC(BufDelayN_next_z);
2858 BufDelayUnit_Reset(unit);
2859 ZOUT0(0) = 0.f;
2862 void BufDelayN_next(BufDelayN *unit, int inNumSamples)
2864 float *out = ZOUT(0);
2865 const float *in = ZIN(1);
2866 float delaytime = ZIN0(2);
2868 GET_BUF
2869 CHECK_BUF
2870 long iwrphase = unit->m_iwrphase;
2871 float dsamp = unit->m_dsamp;
2873 if (delaytime == unit->m_delaytime) {
2874 DelayN_delay_loop<false>(out, in, iwrphase, dsamp, mask, bufData, inNumSamples, PREVIOUSPOWEROFTWO(bufSamples));
2875 } else {
2876 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2877 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2879 LOOP1(inNumSamples,
2880 dsamp += dsamp_slope;
2881 long idsamp = (long)dsamp;
2882 DelayN_helper<false>::perform(in, out, bufData, iwrphase, idsamp, mask);
2884 unit->m_dsamp = dsamp;
2885 unit->m_delaytime = delaytime;
2888 unit->m_iwrphase = iwrphase;
2892 void BufDelayN_next_z(BufDelayN *unit, int inNumSamples)
2894 float *out = ZOUT(0);
2895 const float *in = ZIN(1);
2896 float delaytime = ZIN0(2);
2898 GET_BUF
2899 CHECK_BUF
2900 long iwrphase = unit->m_iwrphase;
2901 float dsamp = unit->m_dsamp;
2903 if (delaytime == unit->m_delaytime) {
2904 DelayN_delay_loop<true>(out, in, iwrphase, dsamp, mask, bufData, inNumSamples, PREVIOUSPOWEROFTWO(bufSamples));
2905 } else {
2906 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2907 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2909 LOOP1(inNumSamples,
2910 dsamp += dsamp_slope;
2911 long idsamp = (long)dsamp;
2912 DelayN_helper<true>::perform(in, out, bufData, iwrphase, idsamp, mask);
2914 unit->m_dsamp = dsamp;
2915 unit->m_delaytime = delaytime;
2918 unit->m_iwrphase = iwrphase;
2920 unit->m_numoutput += inNumSamples;
2921 if (unit->m_numoutput >= bufSamples)
2922 SETCALC(BufDelayN_next);
2925 template <bool checked>
2926 inline void BufDelayN_perform_a(BufDelayN *unit, int inNumSamples)
2928 BufDelayX_perform_a<DelayN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayN_next_a);
2931 void BufDelayN_next_a(BufDelayN *unit, int inNumSamples)
2933 BufDelayN_perform_a<false>(unit, inNumSamples);
2936 void BufDelayN_next_a_z(BufDelayN *unit, int inNumSamples)
2938 BufDelayN_perform_a<true>(unit, inNumSamples);
2941 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2942 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2944 void BufDelayL_Ctor(BufDelayL *unit)
2946 BufDelayUnit_Reset(unit);
2947 if(INRATE(2) == calc_FullRate)
2948 SETCALC(BufDelayL_next_a_z);
2949 else
2950 SETCALC(BufDelayL_next_z);
2951 ZOUT0(0) = 0.f;
2955 template <bool checked>
2956 inline void BufDelayL_perform(BufDelayL *unit, int inNumSamples)
2958 BufDelayX_perform<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next);
2961 void BufDelayL_next(BufDelayL *unit, int inNumSamples)
2963 BufDelayL_perform<false>(unit, inNumSamples);
2966 void BufDelayL_next_z(BufDelayL *unit, int inNumSamples)
2968 BufDelayL_perform<true>(unit, inNumSamples);
2971 template <bool checked>
2972 inline void BufDelayL_perform_a(BufDelayL *unit, int inNumSamples)
2974 BufDelayX_perform_a<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next_a);
2977 void BufDelayL_next_a(BufDelayL *unit, int inNumSamples)
2979 BufDelayL_perform_a<false>(unit, inNumSamples);
2982 void BufDelayL_next_a_z(BufDelayL *unit, int inNumSamples)
2984 BufDelayL_perform_a<true>(unit, inNumSamples);
2987 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2989 void BufDelayC_Ctor(BufDelayC *unit)
2991 BufDelayUnit_Reset(unit);
2992 if(INRATE(2) == calc_FullRate)
2993 SETCALC(BufDelayC_next_a_z);
2994 else
2995 SETCALC(BufDelayC_next_z);
2996 ZOUT0(0) = 0.f;
2999 template <bool checked>
3000 inline void BufDelayC_perform(BufDelayC *unit, int inNumSamples)
3002 BufDelayX_perform<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayC_next);
3005 void BufDelayC_next(BufDelayC *unit, int inNumSamples)
3007 BufDelayC_perform<false>(unit, inNumSamples);
3010 void BufDelayC_next_z(BufDelayC *unit, int inNumSamples)
3012 BufDelayC_perform<true>(unit, inNumSamples);
3015 template <bool checked>
3016 inline void BufDelayC_perform_a(BufDelayC *unit, int inNumSamples)
3018 BufDelayX_perform_a<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next_a);
3021 void BufDelayC_next_a(BufDelayC *unit, int inNumSamples)
3023 BufDelayC_perform_a<false>(unit, inNumSamples);
3026 void BufDelayC_next_a_z(BufDelayC *unit, int inNumSamples)
3028 BufDelayC_perform_a<true>(unit, inNumSamples);
3031 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3032 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3034 template <typename PerformClass,
3035 typename BufCombX
3037 inline void BufFilterX_perform(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3039 float *out = ZOUT(0);
3040 const float *in = ZIN(1);
3041 float delaytime = ZIN0(2);
3042 float decaytime = ZIN0(3);
3044 GET_BUF
3045 CHECK_BUF
3046 long iwrphase = unit->m_iwrphase;
3047 float dsamp = unit->m_dsamp;
3048 float feedbk = unit->m_feedbk;
3050 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
3051 long idsamp = (long)dsamp;
3052 float frac = dsamp - idsamp;
3053 LOOP1(inNumSamples,
3054 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3056 } else {
3057 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3058 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3060 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3061 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3063 LOOP1(inNumSamples,
3064 dsamp += dsamp_slope;
3065 feedbk += feedbk_slope;
3066 long idsamp = (long)dsamp;
3067 float frac = dsamp - idsamp;
3068 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3070 unit->m_feedbk = feedbk;
3071 unit->m_dsamp = dsamp;
3072 unit->m_delaytime = delaytime;
3073 unit->m_decaytime = decaytime;
3076 unit->m_iwrphase = iwrphase;
3078 if (PerformClass::checked) {
3079 unit->m_numoutput += inNumSamples;
3080 if (unit->m_numoutput >= bufSamples)
3081 unit->mCalcFunc = resetFunc;
3085 template <typename PerformClass,
3086 typename BufCombX
3088 inline void BufFilterX_perform_a(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3090 float *out = ZOUT(0);
3091 const float *in = ZIN(1);
3092 float * delaytime = ZIN(2);
3093 float decaytime = ZIN0(3);
3095 GET_BUF
3096 CHECK_BUF
3097 long iwrphase = unit->m_iwrphase;
3099 LOOP1(inNumSamples,
3100 float del = ZXP(delaytime);
3101 float dsamp = BufCalcDelay(unit, bufSamples, del);
3102 float feedbk = sc_CalcFeedback(del, decaytime);
3104 long idsamp = (long)dsamp;
3105 float frac = dsamp - idsamp;
3106 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3109 unit->m_iwrphase = iwrphase;
3111 if (PerformClass::checked)
3113 unit->m_numoutput += inNumSamples;
3114 if (unit->m_numoutput >= bufSamples)
3115 unit->mCalcFunc = resetFunc;
3120 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3122 void BufCombN_Ctor(BufCombN *unit)
3124 BufFeedbackDelay_Reset(unit);
3125 if(INRATE(2) == calc_FullRate)
3126 SETCALC(BufCombN_next_a_z);
3127 else
3128 SETCALC(BufCombN_next_z);
3129 ZOUT0(0) = 0.f;
3132 void BufCombN_next(BufCombN *unit, int inNumSamples)
3134 float *out = ZOUT(0);
3135 const float *in = ZIN(1);
3136 float delaytime = ZIN0(2);
3137 float decaytime = ZIN0(3);
3139 GET_BUF
3140 CHECK_BUF
3141 long iwrphase = unit->m_iwrphase;
3142 float dsamp = unit->m_dsamp;
3143 float feedbk = unit->m_feedbk;
3145 //postbuf("BufCombN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3146 if (delaytime == unit->m_delaytime) {
3147 long irdphase = iwrphase - (long)dsamp;
3148 float* dlybuf1 = bufData - ZOFF;
3149 float* dlyrd = dlybuf1 + (irdphase & mask);
3150 float* dlywr = dlybuf1 + (iwrphase & mask);
3151 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3152 if (decaytime == unit->m_decaytime) {
3153 long remain = inNumSamples;
3154 while (remain) {
3155 long rdspace = dlyN - dlyrd;
3156 long wrspace = dlyN - dlywr;
3157 long nsmps = sc_min(rdspace, wrspace);
3158 nsmps = sc_min(remain, nsmps);
3159 remain -= nsmps;
3160 LOOP1(nsmps,
3161 float value = ZXP(dlyrd);
3162 ZXP(dlywr) = value * feedbk + ZXP(in);
3163 ZXP(out) = value;
3165 if (dlyrd == dlyN) dlyrd = dlybuf1;
3166 if (dlywr == dlyN) dlywr = dlybuf1;
3168 } else {
3169 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3170 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3171 long remain = inNumSamples;
3172 while (remain) {
3173 long rdspace = dlyN - dlyrd;
3174 long wrspace = dlyN - dlywr;
3175 long nsmps = sc_min(rdspace, wrspace);
3176 nsmps = sc_min(remain, nsmps);
3177 remain -= nsmps;
3179 LOOP1(nsmps,
3180 float value = ZXP(dlyrd);
3181 ZXP(dlywr) = value * feedbk + ZXP(in);
3182 ZXP(out) = value;
3183 feedbk += feedbk_slope;
3185 if (dlyrd == dlyN) dlyrd = dlybuf1;
3186 if (dlywr == dlyN) dlywr = dlybuf1;
3188 unit->m_feedbk = feedbk;
3189 unit->m_decaytime = decaytime;
3191 iwrphase += inNumSamples;
3192 } else {
3193 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3194 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3196 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3197 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3198 LOOP1(inNumSamples,
3199 dsamp += dsamp_slope;
3200 feedbk += feedbk_slope;
3201 CombN_helper<false>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3203 unit->m_feedbk = feedbk;
3204 unit->m_dsamp = dsamp;
3205 unit->m_delaytime = delaytime;
3206 unit->m_decaytime = decaytime;
3209 unit->m_iwrphase = iwrphase;
3212 void BufCombN_next_z(BufCombN *unit, int inNumSamples)
3214 float *out = ZOUT(0);
3215 const float *in = ZIN(1);
3216 float delaytime = ZIN0(2);
3217 float decaytime = ZIN0(3);
3219 GET_BUF
3220 CHECK_BUF
3221 long iwrphase = unit->m_iwrphase;
3222 float dsamp = unit->m_dsamp;
3223 float feedbk = unit->m_feedbk;
3225 //Print("BufCombN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3226 if (delaytime == unit->m_delaytime) {
3227 long irdphase = iwrphase - (long)dsamp;
3228 float* dlybuf1 = bufData - ZOFF;
3229 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3230 if (decaytime == unit->m_decaytime) {
3231 long remain = inNumSamples;
3232 while (remain) {
3233 float* dlywr = dlybuf1 + (iwrphase & mask);
3234 float* dlyrd = dlybuf1 + (irdphase & mask);
3235 long rdspace = dlyN - dlyrd;
3236 long wrspace = dlyN - dlywr;
3237 long nsmps = sc_min(rdspace, wrspace);
3238 nsmps = sc_min(remain, nsmps);
3239 remain -= nsmps;
3240 if (irdphase < 0) {
3241 LOOP1(nsmps,
3242 ZXP(dlywr) = ZXP(in);
3243 ZXP(out) = 0.f;
3245 } else {
3246 LOOP1(nsmps,
3247 float value = ZXP(dlyrd);
3248 ZXP(dlywr) = value * feedbk + ZXP(in);
3249 ZXP(out) = value;
3252 iwrphase += nsmps;
3253 irdphase += nsmps;
3255 } else {
3256 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3257 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3258 long remain = inNumSamples;
3259 while (remain) {
3260 float* dlyrd = dlybuf1 + (irdphase & mask);
3261 float* dlywr = dlybuf1 + (iwrphase & mask);
3262 long rdspace = dlyN - dlyrd;
3263 long wrspace = dlyN - dlywr;
3264 long nsmps = sc_min(rdspace, wrspace);
3265 nsmps = sc_min(remain, nsmps);
3266 remain -= nsmps;
3268 if (irdphase < 0) {
3269 feedbk += nsmps * feedbk_slope;
3270 dlyrd += nsmps;
3271 LOOP1(nsmps,
3272 ZXP(dlywr) = ZXP(in);
3273 ZXP(out) = 0.f;
3275 } else {
3276 LOOP1(nsmps,
3277 float value = ZXP(dlyrd);
3278 ZXP(dlywr) = value * feedbk + ZXP(in);
3279 ZXP(out) = value;
3280 feedbk += feedbk_slope;
3283 iwrphase += nsmps;
3284 irdphase += nsmps;
3286 unit->m_feedbk = feedbk;
3287 unit->m_decaytime = decaytime;
3289 } else {
3290 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3291 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3293 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3294 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3296 LOOP1(inNumSamples,
3297 dsamp += dsamp_slope;
3298 feedbk += feedbk_slope;
3299 CombN_helper<true>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3301 unit->m_feedbk = feedbk;
3302 unit->m_dsamp = dsamp;
3303 unit->m_delaytime = delaytime;
3304 unit->m_decaytime = decaytime;
3307 unit->m_iwrphase = iwrphase;
3309 unit->m_numoutput += inNumSamples;
3310 if (unit->m_numoutput >= bufSamples)
3311 SETCALC(BufCombN_next);
3314 template <bool checked>
3315 inline void BufCombN_perform_a(BufCombN *unit, int inNumSamples)
3317 BufFilterX_perform_a<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombN_next_a);
3320 void BufCombN_next_a(BufCombN *unit, int inNumSamples)
3322 BufCombN_perform_a<false>(unit, inNumSamples);
3325 void BufCombN_next_a_z(BufCombN *unit, int inNumSamples)
3327 BufCombN_perform_a<true>(unit, inNumSamples);
3330 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3331 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3333 void BufCombL_Ctor(BufCombL *unit)
3335 BufFeedbackDelay_Reset(unit);
3336 if(INRATE(2) == calc_FullRate)
3337 SETCALC(BufCombL_next_a_z);
3338 else
3339 SETCALC(BufCombL_next_z);
3340 ZOUT0(0) = 0.f;
3343 template <bool checked>
3344 inline void BufCombL_perform(BufCombL *unit, int inNumSamples)
3346 BufFilterX_perform<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombL_next);
3349 void BufCombL_next(BufCombL *unit, int inNumSamples)
3351 BufCombL_perform<false>(unit, inNumSamples);
3354 void BufCombL_next_z(BufCombL *unit, int inNumSamples)
3356 BufCombL_perform<true>(unit, inNumSamples);
3359 template <bool checked>
3360 inline void BufCombL_perform_a(BufCombL *unit, int inNumSamples)
3362 BufFilterX_perform_a<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombL_next_a);
3365 void BufCombL_next_a(BufCombL *unit, int inNumSamples)
3367 BufCombL_perform_a<false>(unit, inNumSamples);
3370 void BufCombL_next_a_z(BufCombL *unit, int inNumSamples)
3372 BufCombL_perform_a<true>(unit, inNumSamples);
3376 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3378 void BufCombC_Ctor(BufCombC *unit)
3380 BufFeedbackDelay_Reset(unit);
3381 if(INRATE(2) == calc_FullRate)
3382 SETCALC(BufCombC_next_a_z);
3383 else
3384 SETCALC(BufCombC_next_z);
3385 ZOUT0(0) = 0.f;
3389 template <bool checked>
3390 inline void BufCombC_perform(BufCombC *unit, int inNumSamples)
3392 BufFilterX_perform<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombC_next);
3395 void BufCombC_next(BufCombC *unit, int inNumSamples)
3397 BufCombC_perform<false>(unit, inNumSamples);
3400 void BufCombC_next_z(BufCombC *unit, int inNumSamples)
3402 BufCombC_perform<true>(unit, inNumSamples);
3405 template <bool checked>
3406 inline void BufCombC_perform_a(BufCombC *unit, int inNumSamples)
3408 BufFilterX_perform_a<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombC_next_a);
3411 void BufCombC_next_a(BufCombC *unit, int inNumSamples)
3413 BufCombC_perform_a<false>(unit, inNumSamples);
3416 void BufCombC_next_a_z(BufCombC *unit, int inNumSamples)
3418 BufCombC_perform_a<true>(unit, inNumSamples);
3422 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3423 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3425 void BufAllpassN_Ctor(BufAllpassN *unit)
3427 BufFeedbackDelay_Reset(unit);
3428 if(INRATE(2) == calc_FullRate)
3429 SETCALC(BufAllpassN_next_a_z);
3430 else
3431 SETCALC(BufAllpassN_next_z);
3432 ZOUT0(0) = 0.f;
3435 void BufAllpassN_next(BufAllpassN *unit, int inNumSamples)
3437 float *out = ZOUT(0);
3438 const float *in = ZIN(1);
3439 float delaytime = ZIN0(2);
3440 float decaytime = ZIN0(3);
3442 GET_BUF
3443 CHECK_BUF
3444 long iwrphase = unit->m_iwrphase;
3445 float dsamp = unit->m_dsamp;
3446 float feedbk = unit->m_feedbk;
3448 //postbuf("BufAllpassN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3449 if (delaytime == unit->m_delaytime) {
3450 long irdphase = iwrphase - (long)dsamp;
3451 float* dlybuf1 = bufData - ZOFF;
3452 float* dlyrd = dlybuf1 + (irdphase & mask);
3453 float* dlywr = dlybuf1 + (iwrphase & mask);
3454 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3455 if (decaytime == unit->m_decaytime) {
3456 long remain = inNumSamples;
3457 while (remain) {
3458 long rdspace = dlyN - dlyrd;
3459 long wrspace = dlyN - dlywr;
3460 long nsmps = sc_min(rdspace, wrspace);
3461 nsmps = sc_min(remain, nsmps);
3462 remain -= nsmps;
3463 LOOP1(nsmps,
3464 float value = ZXP(dlyrd);
3465 float dwr = value * feedbk + ZXP(in);
3466 ZXP(dlywr) = dwr;
3467 ZXP(out) = value - feedbk * dwr;
3469 if (dlyrd == dlyN) dlyrd = dlybuf1;
3470 if (dlywr == dlyN) dlywr = dlybuf1;
3472 } else {
3473 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3474 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3475 long remain = inNumSamples;
3476 while (remain) {
3477 long rdspace = dlyN - dlyrd;
3478 long wrspace = dlyN - dlywr;
3479 long nsmps = sc_min(rdspace, wrspace);
3480 nsmps = sc_min(remain, nsmps);
3481 remain -= nsmps;
3483 LOOP1(nsmps,
3484 float value = ZXP(dlyrd);
3485 float dwr = value * feedbk + ZXP(in);
3486 ZXP(dlywr) = dwr;
3487 ZXP(out) = value - feedbk * dwr;
3488 feedbk += feedbk_slope;
3490 if (dlyrd == dlyN) dlyrd = dlybuf1;
3491 if (dlywr == dlyN) dlywr = dlybuf1;
3493 unit->m_feedbk = feedbk;
3494 unit->m_decaytime = decaytime;
3496 iwrphase += inNumSamples;
3497 } else {
3498 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3499 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3501 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3502 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3503 LOOP1(inNumSamples,
3504 dsamp += dsamp_slope;
3505 feedbk += feedbk_slope;
3506 AllpassN_helper<false>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3508 unit->m_feedbk = feedbk;
3509 unit->m_dsamp = dsamp;
3510 unit->m_delaytime = delaytime;
3511 unit->m_decaytime = decaytime;
3514 unit->m_iwrphase = iwrphase;
3518 void BufAllpassN_next_z(BufAllpassN *unit, int inNumSamples)
3520 float *out = ZOUT(0);
3521 const float *in = ZIN(1);
3522 float delaytime = ZIN0(2);
3523 float decaytime = ZIN0(3);
3525 GET_BUF
3526 CHECK_BUF
3527 long iwrphase = unit->m_iwrphase;
3528 float dsamp = unit->m_dsamp;
3529 float feedbk = unit->m_feedbk;
3531 //postbuf("BufAllpassN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3532 if (delaytime == unit->m_delaytime) {
3533 long irdphase = iwrphase - (long)dsamp;
3534 float* dlybuf1 = bufData - ZOFF;
3535 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3536 if (decaytime == unit->m_decaytime) {
3537 long remain = inNumSamples;
3538 while (remain) {
3539 float* dlywr = dlybuf1 + (iwrphase & mask);
3540 float* dlyrd = dlybuf1 + (irdphase & mask);
3541 long rdspace = dlyN - dlyrd;
3542 long wrspace = dlyN - dlywr;
3543 long nsmps = sc_min(rdspace, wrspace);
3544 nsmps = sc_min(remain, nsmps);
3545 remain -= nsmps;
3546 if (irdphase < 0) {
3547 feedbk = -feedbk;
3548 LOOP1(nsmps,
3549 float dwr = ZXP(in);
3550 ZXP(dlywr) = dwr;
3551 ZXP(out) = feedbk * dwr;
3553 feedbk = -feedbk;
3554 } else {
3555 LOOP1(nsmps,
3556 float x1 = ZXP(dlyrd);
3557 float dwr = x1 * feedbk + ZXP(in);
3558 ZXP(dlywr) = dwr;
3559 ZXP(out) = x1 - feedbk * dwr;
3562 iwrphase += nsmps;
3563 irdphase += nsmps;
3565 } else {
3566 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3567 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3568 long remain = inNumSamples;
3569 while (remain) {
3570 float* dlyrd = dlybuf1 + (irdphase & mask);
3571 float* dlywr = dlybuf1 + (iwrphase & mask);
3572 long rdspace = dlyN - dlyrd;
3573 long wrspace = dlyN - dlywr;
3574 long nsmps = sc_min(rdspace, wrspace);
3575 nsmps = sc_min(remain, nsmps);
3576 remain -= nsmps;
3578 if (irdphase < 0) {
3579 dlyrd += nsmps;
3580 LOOP1(nsmps,
3581 float dwr = ZXP(in);
3582 ZXP(dlywr) = dwr;
3583 ZXP(out) = -feedbk * dwr;
3584 feedbk += feedbk_slope;
3586 } else {
3587 LOOP1(nsmps,
3588 float x1 = ZXP(dlyrd);
3589 float dwr = x1 * feedbk + ZXP(in);
3590 ZXP(dlywr) = dwr;
3591 ZXP(out) = x1 - feedbk * dwr;
3592 feedbk += feedbk_slope;
3595 iwrphase += nsmps;
3596 irdphase += nsmps;
3598 unit->m_feedbk = feedbk;
3599 unit->m_decaytime = decaytime;
3601 } else {
3602 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3603 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3605 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3606 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3608 LOOP1(inNumSamples,
3609 dsamp += dsamp_slope;
3610 feedbk += feedbk_slope;
3611 AllpassN_helper<true>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3613 unit->m_feedbk = feedbk;
3614 unit->m_dsamp = dsamp;
3615 unit->m_delaytime = delaytime;
3616 unit->m_decaytime = decaytime;
3619 unit->m_iwrphase = iwrphase;
3621 unit->m_numoutput += inNumSamples;
3622 if (unit->m_numoutput >= bufSamples)
3623 SETCALC(BufAllpassN_next);
3626 template <bool checked>
3627 inline void BufAllpassN_perform_a(BufAllpassN *unit, int inNumSamples)
3629 BufFilterX_perform_a<AllpassN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassN_next_a);
3632 void BufAllpassN_next_a(BufAllpassN *unit, int inNumSamples)
3634 BufAllpassN_perform_a<false>(unit, inNumSamples);
3637 void BufAllpassN_next_a_z(BufAllpassN *unit, int inNumSamples)
3639 BufAllpassN_perform_a<true>(unit, inNumSamples);
3643 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3644 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3646 void BufAllpassL_Ctor(BufAllpassL *unit)
3648 BufFeedbackDelay_Reset(unit);
3649 if(INRATE(2) == calc_FullRate)
3650 SETCALC(BufAllpassL_next_a_z);
3651 else
3652 SETCALC(BufAllpassL_next_z);
3653 ZOUT0(0) = 0.f;
3656 template <bool checked>
3657 inline void BufAllpassL_perform(BufAllpassL *unit, int inNumSamples)
3659 BufFilterX_perform<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassL_next);
3662 void BufAllpassL_next(BufAllpassL *unit, int inNumSamples)
3664 BufAllpassL_perform<false>(unit, inNumSamples);
3667 void BufAllpassL_next_z(BufAllpassL *unit, int inNumSamples)
3669 BufAllpassL_perform<true>(unit, inNumSamples);
3672 template <bool checked>
3673 inline void BufAllpassL_perform_a(BufAllpassL *unit, int inNumSamples)
3675 BufFilterX_perform_a<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassL_next_a);
3678 void BufAllpassL_next_a(BufAllpassL *unit, int inNumSamples)
3680 BufAllpassL_perform_a<false>(unit, inNumSamples);
3683 void BufAllpassL_next_a_z(BufAllpassL *unit, int inNumSamples)
3685 BufAllpassL_perform_a<true>(unit, inNumSamples);
3689 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3690 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3692 void BufAllpassC_Ctor(BufAllpassC *unit)
3694 BufFeedbackDelay_Reset(unit);
3695 if(INRATE(2) == calc_FullRate)
3696 SETCALC(BufAllpassC_next_a_z);
3697 else
3698 SETCALC(BufAllpassC_next_z);
3699 ZOUT0(0) = 0.f;
3702 template <bool checked>
3703 inline void BufAllpassC_perform(BufAllpassC *unit, int inNumSamples)
3705 BufFilterX_perform<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassC_next);
3708 void BufAllpassC_next(BufAllpassC *unit, int inNumSamples)
3710 BufAllpassC_perform<false>(unit, inNumSamples);
3713 void BufAllpassC_next_z(BufAllpassC *unit, int inNumSamples)
3715 BufAllpassC_perform<true>(unit, inNumSamples);
3718 template <bool checked>
3719 inline void BufAllpassC_perform_a(BufAllpassC *unit, int inNumSamples)
3721 BufFilterX_perform_a<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassC_next_a);
3724 void BufAllpassC_next_a(BufAllpassC *unit, int inNumSamples)
3726 BufAllpassC_perform_a<false>(unit, inNumSamples);
3729 void BufAllpassC_next_a_z(BufAllpassC *unit, int inNumSamples)
3731 BufAllpassC_perform_a<true>(unit, inNumSamples);
3734 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3735 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3736 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3737 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3739 static bool DelayUnit_AllocDelayLine(DelayUnit *unit, const char * className)
3741 long delaybufsize = (long)ceil(unit->m_maxdelaytime * SAMPLERATE + 1.f);
3742 delaybufsize = delaybufsize + BUFLENGTH;
3743 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
3744 unit->m_fdelaylen = unit->m_idelaylen = delaybufsize;
3746 if (unit->m_dlybuf)
3747 RTFree(unit->mWorld, unit->m_dlybuf);
3748 unit->m_dlybuf = (float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
3750 if (unit->m_dlybuf == NULL) {
3751 SETCALC(ft->fClearUnitOutputs);
3752 ClearUnitOutputs(unit, 1);
3754 if(unit->mWorld->mVerbosity > -2)
3755 Print("Failed to allocate memory for %s ugen.\n", className);
3758 unit->m_mask = delaybufsize - 1;
3759 return (unit->m_dlybuf != NULL);
3762 template <typename Unit>
3763 static float CalcDelay(Unit *unit, float delaytime)
3765 float minDelay = Unit::minDelaySamples;
3766 float next_dsamp = delaytime * (float)SAMPLERATE;
3767 return sc_clip(next_dsamp, minDelay, unit->m_fdelaylen);
3770 template <typename Unit>
3771 static bool DelayUnit_Reset(Unit *unit, const char * className)
3773 unit->m_maxdelaytime = ZIN0(1);
3774 unit->m_delaytime = ZIN0(2);
3775 unit->m_dlybuf = 0;
3777 if (!DelayUnit_AllocDelayLine(unit, className))
3778 return false;
3780 unit->m_dsamp = CalcDelay(unit, unit->m_delaytime);
3782 unit->m_numoutput = 0;
3783 unit->m_iwrphase = 0;
3784 return true;
3788 void DelayUnit_Dtor(DelayUnit *unit)
3790 RTFree(unit->mWorld, unit->m_dlybuf);
3793 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3795 template <typename Unit>
3796 static bool FeedbackDelay_Reset(Unit *unit, const char * className)
3798 unit->m_decaytime = ZIN0(3);
3800 bool allocationSucessful = DelayUnit_Reset(unit, className);
3801 if (!allocationSucessful)
3802 return false;
3804 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
3805 return true;
3808 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3810 /* template function to generate delay ugen function, control-rate delay time */
3811 template <typename PerformClass,
3812 typename DelayX
3814 inline void DelayX_perform(DelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3816 float *out = ZOUT(0);
3817 const float *in = ZIN(0);
3818 float delaytime = ZIN0(2);
3820 float *dlybuf = unit->m_dlybuf;
3821 long iwrphase = unit->m_iwrphase;
3822 float dsamp = unit->m_dsamp;
3823 long mask = unit->m_mask;
3825 if (delaytime == unit->m_delaytime) {
3826 long idsamp = (long)dsamp;
3827 float frac = dsamp - idsamp;
3828 LOOP1(inNumSamples,
3829 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3831 } else {
3832 float next_dsamp = CalcDelay(unit, delaytime);
3833 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3835 LOOP1(inNumSamples,
3836 dsamp += dsamp_slope;
3837 long idsamp = (long)dsamp;
3838 float frac = dsamp - idsamp;
3839 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3841 unit->m_dsamp = dsamp;
3842 unit->m_delaytime = delaytime;
3845 unit->m_iwrphase = iwrphase;
3847 if (PerformClass::checked) {
3848 unit->m_numoutput += inNumSamples;
3849 if (unit->m_numoutput >= unit->m_idelaylen)
3850 unit->mCalcFunc = resetFunc;
3854 /* template function to generate delay ugen function, audio-rate delay time */
3855 template <typename PerformClass,
3856 typename DelayX
3858 inline void DelayX_perform_a(DelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3860 float *out = ZOUT(0);
3861 const float *in = ZIN(0);
3862 float * delaytime = ZIN(2);
3864 float *dlybuf = unit->m_dlybuf;
3865 long iwrphase = unit->m_iwrphase;
3866 long mask = unit->m_mask;
3868 LOOP1(inNumSamples,
3869 float dsamp = CalcDelay(unit, ZXP(delaytime));
3870 long idsamp = (long)dsamp;
3872 float frac = dsamp - idsamp;
3873 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3876 unit->m_iwrphase = iwrphase;
3878 if (PerformClass::checked)
3880 unit->m_numoutput += inNumSamples;
3881 if (unit->m_numoutput >= unit->m_idelaylen)
3882 unit->mCalcFunc = resetFunc;
3887 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3889 void Delay_next_0(DelayUnit *unit, int inNumSamples)
3891 float *out = OUT(0);
3892 const float *in = IN(0);
3894 memcpy(out, in, inNumSamples * sizeof(float));
3897 void Delay_next_0_nop(DelayUnit *unit, int inNumSamples)
3900 #ifdef NOVA_SIMD
3901 void Delay_next_0_nova(DelayUnit *unit, int inNumSamples)
3903 nova::copyvec_simd(OUT(0), IN(0), inNumSamples);
3905 #endif
3907 static bool DelayUnit_init_0(DelayUnit *unit)
3909 if (INRATE(2) == calc_ScalarRate && ZIN0(2) == 0) {
3910 if (ZIN(0) == ZOUT(0))
3911 SETCALC(Delay_next_0_nop);
3912 #ifdef NOVA_SIMD
3913 else if (!(BUFLENGTH & 15))
3914 SETCALC(Delay_next_0_nova);
3915 #endif
3916 else
3917 SETCALC(Delay_next_0);
3919 ZOUT0(0) = ZIN0(0);
3920 return true;
3921 } else
3922 return false;
3925 enum {
3926 initializationComplete,
3927 initializationIncomplete
3930 template <typename Delay>
3931 static int Delay_Ctor(Delay *unit, const char *className)
3933 bool allocationSucessful = DelayUnit_Reset(unit, className);
3934 if (!allocationSucessful)
3935 return initializationComplete;
3937 // optimize for a constant delay of zero
3938 if (DelayUnit_init_0(unit))
3939 return initializationComplete;
3940 return initializationIncomplete;
3943 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3945 void DelayN_Ctor(DelayN *unit)
3947 if (Delay_Ctor(unit, "DelayN") == initializationComplete)
3948 return;
3950 if (INRATE(2) == calc_FullRate)
3951 SETCALC(DelayN_next_a_z);
3952 else
3953 SETCALC(DelayN_next_z);
3954 ZOUT0(0) = 0.f;
3957 void DelayN_next(DelayN *unit, int inNumSamples)
3959 float *out = ZOUT(0);
3960 const float *in = ZIN(0);
3961 float delaytime = ZIN0(2);
3963 float *dlybuf = unit->m_dlybuf;
3964 long iwrphase = unit->m_iwrphase;
3965 float dsamp = unit->m_dsamp;
3966 long mask = unit->m_mask;
3968 //Print("DelayN_next %p %g %g %d %d\n", unit, delaytime, dsamp, mask, iwrphase);
3969 if (delaytime == unit->m_delaytime) {
3970 DelayN_delay_loop<false>(out, in, iwrphase, dsamp, mask, dlybuf, inNumSamples, unit->m_idelaylen);
3971 } else {
3972 float next_dsamp = CalcDelay(unit, delaytime);
3973 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3975 LOOP1(inNumSamples,
3976 dsamp += dsamp_slope;
3977 DelayN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask);
3979 unit->m_dsamp = dsamp;
3980 unit->m_delaytime = delaytime;
3983 unit->m_iwrphase = iwrphase;
3987 void DelayN_next_z(DelayN *unit, int inNumSamples)
3989 float *out = ZOUT(0);
3990 const float *in = ZIN(0);
3991 float delaytime = ZIN0(2);
3993 float *dlybuf = unit->m_dlybuf;
3994 long iwrphase = unit->m_iwrphase;
3995 float dsamp = unit->m_dsamp;
3996 long mask = unit->m_mask;
3998 if (delaytime == unit->m_delaytime) {
3999 DelayN_delay_loop<true>(out, in, iwrphase, dsamp, mask, dlybuf, inNumSamples, unit->m_idelaylen);
4000 } else {
4001 float next_dsamp = CalcDelay(unit, delaytime);
4002 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4004 LOOP1(inNumSamples,
4005 dsamp += dsamp_slope;
4006 DelayN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask);
4008 unit->m_dsamp = dsamp;
4009 unit->m_delaytime = delaytime;
4012 unit->m_iwrphase = iwrphase;
4014 unit->m_numoutput += inNumSamples;
4015 if (unit->m_numoutput >= unit->m_idelaylen)
4016 SETCALC(DelayN_next);
4019 template <bool checked>
4020 inline void DelayN_perform_a(DelayN *unit, int inNumSamples)
4022 DelayX_perform_a<DelayN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayN_next_a);
4025 void DelayN_next_a(DelayN *unit, int inNumSamples)
4027 DelayN_perform_a<false>(unit, inNumSamples);
4030 void DelayN_next_a_z(DelayN *unit, int inNumSamples)
4032 DelayN_perform_a<true>(unit, inNumSamples);
4036 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4038 void DelayL_Ctor(DelayL *unit)
4040 if (Delay_Ctor(unit, "DelayL") == initializationComplete)
4041 return;
4043 if (INRATE(2) == calc_FullRate)
4044 SETCALC(DelayL_next_a_z);
4045 else
4046 SETCALC(DelayL_next_z);
4047 ZOUT0(0) = 0.f;
4050 template <bool checked>
4051 inline void DelayL_perform(DelayL *unit, int inNumSamples)
4053 DelayX_perform<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayL_next);
4056 void DelayL_next(DelayL *unit, int inNumSamples)
4058 DelayL_perform<false>(unit, inNumSamples);
4061 void DelayL_next_z(DelayL *unit, int inNumSamples)
4063 DelayL_perform<true>(unit, inNumSamples);
4066 template <bool checked>
4067 inline void DelayL_perform_a(DelayL *unit, int inNumSamples)
4069 DelayX_perform_a<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayL_next_a);
4072 void DelayL_next_a(DelayL *unit, int inNumSamples)
4074 DelayL_perform_a<false>(unit, inNumSamples);
4077 void DelayL_next_a_z(DelayL *unit, int inNumSamples)
4079 DelayL_perform_a<true>(unit, inNumSamples);
4083 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4085 void DelayC_Ctor(DelayC *unit)
4087 if (Delay_Ctor(unit, "DelayC") == initializationComplete)
4088 return;
4090 if (INRATE(2) == calc_FullRate)
4091 SETCALC(DelayC_next_a_z);
4092 else
4093 SETCALC(DelayC_next_z);
4094 ZOUT0(0) = 0.f;
4097 template <bool checked>
4098 inline void DelayC_perform(DelayC *unit, int inNumSamples)
4100 DelayX_perform<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayC_next);
4103 void DelayC_next(DelayC *unit, int inNumSamples)
4105 DelayC_perform<false>(unit, inNumSamples);
4108 void DelayC_next_z(DelayC *unit, int inNumSamples)
4110 DelayC_perform<true>(unit, inNumSamples);
4114 template <bool checked>
4115 inline void DelayC_perform_a(DelayC *unit, int inNumSamples)
4117 DelayX_perform_a<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayC_next_a);
4120 void DelayC_next_a(DelayC *unit, int inNumSamples)
4122 DelayC_perform_a<false>(unit, inNumSamples);
4125 void DelayC_next_a_z(DelayC *unit, int inNumSamples)
4127 DelayC_perform_a<true>(unit, inNumSamples);
4130 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4131 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4133 template <typename PerformClass,
4134 typename BufCombX
4136 inline void FilterX_perform(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
4138 float *out = ZOUT(0);
4139 const float *in = ZIN(0);
4140 float delaytime = ZIN0(2);
4141 float decaytime = ZIN0(3);
4143 float *dlybuf = unit->m_dlybuf;
4144 long iwrphase = unit->m_iwrphase;
4145 float dsamp = unit->m_dsamp;
4146 float feedbk = unit->m_feedbk;
4147 long mask = unit->m_mask;
4149 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
4150 long idsamp = (long)dsamp;
4151 float frac = dsamp - idsamp;
4152 LOOP1(inNumSamples,
4153 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4155 } else {
4156 float next_dsamp = CalcDelay(unit, delaytime);
4157 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4159 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4160 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4162 LOOP1(inNumSamples,
4163 dsamp += dsamp_slope;
4164 feedbk += feedbk_slope;
4165 long idsamp = (long)dsamp;
4166 float frac = dsamp - idsamp;
4167 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4169 unit->m_feedbk = feedbk;
4170 unit->m_dsamp = dsamp;
4171 unit->m_delaytime = delaytime;
4172 unit->m_decaytime = decaytime;
4175 unit->m_iwrphase = iwrphase;
4177 if (PerformClass::checked) {
4178 unit->m_numoutput += inNumSamples;
4179 if (unit->m_numoutput >= unit->m_idelaylen)
4180 unit->mCalcFunc = resetFunc;
4184 template <typename PerformClass,
4185 typename CombX
4187 inline void FilterX_perform_a(CombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
4189 float *out = ZOUT(0);
4190 const float *in = ZIN(0);
4191 float * delaytime = ZIN(2);
4192 float decaytime = ZIN0(3);
4194 float *dlybuf = unit->m_dlybuf;
4195 long iwrphase = unit->m_iwrphase;
4196 long mask = unit->m_mask;
4198 LOOP1(inNumSamples,
4199 float del = ZXP(delaytime);
4200 float dsamp = CalcDelay(unit, del);
4201 float feedbk = sc_CalcFeedback(del, decaytime);
4203 long idsamp = (long)dsamp;
4204 float frac = dsamp - idsamp;
4205 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4208 unit->m_iwrphase = iwrphase;
4210 if (PerformClass::checked)
4212 unit->m_numoutput += inNumSamples;
4213 if (unit->m_numoutput >= unit->m_idelaylen)
4214 unit->mCalcFunc = resetFunc;
4218 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4220 void CombN_Ctor(CombN *unit)
4222 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombN");
4223 if (!allocationSucessful)
4224 return;
4226 if(INRATE(2) == calc_FullRate)
4227 SETCALC(CombN_next_a_z);
4228 else
4229 SETCALC(CombN_next_z);
4230 ZOUT0(0) = 0.f;
4233 void CombN_next(CombN *unit, int inNumSamples)
4235 float *out = ZOUT(0);
4236 const float *in = ZIN(0);
4237 float delaytime = ZIN0(2);
4238 float decaytime = ZIN0(3);
4240 float *dlybuf = unit->m_dlybuf;
4241 long iwrphase = unit->m_iwrphase;
4242 float dsamp = unit->m_dsamp;
4243 float feedbk = unit->m_feedbk;
4244 long mask = unit->m_mask;
4246 //postbuf("CombN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4247 if (delaytime == unit->m_delaytime) {
4248 long irdphase = iwrphase - (long)dsamp;
4249 float* dlybuf1 = dlybuf - ZOFF;
4250 float* dlyrd = dlybuf1 + (irdphase & mask);
4251 float* dlywr = dlybuf1 + (iwrphase & mask);
4252 float* dlyN = dlybuf1 + unit->m_idelaylen;
4253 if (decaytime == unit->m_decaytime) {
4254 long remain = inNumSamples;
4255 while (remain) {
4256 long rdspace = dlyN - dlyrd;
4257 long wrspace = dlyN - dlywr;
4258 long nsmps = sc_min(rdspace, wrspace);
4259 nsmps = sc_min(remain, nsmps);
4260 remain -= nsmps;
4261 LOOP(nsmps,
4262 float value = ZXP(dlyrd);
4263 ZXP(dlywr) = value * feedbk + ZXP(in);
4264 ZXP(out) = value;
4266 if (dlyrd == dlyN) dlyrd = dlybuf1;
4267 if (dlywr == dlyN) dlywr = dlybuf1;
4269 } else {
4270 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4271 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4272 long remain = inNumSamples;
4273 while (remain) {
4274 long rdspace = dlyN - dlyrd;
4275 long wrspace = dlyN - dlywr;
4276 long nsmps = sc_min(rdspace, wrspace);
4277 nsmps = sc_min(remain, nsmps);
4278 remain -= nsmps;
4280 LOOP(nsmps,
4281 float value = ZXP(dlyrd);
4282 ZXP(dlywr) = value * feedbk + ZXP(in);
4283 ZXP(out) = value;
4284 feedbk += feedbk_slope;
4286 if (dlyrd == dlyN) dlyrd = dlybuf1;
4287 if (dlywr == dlyN) dlywr = dlybuf1;
4289 unit->m_feedbk = feedbk;
4290 unit->m_decaytime = decaytime;
4292 iwrphase += inNumSamples;
4293 } else {
4294 float next_dsamp = CalcDelay(unit, delaytime);
4295 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4297 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4298 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4299 LOOP1(inNumSamples,
4300 dsamp += dsamp_slope;
4301 feedbk += feedbk_slope;
4302 CombN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4304 unit->m_feedbk = feedbk;
4305 unit->m_dsamp = dsamp;
4306 unit->m_delaytime = delaytime;
4307 unit->m_decaytime = decaytime;
4310 unit->m_iwrphase = iwrphase;
4314 void CombN_next_z(CombN *unit, int inNumSamples)
4316 float *out = ZOUT(0);
4317 const float *in = ZIN(0);
4318 float delaytime = ZIN0(2);
4319 float decaytime = ZIN0(3);
4321 float *dlybuf = unit->m_dlybuf;
4322 long iwrphase = unit->m_iwrphase;
4323 float dsamp = unit->m_dsamp;
4324 float feedbk = unit->m_feedbk;
4325 long mask = unit->m_mask;
4327 //postbuf("CombN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4328 if (delaytime == unit->m_delaytime) {
4329 long irdphase = iwrphase - (long)dsamp;
4330 float* dlybuf1 = dlybuf - ZOFF;
4331 float* dlyN = dlybuf1 + unit->m_idelaylen;
4332 if (decaytime == unit->m_decaytime) {
4333 long remain = inNumSamples;
4334 while (remain) {
4335 float* dlywr = dlybuf1 + (iwrphase & mask);
4336 float* dlyrd = dlybuf1 + (irdphase & mask);
4337 long rdspace = dlyN - dlyrd;
4338 long wrspace = dlyN - dlywr;
4339 long nsmps = sc_min(rdspace, wrspace);
4340 nsmps = sc_min(remain, nsmps);
4341 remain -= nsmps;
4342 if (irdphase < 0) {
4343 LOOP(nsmps,
4344 ZXP(dlywr) = ZXP(in);
4345 ZXP(out) = 0.f;
4347 } else {
4348 LOOP(nsmps,
4349 float value = ZXP(dlyrd);
4350 ZXP(dlywr) = value * feedbk + ZXP(in);
4351 ZXP(out) = value;
4354 iwrphase += nsmps;
4355 irdphase += nsmps;
4357 } else {
4358 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4359 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4360 long remain = inNumSamples;
4361 while (remain) {
4362 float* dlyrd = dlybuf1 + (irdphase & mask);
4363 float* dlywr = dlybuf1 + (iwrphase & mask);
4364 long rdspace = dlyN - dlyrd;
4365 long wrspace = dlyN - dlywr;
4366 long nsmps = sc_min(rdspace, wrspace);
4367 nsmps = sc_min(remain, nsmps);
4368 remain -= nsmps;
4370 if (irdphase < 0) {
4371 feedbk += nsmps * feedbk_slope;
4372 dlyrd += nsmps;
4373 LOOP(nsmps,
4374 ZXP(dlywr) = ZXP(in);
4375 ZXP(out) = 0.f;
4377 } else {
4378 LOOP(nsmps,
4379 float value = ZXP(dlyrd);
4380 ZXP(dlywr) = value * feedbk + ZXP(in);
4381 ZXP(out) = value;
4382 feedbk += feedbk_slope;
4385 iwrphase += nsmps;
4386 irdphase += nsmps;
4388 unit->m_feedbk = feedbk;
4389 unit->m_decaytime = decaytime;
4391 } else {
4393 float next_dsamp = CalcDelay(unit, delaytime);
4394 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4396 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4397 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4399 LOOP1(inNumSamples,
4400 dsamp += dsamp_slope;
4401 feedbk += feedbk_slope;
4402 CombN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4404 unit->m_feedbk = feedbk;
4405 unit->m_dsamp = dsamp;
4406 unit->m_delaytime = delaytime;
4407 unit->m_decaytime = decaytime;
4410 unit->m_iwrphase = iwrphase;
4412 unit->m_numoutput += inNumSamples;
4413 if (unit->m_numoutput >= unit->m_idelaylen)
4414 SETCALC(CombN_next);
4417 template <bool checked>
4418 inline void CombN_perform_a(CombN *unit, int inNumSamples)
4420 FilterX_perform_a<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombN_next_a);
4423 void CombN_next_a(CombN *unit, int inNumSamples)
4425 CombN_perform_a<false>(unit, inNumSamples);
4428 void CombN_next_a_z(CombN *unit, int inNumSamples)
4430 CombN_perform_a<true>(unit, inNumSamples);
4434 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4435 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4437 void CombL_Ctor(CombL *unit)
4439 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombL");
4440 if (!allocationSucessful)
4441 return;
4443 if(INRATE(2) == calc_FullRate)
4444 SETCALC(CombL_next_a_z);
4445 else
4446 SETCALC(CombL_next_z);
4447 ZOUT0(0) = 0.f;
4450 template <bool checked>
4451 inline void CombL_perform(CombL *unit, int inNumSamples)
4453 FilterX_perform<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombL_next);
4456 void CombL_next(CombL *unit, int inNumSamples)
4458 CombL_perform<false>(unit, inNumSamples);
4461 void CombL_next_z(CombL *unit, int inNumSamples)
4463 CombL_perform<true>(unit, inNumSamples);
4466 template <bool checked>
4467 inline void CombL_perform_a(CombL *unit, int inNumSamples)
4469 FilterX_perform_a<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombL_next_a);
4472 void CombL_next_a(CombL *unit, int inNumSamples)
4474 CombL_perform_a<false>(unit, inNumSamples);
4477 void CombL_next_a_z(CombL *unit, int inNumSamples)
4479 CombL_perform_a<true>(unit, inNumSamples);
4482 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4484 void CombC_Ctor(CombC *unit)
4486 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombC");
4487 if (!allocationSucessful)
4488 return;
4490 if(INRATE(2) == calc_FullRate)
4491 SETCALC(CombC_next_a_z);
4492 else
4493 SETCALC(CombC_next_z);
4494 ZOUT0(0) = 0.f;
4497 template <bool checked>
4498 inline void CombC_perform(CombC *unit, int inNumSamples)
4500 FilterX_perform<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombC_next);
4503 void CombC_next(CombC *unit, int inNumSamples)
4505 CombC_perform<false>(unit, inNumSamples);
4508 void CombC_next_z(CombC *unit, int inNumSamples)
4510 CombC_perform<true>(unit, inNumSamples);
4513 template <bool checked>
4514 inline void CombC_perform_a(CombC *unit, int inNumSamples)
4516 FilterX_perform_a<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombC_next_a);
4519 void CombC_next_a(CombC *unit, int inNumSamples)
4521 CombC_perform_a<false>(unit, inNumSamples);
4524 void CombC_next_a_z(CombC *unit, int inNumSamples)
4526 CombC_perform_a<true>(unit, inNumSamples);
4530 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4531 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4533 void AllpassN_Ctor(AllpassN *unit)
4535 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassN");
4536 if (!allocationSucessful)
4537 return;
4539 if(INRATE(2) == calc_FullRate)
4540 SETCALC(AllpassN_next_a_z);
4541 else
4542 SETCALC(AllpassN_next_z);
4543 ZOUT0(0) = 0.f;
4546 void AllpassN_next(AllpassN *unit, int inNumSamples)
4548 float *out = ZOUT(0);
4549 const float *in = ZIN(0);
4550 float delaytime = ZIN0(2);
4551 float decaytime = ZIN0(3);
4553 float *dlybuf = unit->m_dlybuf;
4554 long iwrphase = unit->m_iwrphase;
4555 float dsamp = unit->m_dsamp;
4556 float feedbk = unit->m_feedbk;
4557 long mask = unit->m_mask;
4559 //postbuf("AllpassN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4560 if (delaytime == unit->m_delaytime) {
4561 long irdphase = iwrphase - (long)dsamp;
4562 float* dlybuf1 = dlybuf - ZOFF;
4563 float* dlyrd = dlybuf1 + (irdphase & mask);
4564 float* dlywr = dlybuf1 + (iwrphase & mask);
4565 float* dlyN = dlybuf1 + unit->m_idelaylen;
4566 if (decaytime == unit->m_decaytime) {
4567 long remain = inNumSamples;
4568 while (remain) {
4569 long rdspace = dlyN - dlyrd;
4570 long wrspace = dlyN - dlywr;
4571 long nsmps = sc_min(rdspace, wrspace);
4572 nsmps = sc_min(remain, nsmps);
4573 remain -= nsmps;
4574 LOOP(nsmps,
4575 float value = ZXP(dlyrd);
4576 float dwr = value * feedbk + ZXP(in);
4577 ZXP(dlywr) = dwr;
4578 ZXP(out) = value - feedbk * dwr;
4580 if (dlyrd == dlyN) dlyrd = dlybuf1;
4581 if (dlywr == dlyN) dlywr = dlybuf1;
4583 } else {
4584 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4585 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4586 long remain = inNumSamples;
4587 while (remain) {
4588 long rdspace = dlyN - dlyrd;
4589 long wrspace = dlyN - dlywr;
4590 long nsmps = sc_min(rdspace, wrspace);
4591 nsmps = sc_min(remain, nsmps);
4592 remain -= nsmps;
4594 LOOP(nsmps,
4595 float value = ZXP(dlyrd);
4596 float dwr = value * feedbk + ZXP(in);
4597 ZXP(dlywr) = dwr;
4598 ZXP(out) = value - feedbk * dwr;
4599 feedbk += feedbk_slope;
4601 if (dlyrd == dlyN) dlyrd = dlybuf1;
4602 if (dlywr == dlyN) dlywr = dlybuf1;
4604 unit->m_feedbk = feedbk;
4605 unit->m_decaytime = decaytime;
4607 iwrphase += inNumSamples;
4608 } else {
4609 float next_dsamp = CalcDelay(unit, delaytime);
4610 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4612 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4613 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4614 LOOP1(inNumSamples,
4615 dsamp += dsamp_slope;
4616 feedbk += feedbk_slope;
4617 AllpassN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4619 unit->m_feedbk = feedbk;
4620 unit->m_dsamp = dsamp;
4621 unit->m_delaytime = delaytime;
4622 unit->m_decaytime = decaytime;
4625 unit->m_iwrphase = iwrphase;
4629 void AllpassN_next_z(AllpassN *unit, int inNumSamples)
4631 float *out = ZOUT(0);
4632 const float *in = ZIN(0);
4633 float delaytime = ZIN0(2);
4634 float decaytime = ZIN0(3);
4636 float *dlybuf = unit->m_dlybuf;
4637 long iwrphase = unit->m_iwrphase;
4638 float dsamp = unit->m_dsamp;
4639 float feedbk = unit->m_feedbk;
4640 long mask = unit->m_mask;
4642 //postbuf("AllpassN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4643 if (delaytime == unit->m_delaytime) {
4644 long irdphase = iwrphase - (long)dsamp;
4645 float* dlybuf1 = dlybuf - ZOFF;
4646 float* dlyN = dlybuf1 + unit->m_idelaylen;
4647 if (decaytime == unit->m_decaytime) {
4648 long remain = inNumSamples;
4649 while (remain) {
4650 float* dlywr = dlybuf1 + (iwrphase & mask);
4651 float* dlyrd = dlybuf1 + (irdphase & mask);
4652 long rdspace = dlyN - dlyrd;
4653 long wrspace = dlyN - dlywr;
4654 long nsmps = sc_min(rdspace, wrspace);
4655 nsmps = sc_min(remain, nsmps);
4656 remain -= nsmps;
4657 if (irdphase < 0) {
4658 feedbk = -feedbk;
4659 LOOP(nsmps,
4660 float dwr = ZXP(in);
4661 ZXP(dlywr) = dwr;
4662 ZXP(out) = feedbk * dwr;
4664 feedbk = -feedbk;
4665 } else {
4666 LOOP(nsmps,
4667 float x1 = ZXP(dlyrd);
4668 float dwr = x1 * feedbk + ZXP(in);
4669 ZXP(dlywr) = dwr;
4670 ZXP(out) = x1 - feedbk * dwr;
4673 iwrphase += nsmps;
4674 irdphase += nsmps;
4676 } else {
4677 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4678 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4679 long remain = inNumSamples;
4680 while (remain) {
4681 float* dlyrd = dlybuf1 + (irdphase & mask);
4682 float* dlywr = dlybuf1 + (iwrphase & mask);
4683 long rdspace = dlyN - dlyrd;
4684 long wrspace = dlyN - dlywr;
4685 long nsmps = sc_min(rdspace, wrspace);
4686 nsmps = sc_min(remain, nsmps);
4687 remain -= nsmps;
4689 if (irdphase < 0) {
4690 dlyrd += nsmps;
4691 LOOP(nsmps,
4692 float dwr = ZXP(in);
4693 ZXP(dlywr) = dwr;
4694 ZXP(out) = -feedbk * dwr;
4695 feedbk += feedbk_slope;
4697 } else {
4698 LOOP(nsmps,
4699 float x1 = ZXP(dlyrd);
4700 float dwr = x1 * feedbk + ZXP(in);
4701 ZXP(dlywr) = dwr;
4702 ZXP(out) = x1 - feedbk * dwr;
4703 feedbk += feedbk_slope;
4706 iwrphase += nsmps;
4707 irdphase += nsmps;
4709 unit->m_feedbk = feedbk;
4710 unit->m_decaytime = decaytime;
4712 } else {
4713 float next_dsamp = CalcDelay(unit, delaytime);
4714 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4716 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4717 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4719 LOOP1(inNumSamples,
4720 dsamp += dsamp_slope;
4721 feedbk += feedbk_slope;
4722 AllpassN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4724 unit->m_feedbk = feedbk;
4725 unit->m_dsamp = dsamp;
4726 unit->m_delaytime = delaytime;
4727 unit->m_decaytime = decaytime;
4730 unit->m_iwrphase = iwrphase;
4732 unit->m_numoutput += inNumSamples;
4733 if (unit->m_numoutput >= unit->m_idelaylen)
4734 SETCALC(AllpassN_next);
4737 template <bool checked>
4738 inline void AllpassN_perform_a(AllpassN *unit, int inNumSamples)
4740 FilterX_perform_a<AllpassN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassN_next_a);
4743 void AllpassN_next_a(AllpassN *unit, int inNumSamples)
4745 AllpassN_perform_a<false>(unit, inNumSamples);
4748 void AllpassN_next_a_z(AllpassN *unit, int inNumSamples)
4750 AllpassN_perform_a<true>(unit, inNumSamples);
4754 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4755 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4757 void AllpassL_Ctor(AllpassL *unit)
4759 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassL");
4760 if (!allocationSucessful)
4761 return;
4763 if(INRATE(2) == calc_FullRate)
4764 SETCALC(AllpassL_next_a_z);
4765 else
4766 SETCALC(AllpassL_next_z);
4767 ZOUT0(0) = 0.f;
4770 template <bool checked>
4771 inline void AllpassL_perform(AllpassL *unit, int inNumSamples)
4773 FilterX_perform<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassL_next);
4776 void AllpassL_next(AllpassL *unit, int inNumSamples)
4778 AllpassL_perform<false>(unit, inNumSamples);
4781 void AllpassL_next_z(AllpassL *unit, int inNumSamples)
4783 AllpassL_perform<true>(unit, inNumSamples);
4786 template <bool checked>
4787 inline void AllpassL_perform_a(AllpassL *unit, int inNumSamples)
4789 FilterX_perform_a<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassL_next_a);
4792 void AllpassL_next_a(AllpassL *unit, int inNumSamples)
4794 AllpassL_perform_a<false>(unit, inNumSamples);
4797 void AllpassL_next_a_z(AllpassL *unit, int inNumSamples)
4799 AllpassL_perform_a<true>(unit, inNumSamples);
4802 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4803 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4805 void AllpassC_Ctor(AllpassC *unit)
4807 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassC");
4808 if (!allocationSucessful)
4809 return;
4811 if(INRATE(2) == calc_FullRate)
4812 SETCALC(AllpassC_next_a_z);
4813 else
4814 SETCALC(AllpassC_next_z);
4815 ZOUT0(0) = 0.f;
4818 template <bool checked>
4819 inline void AllpassC_perform(AllpassC *unit, int inNumSamples)
4821 FilterX_perform<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassC_next);
4824 void AllpassC_next(AllpassC *unit, int inNumSamples)
4826 AllpassC_perform<false>(unit, inNumSamples);
4829 void AllpassC_next_z(AllpassC *unit, int inNumSamples)
4831 AllpassC_perform<true>(unit, inNumSamples);
4834 template <bool checked>
4835 inline void AllpassC_perform_a(AllpassC *unit, int inNumSamples)
4837 FilterX_perform_a<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassC_next_a);
4840 void AllpassC_next_a(AllpassC *unit, int inNumSamples)
4842 AllpassC_perform_a<false>(unit, inNumSamples);
4845 void AllpassC_next_a_z(AllpassC *unit, int inNumSamples)
4847 AllpassC_perform_a<true>(unit, inNumSamples);
4850 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4853 inline double sc_loop1(int32 in, int32 lo, int32 hi)
4855 // avoid the divide if possible
4856 if (in >= hi) {
4857 in -= hi;
4858 if (in < hi) return in;
4859 } else if (in < lo) {
4860 in += hi;
4861 if (in >= lo) return in;
4862 } else return in;
4864 int32 range = hi - lo;
4865 return lo + range * (in-lo) / range;
4868 #if NOTYET
4870 void SimpleLoopBuf_next_kk(SimpleLoopBuf *unit, int inNumSamples)
4872 float trig = ZIN0(1);
4873 double loopstart = (double)ZIN0(2);
4874 double loopend = (double)ZIN0(3);
4875 GET_BUF
4877 int numOutputs = unit->mNumOutputs;
4878 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
4879 return;
4882 loopend = sc_max(loopend, bufFrames);
4883 int32 phase = unit->m_phase;
4884 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
4885 unit->mDone = false;
4886 phase = (int32)ZIN0(2);
4888 unit->m_prevtrig = trig;
4889 for (int i=0; i<inNumSamples; ++i) {
4890 phase = sc_loop1(phase, loopstart, loopend);
4891 int32 iphase = (int32)phase;
4892 float* table1 = bufData + iphase * bufChannels;
4893 int32 index = 0;
4894 for (uint32 channel=0; channel<bufChannels; ++channel) {
4895 OUT(channel[i]) = table1[index++];
4898 phase++;
4900 unit->m_phase = phase;
4904 void SimpleLoopBuf_Ctor(SimpleLoopBuf *unit)
4906 SETCALC(SimpleLoopBuf_next_kk);
4908 unit->m_fbufnum = -1e9f;
4909 unit->m_prevtrig = 0.;
4910 unit->m_phase = ZIN0(2);
4912 ClearUnitOutputs(unit, 1);
4914 #endif
4916 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4919 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4921 #define GET_SCOPEBUF \
4922 float fbufnum = ZIN0(0); \
4923 if (fbufnum != unit->m_fbufnum) { \
4924 World *world = unit->mWorld; \
4925 if (!world->mNumSndBufs) { \
4926 ClearUnitOutputs(unit, inNumSamples); \
4927 return; \
4929 uint32 bufnum = (int)fbufnum; \
4930 if (bufnum >= world->mNumSndBufs) bufnum = 0; \
4931 unit->m_fbufnum = fbufnum; \
4932 unit->m_buf = world->mSndBufs + bufnum; \
4933 unit->m_bufupdates = world->mSndBufUpdates + bufnum; \
4935 SndBuf *buf = unit->m_buf; \
4936 LOCK_SNDBUF(buf); \
4937 SndBufUpdates *bufupdates = unit->m_bufupdates; \
4938 float *bufData __attribute__((__unused__)) = buf->data; \
4939 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
4940 uint32 bufFrames __attribute__((__unused__)) = buf->frames; \
4942 void ScopeOut_next(ScopeOut *unit, int inNumSamples)
4944 GET_SCOPEBUF
4946 if (!bufData) {
4947 unit->m_framepos = 0;
4948 return;
4951 SETUP_IN(1)
4953 uint32 framepos = unit->m_framepos;
4954 if (framepos >= bufFrames) {
4955 unit->m_framepos = 0;
4958 if (bufupdates->reads != bufupdates->writes) {
4959 unit->m_framepos += inNumSamples;
4960 return;
4963 bufData += framepos * bufChannels;
4965 int remain = (bufFrames - framepos), wrap = 0;
4967 if(inNumSamples <= remain) {
4968 remain = inNumSamples;
4969 wrap = 0;
4971 else
4972 wrap = inNumSamples - remain;
4974 if (bufChannels > 2) {
4975 for (int j=0; j<remain; ++j) {
4976 for (uint32 i=0; i<bufChannels; ++i) {
4977 *bufData++ = *++(in[i]);
4981 bufData = buf->data;
4983 for (int j=0; j<wrap; ++j) {
4984 for (uint32 i=0; i<bufChannels; ++i) {
4985 *bufData++ = *++(in[i]);
4988 } else if (bufChannels == 2) {
4989 float *in0 = in[0];
4990 float *in1 = in[1];
4991 for (int j=0; j<remain; ++j) {
4992 *bufData++ = *++in0;
4993 *bufData++ = *++in1;
4996 bufData = buf->data;
4998 for (int j=0; j<wrap; ++j) {
4999 *bufData++ = *++in0;
5000 *bufData++ = *++in1;
5002 } else {
5003 float *in0 = in[0];
5004 for (int j=0; j<remain; ++j) {
5005 *bufData++ = *++in0;
5008 bufData = buf->data;
5010 for (int j=0; j<wrap; ++j) {
5011 *bufData++ = *++in0;
5015 unit->m_framepos += inNumSamples;
5016 unit->m_framecount += inNumSamples;
5018 if (unit->m_framecount >= bufFrames) {
5019 bufupdates->writes++;
5020 unit->m_framecount = 0;
5026 void ScopeOut_Ctor(ScopeOut *unit)
5029 unit->m_fbufnum = -1e9;
5030 unit->m_framepos = 0;
5031 unit->m_framecount = 0;
5032 unit->mIn = 0;
5033 SETCALC(ScopeOut_next);
5036 void ScopeOut_Dtor(ScopeOut *unit)
5038 TAKEDOWN_IN
5041 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5043 struct ScopeOut2 : public Unit
5045 ScopeBufferHnd m_buffer;
5046 float **m_inBuffers;
5047 int m_maxPeriod;
5048 uint32 m_phase;
5052 void ScopeOut2_next(ScopeOut2 *unit, int inNumSamples)
5054 if( !unit->m_buffer ) return;
5056 const int inputOffset = 3;
5057 int numChannels = unit->mNumInputs - inputOffset;
5059 uint32 period = (uint32)ZIN0(2);
5060 uint32 framepos = unit->m_phase;
5062 period = std::max((uint32)inNumSamples, std::min(unit->m_buffer.maxFrames, period));
5064 if( framepos >= period ) framepos = 0;
5066 int remain = period - framepos, wrap = 0;
5068 if(inNumSamples <= remain)
5069 remain = inNumSamples;
5070 else
5071 wrap = inNumSamples - remain;
5073 for (int i = 0; i != numChannels; ++i) {
5074 float * inBuf = unit->m_buffer.channel_data(i);
5075 const float * in = IN(inputOffset + i);
5077 memcpy(inBuf + framepos, in, remain * sizeof(float));
5080 if(framepos + inNumSamples >= period)
5081 (*ft->fPushScopeBuffer)(unit->mWorld, unit->m_buffer, period);
5083 if (wrap) {
5084 for (int i = 0; i != numChannels; ++i) {
5085 float * inBuf = unit->m_buffer.channel_data(i);
5086 const float * in = IN(inputOffset + i);
5087 memcpy(inBuf, in + remain, wrap * sizeof(float));
5091 framepos += inNumSamples;
5092 if (framepos >= period)
5093 framepos = wrap;
5095 unit->m_phase = framepos;
5098 void ScopeOut2_Ctor(ScopeOut2 *unit)
5100 uint32 numChannels = unit->mNumInputs - 3;
5101 uint32 scopeNum = (uint32)ZIN0(0);
5102 uint32 maxFrames = (uint32)ZIN0(1);
5104 bool ok = (*ft->fGetScopeBuffer)(unit->mWorld, scopeNum, numChannels, maxFrames, unit->m_buffer);
5106 if( !ok ) {
5107 if( unit->mWorld->mVerbosity > -1 && !unit->mDone)
5108 Print("ScopeOut2: Requested scope buffer unavailable! (index: %d, channels: %d, size: %d)\n",
5109 scopeNum, numChannels, maxFrames);
5111 else {
5112 unit->m_phase = 0;
5115 SETCALC(ScopeOut2_next);
5118 void ScopeOut2_Dtor(ScopeOut2 *unit)
5120 if( unit->m_buffer )
5121 (*ft->fReleaseScopeBuffer)(unit->mWorld, unit->m_buffer);
5125 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5127 struct PitchShift : public Unit
5129 float *dlybuf;
5130 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5131 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5132 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5133 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5134 float fdelaylen, slope;
5135 long iwrphase, idelaylen, mask;
5136 long counter, stage, numoutput, framesize;
5139 void PitchShift_next(PitchShift *unit, int inNumSamples);
5140 void PitchShift_next(PitchShift *unit, int inNumSamples)
5142 float *out, *in, *dlybuf;
5143 float disppchratio, pchratio, pchratio1, value;
5144 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5145 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5146 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5147 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5148 float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, winsize, pchdisp, timedisp;
5149 long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp;
5150 long counter, stage, framesize;
5152 RGET
5154 out = ZOUT(0);
5155 in = ZIN(0);
5157 pchratio = ZIN0(2);
5158 winsize = ZIN0(1);
5159 pchdisp = ZIN0(3);
5160 timedisp = ZIN0(4);
5161 timedisp = sc_clip(timedisp, 0.f, winsize) * SAMPLERATE;
5163 dlybuf = unit->dlybuf;
5164 fdelaylen = unit->fdelaylen;
5165 idelaylen = unit->idelaylen;
5166 iwrphase = unit->iwrphase;
5168 counter = unit->counter;
5169 stage = unit->stage;
5170 mask = unit->mask;
5171 framesize = unit->framesize;
5173 dsamp1 = unit->dsamp1;
5174 dsamp2 = unit->dsamp2;
5175 dsamp3 = unit->dsamp3;
5176 dsamp4 = unit->dsamp4;
5178 dsamp1_slope = unit->dsamp1_slope;
5179 dsamp2_slope = unit->dsamp2_slope;
5180 dsamp3_slope = unit->dsamp3_slope;
5181 dsamp4_slope = unit->dsamp4_slope;
5183 ramp1 = unit->ramp1;
5184 ramp2 = unit->ramp2;
5185 ramp3 = unit->ramp3;
5186 ramp4 = unit->ramp4;
5188 ramp1_slope = unit->ramp1_slope;
5189 ramp2_slope = unit->ramp2_slope;
5190 ramp3_slope = unit->ramp3_slope;
5191 ramp4_slope = unit->ramp4_slope;
5193 slope = unit->slope;
5195 remain = inNumSamples;
5196 while (remain) {
5197 if (counter <= 0) {
5198 counter = framesize >> 2;
5199 unit->stage = stage = (stage + 1) & 3;
5200 disppchratio = pchratio;
5201 if (pchdisp != 0.f) {
5202 disppchratio += (pchdisp * frand2(s1,s2,s3));
5204 disppchratio = sc_clip(disppchratio, 0.f, 4.f);
5205 pchratio1 = disppchratio - 1.f;
5206 samp_slope = -pchratio1;
5207 startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
5208 startpos += (timedisp * frand(s1,s2,s3));
5209 switch(stage) {
5210 case 0 :
5211 unit->dsamp1_slope = dsamp1_slope = samp_slope;
5212 dsamp1 = startpos;
5213 ramp1 = 0.0;
5214 unit->ramp1_slope = ramp1_slope = slope;
5215 unit->ramp3_slope = ramp3_slope = -slope;
5216 break;
5217 case 1 :
5218 unit->dsamp2_slope = dsamp2_slope = samp_slope;
5219 dsamp2 = startpos;
5220 ramp2 = 0.0;
5221 unit->ramp2_slope = ramp2_slope = slope;
5222 unit->ramp4_slope = ramp4_slope = -slope;
5223 break;
5224 case 2 :
5225 unit->dsamp3_slope = dsamp3_slope = samp_slope;
5226 dsamp3 = startpos;
5227 ramp3 = 0.0;
5228 unit->ramp3_slope = ramp3_slope = slope;
5229 unit->ramp1_slope = ramp1_slope = -slope;
5230 break;
5231 case 3 :
5232 unit->dsamp4_slope = dsamp4_slope = samp_slope;
5233 dsamp4 = startpos;
5234 ramp4 = 0.0;
5235 unit->ramp2_slope = ramp2_slope = -slope;
5236 unit->ramp4_slope = ramp4_slope = slope;
5237 break;
5239 /*Print("%d %d %g %g %g %g %g %g %g %g %g %g %g %g\n",
5240 counter, stage, dsamp1_slope, dsamp2_slope, dsamp3_slope, dsamp4_slope,
5241 dsamp1, dsamp2, dsamp3, dsamp4,
5242 ramp1, ramp2, ramp3, ramp4);*/
5246 nsmps = sc_min(remain, counter);
5247 remain -= nsmps;
5248 counter -= nsmps;
5250 LOOP(nsmps,
5251 iwrphase = (iwrphase + 1) & mask;
5253 dsamp1 += dsamp1_slope;
5254 idsamp = (long)dsamp1;
5255 frac = dsamp1 - idsamp;
5256 irdphase = (iwrphase - idsamp) & mask;
5257 irdphaseb = (irdphase - 1) & mask;
5258 d1 = dlybuf[irdphase];
5259 d2 = dlybuf[irdphaseb];
5260 value = (d1 + frac * (d2 - d1)) * ramp1;
5261 ramp1 += ramp1_slope;
5263 dsamp2 += dsamp2_slope;
5264 idsamp = (long)dsamp2;
5265 frac = dsamp2 - idsamp;
5266 irdphase = (iwrphase - idsamp) & mask;
5267 irdphaseb = (irdphase - 1) & mask;
5268 d1 = dlybuf[irdphase];
5269 d2 = dlybuf[irdphaseb];
5270 value += (d1 + frac * (d2 - d1)) * ramp2;
5271 ramp2 += ramp2_slope;
5273 dsamp3 += dsamp3_slope;
5274 idsamp = (long)dsamp3;
5275 frac = dsamp3 - idsamp;
5276 irdphase = (iwrphase - idsamp) & mask;
5277 irdphaseb = (irdphase - 1) & mask;
5278 d1 = dlybuf[irdphase];
5279 d2 = dlybuf[irdphaseb];
5280 value += (d1 + frac * (d2 - d1)) * ramp3;
5281 ramp3 += ramp3_slope;
5283 dsamp4 += dsamp4_slope;
5284 idsamp = (long)dsamp4;
5285 frac = dsamp4 - idsamp;
5286 irdphase = (iwrphase - idsamp) & mask;
5287 irdphaseb = (irdphase - 1) & mask;
5288 d1 = dlybuf[irdphase];
5289 d2 = dlybuf[irdphaseb];
5290 value += (d1 + frac * (d2 - d1)) * ramp4;
5291 ramp4 += ramp4_slope;
5293 dlybuf[iwrphase] = ZXP(in);
5294 ZXP(out) = value *= 0.5;
5298 unit->counter = counter;
5300 unit->dsamp1 = dsamp1;
5301 unit->dsamp2 = dsamp2;
5302 unit->dsamp3 = dsamp3;
5303 unit->dsamp4 = dsamp4;
5305 unit->ramp1 = ramp1;
5306 unit->ramp2 = ramp2;
5307 unit->ramp3 = ramp3;
5308 unit->ramp4 = ramp4;
5310 unit->iwrphase = iwrphase;
5312 RPUT
5318 void PitchShift_next_z(PitchShift *unit, int inNumSamples);
5319 void PitchShift_next_z(PitchShift *unit, int inNumSamples)
5321 float *out, *in, *dlybuf;
5322 float disppchratio, pchratio, pchratio1, value;
5323 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5324 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5325 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5326 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5327 float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, winsize, pchdisp, timedisp;
5328 long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase;
5329 long mask, idsamp;
5330 long counter, stage, framesize, numoutput;
5332 RGET
5334 out = ZOUT(0);
5335 in = ZIN(0);
5336 pchratio = ZIN0(2);
5337 winsize = ZIN0(1);
5338 pchdisp = ZIN0(3);
5339 timedisp = ZIN0(4);
5340 timedisp = sc_clip(timedisp, 0.f, winsize) * SAMPLERATE;
5342 dlybuf = unit->dlybuf;
5343 fdelaylen = unit->fdelaylen;
5344 idelaylen = unit->idelaylen;
5345 iwrphase = unit->iwrphase;
5346 numoutput = unit->numoutput;
5348 counter = unit->counter;
5349 stage = unit->stage;
5350 mask = unit->mask;
5351 framesize = unit->framesize;
5353 dsamp1 = unit->dsamp1;
5354 dsamp2 = unit->dsamp2;
5355 dsamp3 = unit->dsamp3;
5356 dsamp4 = unit->dsamp4;
5358 dsamp1_slope = unit->dsamp1_slope;
5359 dsamp2_slope = unit->dsamp2_slope;
5360 dsamp3_slope = unit->dsamp3_slope;
5361 dsamp4_slope = unit->dsamp4_slope;
5363 ramp1 = unit->ramp1;
5364 ramp2 = unit->ramp2;
5365 ramp3 = unit->ramp3;
5366 ramp4 = unit->ramp4;
5368 ramp1_slope = unit->ramp1_slope;
5369 ramp2_slope = unit->ramp2_slope;
5370 ramp3_slope = unit->ramp3_slope;
5371 ramp4_slope = unit->ramp4_slope;
5373 slope = unit->slope;
5375 remain = inNumSamples;
5376 while (remain) {
5377 if (counter <= 0) {
5378 counter = framesize >> 2;
5379 unit->stage = stage = (stage + 1) & 3;
5380 disppchratio = pchratio;
5381 if (pchdisp != 0.f) {
5382 disppchratio += (pchdisp * frand2(s1,s2,s3));
5384 disppchratio = sc_clip(disppchratio, 0.f, 4.f);
5385 pchratio1 = disppchratio - 1.f;
5386 samp_slope = -pchratio1;
5387 startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
5388 startpos += (timedisp * frand(s1,s2,s3));
5389 switch(stage) {
5390 case 0 :
5391 unit->dsamp1_slope = dsamp1_slope = samp_slope;
5392 dsamp1 = startpos;
5393 ramp1 = 0.0;
5394 unit->ramp1_slope = ramp1_slope = slope;
5395 unit->ramp3_slope = ramp3_slope = -slope;
5396 break;
5397 case 1 :
5398 unit->dsamp2_slope = dsamp2_slope = samp_slope;
5399 dsamp2 = startpos;
5400 ramp2 = 0.0;
5401 unit->ramp2_slope = ramp2_slope = slope;
5402 unit->ramp4_slope = ramp4_slope = -slope;
5403 break;
5404 case 2 :
5405 unit->dsamp3_slope = dsamp3_slope = samp_slope;
5406 dsamp3 = startpos;
5407 ramp3 = 0.0;
5408 unit->ramp3_slope = ramp3_slope = slope;
5409 unit->ramp1_slope = ramp1_slope = -slope;
5410 break;
5411 case 3 :
5412 unit->dsamp4_slope = dsamp4_slope = samp_slope;
5413 dsamp4 = startpos;
5414 ramp4 = 0.0;
5415 unit->ramp2_slope = ramp2_slope = -slope;
5416 unit->ramp4_slope = ramp4_slope = slope;
5417 break;
5419 /*Print("z %d %d %g %g %g %g %g %g %g %g %g %g %g %g\n",
5420 counter, stage, dsamp1_slope, dsamp2_slope, dsamp3_slope, dsamp4_slope,
5421 dsamp1, dsamp2, dsamp3, dsamp4,
5422 ramp1, ramp2, ramp3, ramp4);*/
5424 nsmps = sc_min(remain, counter);
5425 remain -= nsmps;
5426 counter -= nsmps;
5428 while (nsmps--) {
5429 numoutput++;
5430 iwrphase = (iwrphase + 1) & mask;
5432 dsamp1 += dsamp1_slope;
5433 idsamp = (long)dsamp1;
5434 frac = dsamp1 - idsamp;
5435 irdphase = (iwrphase - idsamp) & mask;
5436 irdphaseb = (irdphase - 1) & mask;
5437 if (numoutput < idelaylen) {
5438 if (irdphase > iwrphase) {
5439 value = 0.f;
5440 } else if (irdphaseb > iwrphase) {
5441 d1 = dlybuf[irdphase];
5442 value = (d1 - frac * d1) * ramp1;
5443 } else {
5444 d1 = dlybuf[irdphase];
5445 d2 = dlybuf[irdphaseb];
5446 value = (d1 + frac * (d2 - d1)) * ramp1;
5448 } else {
5449 d1 = dlybuf[irdphase];
5450 d2 = dlybuf[irdphaseb];
5451 value = (d1 + frac * (d2 - d1)) * ramp1;
5453 ramp1 += ramp1_slope;
5455 dsamp2 += dsamp2_slope;
5456 idsamp = (long)dsamp2;
5457 frac = dsamp2 - idsamp;
5458 irdphase = (iwrphase - idsamp) & mask;
5459 irdphaseb = (irdphase - 1) & mask;
5460 if (numoutput < idelaylen) {
5461 if (irdphase > iwrphase) {
5462 //value += 0.f;
5463 } else if (irdphaseb > iwrphase) {
5464 d1 = dlybuf[irdphase];
5465 value += (d1 - frac * d1) * ramp2;
5466 } else {
5467 d1 = dlybuf[irdphase];
5468 d2 = dlybuf[irdphaseb];
5469 value += (d1 + frac * (d2 - d1)) * ramp2;
5471 } else {
5472 d1 = dlybuf[irdphase];
5473 d2 = dlybuf[irdphaseb];
5474 value += (d1 + frac * (d2 - d1)) * ramp2;
5476 ramp2 += ramp2_slope;
5478 dsamp3 += dsamp3_slope;
5479 idsamp = (long)dsamp3;
5480 frac = dsamp3 - idsamp;
5481 irdphase = (iwrphase - idsamp) & mask;
5482 irdphaseb = (irdphase - 1) & mask;
5483 if (numoutput < idelaylen) {
5484 if (irdphase > iwrphase) {
5485 //value += 0.f;
5486 } else if (irdphaseb > iwrphase) {
5487 d1 = dlybuf[irdphase];
5488 value += (d1 - frac * d1) * ramp3;
5489 } else {
5490 d1 = dlybuf[irdphase];
5491 d2 = dlybuf[irdphaseb];
5492 value += (d1 + frac * (d2 - d1)) * ramp3;
5494 } else {
5495 d1 = dlybuf[irdphase];
5496 d2 = dlybuf[irdphaseb];
5497 value += (d1 + frac * (d2 - d1)) * ramp3;
5499 ramp3 += ramp3_slope;
5501 dsamp4 += dsamp4_slope;
5502 idsamp = (long)dsamp4;
5503 frac = dsamp4 - idsamp;
5504 irdphase = (iwrphase - idsamp) & mask;
5505 irdphaseb = (irdphase - 1) & mask;
5507 if (numoutput < idelaylen) {
5508 if (irdphase > iwrphase) {
5509 //value += 0.f;
5510 } else if (irdphaseb > iwrphase) {
5511 d1 = dlybuf[irdphase];
5512 value += (d1 - frac * d1) * ramp4;
5513 } else {
5514 d1 = dlybuf[irdphase];
5515 d2 = dlybuf[irdphaseb];
5516 value += (d1 + frac * (d2 - d1)) * ramp4;
5518 } else {
5519 d1 = dlybuf[irdphase];
5520 d2 = dlybuf[irdphaseb];
5521 value += (d1 + frac * (d2 - d1)) * ramp4;
5523 ramp4 += ramp4_slope;
5525 dlybuf[iwrphase] = ZXP(in);
5526 ZXP(out) = value *= 0.5;
5530 unit->counter = counter;
5531 unit->stage = stage;
5532 unit->mask = mask;
5534 unit->dsamp1 = dsamp1;
5535 unit->dsamp2 = dsamp2;
5536 unit->dsamp3 = dsamp3;
5537 unit->dsamp4 = dsamp4;
5539 unit->ramp1 = ramp1;
5540 unit->ramp2 = ramp2;
5541 unit->ramp3 = ramp3;
5542 unit->ramp4 = ramp4;
5544 unit->numoutput = numoutput;
5545 unit->iwrphase = iwrphase;
5547 if (numoutput >= idelaylen) {
5548 SETCALC(PitchShift_next);
5551 RPUT
5555 void PitchShift_Ctor(PitchShift *unit);
5556 void PitchShift_Ctor(PitchShift *unit)
5558 long delaybufsize;
5559 float *out, *in, *dlybuf;
5560 float winsize, pchratio;
5561 float fdelaylen, slope;
5562 long framesize, last;
5564 out = ZOUT(0);
5565 in = ZIN(0);
5566 pchratio = ZIN0(2);
5567 winsize = ZIN0(1);
5569 delaybufsize = (long)ceil(winsize * SAMPLERATE * 3.f + 3.f);
5570 fdelaylen = delaybufsize - 3;
5572 delaybufsize = delaybufsize + BUFLENGTH;
5573 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
5574 dlybuf = (float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
5576 SETCALC(PitchShift_next_z);
5578 *dlybuf = ZIN0(0);
5579 ZOUT0(0) = 0.f;
5581 unit->dlybuf = dlybuf;
5582 unit->idelaylen = delaybufsize;
5583 unit->fdelaylen = fdelaylen;
5584 unit->iwrphase = 0;
5585 unit->numoutput = 0;
5586 unit->mask = last = (delaybufsize - 1);
5588 unit->framesize = framesize = ((long)(winsize * SAMPLERATE) + 2) & ~3;
5589 unit->slope = slope = 2.f / framesize;
5590 unit->stage = 3;
5591 unit->counter = framesize >> 2;
5592 unit->ramp1 = 0.5;
5593 unit->ramp2 = 1.0;
5594 unit->ramp3 = 0.5;
5595 unit->ramp4 = 0.0;
5597 unit->ramp1_slope = -slope;
5598 unit->ramp2_slope = -slope;
5599 unit->ramp3_slope = slope;
5600 unit->ramp4_slope = slope;
5602 dlybuf[last ] = 0.f; // put a few zeroes where we start the read heads
5603 dlybuf[last-1] = 0.f;
5604 dlybuf[last-2] = 0.f;
5606 unit->numoutput = 0;
5608 // start all read heads 2 samples behind the write head
5609 unit->dsamp1 = unit->dsamp2 = unit->dsamp3 = unit->dsamp4 = 2.f;
5610 // pch ratio is initially zero for the read heads
5611 unit->dsamp1_slope = unit->dsamp2_slope = unit->dsamp3_slope = unit->dsamp4_slope = 1.f;
5616 void PitchShift_Dtor(PitchShift *unit)
5618 RTFree(unit->mWorld, unit->dlybuf);
5624 typedef struct graintap1 {
5625 float pos, rate, level, slope, curve;
5626 long counter;
5627 struct graintap1 *next;
5628 } GrainTap1;
5630 #define MAXDGRAINS 32
5632 struct GrainTap : public Unit
5634 float m_fbufnum;
5635 SndBuf *m_buf;
5637 float fdelaylen;
5638 long bufsize, iwrphase;
5639 long nextTime;
5640 GrainTap1 grains[MAXDGRAINS];
5641 GrainTap1 *firstActive, *firstFree;
5645 // coefs: pos, rate, level, slope, curve, counter
5647 void GrainTap_next(GrainTap *unit, int inNumSamples);
5648 void GrainTap_next(GrainTap *unit, int inNumSamples)
5650 float *out, *out0;
5651 const float * dlybuf;
5652 float sdur, rdur, rdur2;
5653 float dsamp, dsamp_slope, fdelaylen, d1, d2, frac;
5654 float level, slope, curve;
5655 float maxpitch, pitch, maxtimedisp, timedisp, density;
5656 long remain, nsmps, irdphase, irdphaseb, iwrphase, iwrphase0;
5657 long idsamp, koffset;
5658 long counter;
5659 uint32 bufsize;
5660 GrainTap1 *grain, *prevGrain, *nextGrain;
5662 GET_BUF_SHARED
5664 RGET
5666 out0 = ZOUT(0);
5668 // bufnum, grainDur, pchRatio, pchDisp, timeDisp, overlap
5669 // 0 1 2 3 4 5
5671 density = ZIN0(5);
5672 density = sc_max(0.0001, density);
5674 bufsize = unit->bufsize;
5675 if (bufsize != bufSamples) {
5676 ClearUnitOutputs(unit, inNumSamples);
5677 return;
5680 dlybuf = bufData;
5681 fdelaylen = unit->fdelaylen;
5682 iwrphase0 = unit->iwrphase;
5684 // initialize buffer to zero
5685 out = out0;
5686 LOOP1(inNumSamples, ZXP(out) = 0.f;);
5688 // do all current grains
5689 prevGrain = NULL;
5690 grain = unit->firstActive;
5691 while (grain) {
5693 dsamp = grain->pos;
5694 dsamp_slope = grain->rate;
5695 level = grain->level;
5696 slope = grain->slope;
5697 curve = grain->curve;
5698 counter = grain->counter;
5700 nsmps = sc_min(counter, inNumSamples);
5701 iwrphase = iwrphase0;
5702 out = out0;
5703 LOOP(nsmps,
5704 dsamp += dsamp_slope;
5705 idsamp = (long)dsamp;
5706 frac = dsamp - idsamp;
5707 iwrphase = (iwrphase + 1) & mask;
5708 irdphase = (iwrphase - idsamp) & mask;
5709 irdphaseb = (irdphase - 1) & mask;
5710 d1 = dlybuf[irdphase];
5711 d2 = dlybuf[irdphaseb];
5712 ZXP(out) += (d1 + frac * (d2 - d1)) * level;
5713 level += slope;
5714 slope += curve;
5716 grain->pos = dsamp;
5717 grain->level = level;
5718 grain->slope = slope;
5719 grain->counter -= nsmps;
5721 nextGrain = grain->next;
5722 if (grain->counter <= 0) {
5723 // unlink from active list
5724 if (prevGrain) prevGrain->next = nextGrain;
5725 else unit->firstActive = nextGrain;
5727 // link onto free list
5728 grain->next = unit->firstFree;
5729 unit->firstFree = grain;
5730 } else {
5731 prevGrain = grain;
5733 grain = nextGrain;
5735 // start new grains
5736 remain = inNumSamples;
5737 while (unit->nextTime <= remain) {
5738 remain -= unit->nextTime;
5739 sdur = ZIN0(1) * SAMPLERATE;
5740 sdur = sc_max(sdur, 4.f);
5742 grain = unit->firstFree;
5743 if (grain) {
5744 unit->firstFree = grain->next;
5745 grain->next = unit->firstActive;
5746 unit->firstActive = grain;
5748 koffset = inNumSamples - remain;
5749 iwrphase = (iwrphase0 + koffset) & mask;
5751 grain->counter = (long)sdur;
5753 timedisp = ZIN0(4);
5754 timedisp = sc_max(timedisp, 0.f);
5755 timedisp = frand(s1,s2,s3) * timedisp * SAMPLERATE;
5757 pitch = ZIN0(2) + frand2(s1,s2,s3) * ZIN0(3);
5758 if (pitch >= 1.f) {
5759 maxpitch = 1.f + (fdelaylen/sdur);
5760 pitch = sc_min(pitch, maxpitch);
5762 dsamp_slope = 1.f - pitch;
5763 grain->rate = dsamp_slope;
5765 maxtimedisp = fdelaylen + sdur * dsamp_slope;
5766 timedisp = sc_min(timedisp, maxtimedisp);
5768 dsamp = BUFLENGTH + koffset + 2.f + timedisp - sdur * dsamp_slope;
5769 dsamp = sc_min(dsamp, fdelaylen);
5770 } else {
5771 maxpitch = -(1.f + (fdelaylen/sdur));
5772 pitch = sc_max(pitch, maxpitch);
5774 dsamp_slope = 1.f - pitch;
5775 grain->rate = dsamp_slope;
5777 maxtimedisp = fdelaylen - sdur * dsamp_slope;
5778 timedisp = sc_min(timedisp, maxtimedisp);
5780 dsamp = BUFLENGTH + koffset + 2.f + timedisp;
5781 dsamp = sc_min(dsamp, fdelaylen);
5784 grain->pos = dsamp;
5785 //postbuf("ds %g %g %g\n", dsamp_slope, dsamp, fdelaylen);
5787 rdur = 1.f / sdur;
5788 rdur2 = rdur * rdur;
5789 grain->level = level = 0.f;
5790 grain->slope = slope = 4.0 * (rdur - rdur2); // ampslope
5791 grain->curve = curve = -8.0 * rdur2; // ampcurve
5793 nsmps = remain;
5794 out = out0 + koffset;
5795 LOOP(nsmps,
5796 dsamp += dsamp_slope;
5797 idsamp = (long)dsamp;
5798 frac = dsamp - idsamp;
5799 iwrphase = (iwrphase + 1) & mask;
5800 irdphase = (iwrphase - idsamp) & mask;
5801 irdphaseb = (irdphase - 1) & mask;
5802 d1 = dlybuf[irdphase];
5803 d2 = dlybuf[irdphaseb];
5804 ZXP(out) += (d1 + frac * (d2 - d1)) * level;
5805 level += slope;
5806 slope += curve;
5808 grain->pos = dsamp;
5809 grain->level = level;
5810 grain->slope = slope;
5811 grain->counter -= nsmps;
5813 if (grain->counter <= 0) {
5814 // unlink from active list
5815 unit->firstActive = grain->next;
5817 // link onto free list
5818 grain->next = unit->firstFree;
5819 unit->firstFree = grain;
5822 unit->nextTime = (long)(sdur / density);
5823 if (unit->nextTime < 1) unit->nextTime = 1;
5825 /*if (grain == NULL) {
5826 postbuf("nextTime %d %g %g %p %p %p\n", unit->nextTime, sdur, density,
5827 grain, unit->firstActive, unit->firstFree);
5830 iwrphase = (iwrphase0 + BUFLENGTH) & mask;
5831 unit->nextTime -= remain;
5832 if (unit->nextTime < 0) unit->nextTime = 0;
5834 unit->iwrphase = iwrphase;
5836 RPUT
5840 void GrainTap_Ctor(GrainTap *unit);
5841 void GrainTap_Ctor(GrainTap *unit)
5843 float fdelaylen;
5844 float maxdelaytime;
5846 GET_BUF
5848 if (!ISPOWEROFTWO(bufSamples)) {
5849 Print("GrainTap buffer size not a power of two.\n");
5850 SETCALC(*ClearUnitOutputs);
5851 return;
5854 fdelaylen = bufSamples - 2 * BUFLENGTH - 3;
5855 maxdelaytime = fdelaylen * SAMPLEDUR;
5857 SETCALC(GrainTap_next);
5859 ZOUT0(0) = 0.f;
5861 unit->bufsize = bufSamples;
5862 unit->fdelaylen = fdelaylen;
5863 unit->iwrphase = 0;
5864 unit->nextTime = 0;
5865 for (int i=0; i<MAXDGRAINS-1; ++i) {
5866 unit->grains[i].next = unit->grains + (i + 1);
5868 unit->grains[MAXDGRAINS-1].next = NULL;
5869 unit->firstFree = unit->grains;
5870 unit->firstActive = NULL;
5876 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5879 #define GRAIN_BUF \
5880 const SndBuf *buf = bufs + bufnum; \
5881 LOCK_SNDBUF_SHARED(buf); \
5882 const float *bufData __attribute__((__unused__)) = buf->data; \
5883 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
5884 uint32 bufSamples __attribute__((__unused__)) = buf->samples; \
5885 uint32 bufFrames = buf->frames; \
5886 int guardFrame __attribute__((__unused__)) = bufFrames - 2; \
5889 inline float IN_AT(Unit* unit, int index, int offset)
5891 if (INRATE(index) == calc_FullRate) return IN(index)[offset];
5892 if (INRATE(index) == calc_DemandRate) return DEMANDINPUT_A(index, offset + 1);
5893 return ZIN0(index);
5896 inline double sc_gloop(double in, double hi)
5898 // avoid the divide if possible
5899 if (in >= hi) {
5900 in -= hi;
5901 if (in < hi) return in;
5902 } else if (in < 0.) {
5903 in += hi;
5904 if (in >= 0.) return in;
5905 } else return in;
5907 return in - hi * floor(in/hi);
5910 #define GRAIN_LOOP_BODY_4 \
5911 float amp = y1 * y1; \
5912 phase = sc_gloop(phase, loopMax); \
5913 int32 iphase = (int32)phase; \
5914 const float* table1 = bufData + iphase; \
5915 const float* table0 = table1 - 1; \
5916 const float* table2 = table1 + 1; \
5917 const float* table3 = table1 + 2; \
5918 if (iphase == 0) { \
5919 table0 += bufSamples; \
5920 } else if (iphase >= guardFrame) { \
5921 if (iphase == guardFrame) { \
5922 table3 -= bufSamples; \
5923 } else { \
5924 table2 -= bufSamples; \
5925 table3 -= bufSamples; \
5928 float fracphase = phase - (double)iphase; \
5929 float a = table0[0]; \
5930 float b = table1[0]; \
5931 float c = table2[0]; \
5932 float d = table3[0]; \
5933 float outval = amp * cubicinterp(fracphase, a, b, c, d); \
5934 ZXP(out1) += outval * pan1; \
5935 ZXP(out2) += outval * pan2; \
5936 double y0 = b1 * y1 - y2; \
5937 y2 = y1; \
5938 y1 = y0; \
5941 #define GRAIN_LOOP_BODY_2 \
5942 float amp = y1 * y1; \
5943 phase = sc_gloop(phase, loopMax); \
5944 int32 iphase = (int32)phase; \
5945 const float* table1 = bufData + iphase; \
5946 const float* table2 = table1 + 1; \
5947 if (iphase > guardFrame) { \
5948 table2 -= bufSamples; \
5950 float fracphase = phase - (double)iphase; \
5951 float b = table1[0]; \
5952 float c = table2[0]; \
5953 float outval = amp * (b + fracphase * (c - b)); \
5954 ZXP(out1) += outval * pan1; \
5955 ZXP(out2) += outval * pan2; \
5956 double y0 = b1 * y1 - y2; \
5957 y2 = y1; \
5958 y1 = y0; \
5961 #define GRAIN_LOOP_BODY_1 \
5962 float amp = y1 * y1; \
5963 phase = sc_gloop(phase, loopMax); \
5964 int32 iphase = (int32)phase; \
5965 float outval = amp * bufData[iphase]; \
5966 ZXP(out1) += outval * pan1; \
5967 ZXP(out2) += outval * pan2; \
5968 double y0 = b1 * y1 - y2; \
5969 y2 = y1; \
5970 y1 = y0; \
5973 void TGrains_next(TGrains *unit, int inNumSamples)
5975 float *trigin = IN(0);
5976 float prevtrig = unit->mPrevTrig;
5978 uint32 numOutputs = unit->mNumOutputs;
5979 ClearUnitOutputs(unit, inNumSamples);
5980 float *out[16];
5981 for (uint32 i=0; i<numOutputs; ++i) out[i] = ZOUT(i);
5983 World *world = unit->mWorld;
5984 SndBuf *bufs = world->mSndBufs;
5985 uint32 numBufs = world->mNumSndBufs;
5987 for (int i=0; i < unit->mNumActive; ) {
5988 Grain *grain = unit->mGrains + i;
5989 uint32 bufnum = grain->bufnum;
5991 GRAIN_BUF
5993 if (bufChannels != 1) {
5994 ++i;
5995 continue;
5998 double loopMax = (double)bufFrames;
6000 float pan1 = grain->pan1;
6001 float pan2 = grain->pan2;
6002 double rate = grain->rate;
6003 double phase = grain->phase;
6004 double b1 = grain->b1;
6005 double y1 = grain->y1;
6006 double y2 = grain->y2;
6008 uint32 chan1 = grain->chan;
6009 uint32 chan2 = chan1 + 1;
6010 if (chan2 >= numOutputs) chan2 = 0;
6012 float *out1 = out[chan1];
6013 float *out2 = out[chan2];
6014 //printf("B chan %d %d %p %p", chan1, chan2, out1, out2);
6016 int nsmps = sc_min(grain->counter, inNumSamples);
6017 if (grain->interp >= 4) {
6018 for (int j=0; j<nsmps; ++j) {
6019 GRAIN_LOOP_BODY_4;
6020 phase += rate;
6022 } else if (grain->interp >= 2) {
6023 for (int j=0; j<nsmps; ++j) {
6024 GRAIN_LOOP_BODY_2;
6025 phase += rate;
6027 } else {
6028 for (int j=0; j<nsmps; ++j) {
6029 GRAIN_LOOP_BODY_1;
6030 phase += rate;
6034 grain->phase = phase;
6035 grain->y1 = y1;
6036 grain->y2 = y2;
6038 grain->counter -= nsmps;
6039 if (grain->counter <= 0) {
6040 // remove grain
6041 *grain = unit->mGrains[--unit->mNumActive];
6042 } else ++i;
6045 int trigSamples = INRATE(0) == calc_FullRate ? inNumSamples : 1;
6047 for (int i=0; i<trigSamples; ++i) {
6048 float trig = trigin[i];
6050 if (trig > 0.f && prevtrig <= 0.f) {
6051 // start a grain
6052 if (unit->mNumActive+1 >= kMaxGrains) break;
6053 uint32 bufnum = (uint32)IN_AT(unit, 1, i);
6054 if (bufnum >= numBufs) continue;
6055 GRAIN_BUF
6057 if (bufChannels != 1) continue;
6059 float bufSampleRate = buf->samplerate;
6060 float bufRateScale = bufSampleRate * SAMPLEDUR;
6061 double loopMax = (double)bufFrames;
6063 Grain *grain = unit->mGrains + unit->mNumActive++;
6064 grain->bufnum = bufnum;
6066 double counter = floor(IN_AT(unit, 4, i) * SAMPLERATE);
6067 counter = sc_max(4., counter);
6068 grain->counter = (int)counter;
6070 double rate = grain->rate = IN_AT(unit, 2, i) * bufRateScale;
6071 double centerPhase = IN_AT(unit, 3, i) * bufSampleRate;
6072 double phase = centerPhase - 0.5 * counter * rate;
6074 float pan = IN_AT(unit, 5, i);
6075 float amp = IN_AT(unit, 6, i);
6076 grain->interp = (int)IN_AT(unit, 7, i);
6078 float panangle;
6079 if (numOutputs > 2) {
6080 pan = sc_wrap(pan * 0.5f, 0.f, 1.f);
6081 float cpan = numOutputs * pan + 0.5;
6082 float ipan = floor(cpan);
6083 float panfrac = cpan - ipan;
6084 panangle = panfrac * pi2_f;
6085 grain->chan = (int)ipan;
6086 if (grain->chan >= (int)numOutputs) grain->chan -= numOutputs;
6087 } else {
6088 grain->chan = 0;
6089 pan = sc_wrap(pan * 0.5f + 0.5f, 0.f, 1.f);
6090 panangle = pan * pi2_f;
6092 float pan1 = grain->pan1 = amp * cos(panangle);
6093 float pan2 = grain->pan2 = amp * sin(panangle);
6094 double w = pi / counter;
6095 double b1 = grain->b1 = 2. * cos(w);
6096 double y1 = sin(w);
6097 double y2 = 0.;
6099 uint32 chan1 = grain->chan;
6100 uint32 chan2 = chan1 + 1;
6101 if (chan2 >= numOutputs) chan2 = 0;
6103 float *out1 = out[chan1] + i;
6104 float *out2 = out[chan2] + i;
6106 int nsmps = sc_min(grain->counter, inNumSamples - i);
6107 if (grain->interp >= 4) {
6108 for (int j=0; j<nsmps; ++j) {
6109 GRAIN_LOOP_BODY_4;
6110 phase += rate;
6112 } else if (grain->interp >= 2) {
6113 for (int j=0; j<nsmps; ++j) {
6114 GRAIN_LOOP_BODY_2;
6115 phase += rate;
6117 } else {
6118 for (int j=0; j<nsmps; ++j) {
6119 GRAIN_LOOP_BODY_1;
6120 phase += rate;
6124 grain->phase = phase;
6125 grain->y1 = y1;
6126 grain->y2 = y2;
6128 grain->counter -= nsmps;
6129 if (grain->counter <= 0) {
6130 // remove grain
6131 *grain = unit->mGrains[--unit->mNumActive];
6134 prevtrig = trig;
6137 unit->mPrevTrig = prevtrig;
6140 void TGrains_Ctor(TGrains *unit)
6142 SETCALC(TGrains_next);
6144 unit->mNumActive = 0;
6145 unit->mPrevTrig = 0.;
6147 ClearUnitOutputs(unit, 1);
6151 ////////////////////////////////////////////////////////////////////////////////////////////////////////
6153 Pluck - Karplus-Strong
6155 void Pluck_Ctor(Pluck *unit)
6157 // FeedbackDelay_Reset(unit);
6158 unit->m_maxdelaytime = IN0(2);
6159 unit->m_delaytime = IN0(3);
6160 unit->m_dlybuf = 0;
6161 bool allocationSucessful = DelayUnit_AllocDelayLine(unit, "Pluck");
6162 if (!allocationSucessful)
6163 return;
6165 unit->m_dsamp = CalcDelay(unit, unit->m_delaytime);
6167 unit->m_numoutput = 0;
6168 unit->m_iwrphase = 0;
6169 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
6171 if (INRATE(1) == calc_FullRate) {
6172 if(INRATE(5) == calc_FullRate){
6173 SETCALC(Pluck_next_aa_z);
6174 } else {
6175 SETCALC(Pluck_next_ak_z); //ak
6177 } else {
6178 if(INRATE(5) == calc_FullRate){
6179 SETCALC(Pluck_next_ka_z); //ka
6180 } else {
6181 SETCALC(Pluck_next_kk_z); //kk
6184 OUT0(0) = unit->m_lastsamp = 0.f;
6185 unit->m_prevtrig = 0.f;
6186 unit->m_inputsamps = 0;
6187 unit->m_coef = IN0(5);
6190 void Pluck_next_aa(Pluck *unit, int inNumSamples)
6192 float *out = OUT(0);
6193 float *in = IN(0);
6194 float *trig = IN(1);
6195 float delaytime = IN0(3);
6196 float decaytime = IN0(4);
6197 float *coef = IN(5);
6198 float lastsamp = unit->m_lastsamp;
6199 unsigned long inputsamps = unit->m_inputsamps;
6201 float *dlybuf = unit->m_dlybuf;
6202 long iwrphase = unit->m_iwrphase;
6203 float dsamp = unit->m_dsamp;
6204 float feedbk = unit->m_feedbk;
6205 long mask = unit->m_mask;
6206 float thisin, curtrig;
6207 float prevtrig = unit->m_prevtrig;
6209 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6210 long idsamp = (long)dsamp;
6211 float frac = dsamp - idsamp;
6212 for(int i = 0; i < inNumSamples; i++){
6213 curtrig = trig[i];
6214 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6215 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6217 prevtrig = curtrig;
6218 long irdphase1 = iwrphase - idsamp;
6219 long irdphase2 = irdphase1 - 1;
6220 long irdphase3 = irdphase1 - 2;
6221 long irdphase0 = irdphase1 + 1;
6222 if (inputsamps > 0) {
6223 thisin = in[i];
6224 --inputsamps;
6225 } else {
6226 thisin = 0.f;
6228 float d0 = dlybuf[irdphase0 & mask];
6229 float d1 = dlybuf[irdphase1 & mask];
6230 float d2 = dlybuf[irdphase2 & mask];
6231 float d3 = dlybuf[irdphase3 & mask];
6232 float value = cubicinterp(frac, d0, d1, d2, d3);
6233 float thiscoef = coef[i];
6234 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6235 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6236 out[i] = lastsamp = onepole;
6237 iwrphase++;
6239 } else {
6241 float next_dsamp = CalcDelay(unit, delaytime);
6242 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6244 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6245 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6247 for(int i = 0; i < inNumSamples; i++){
6248 curtrig = trig[i];
6249 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6250 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6252 prevtrig = curtrig;
6253 dsamp += dsamp_slope;
6254 long idsamp = (long)dsamp;
6255 float frac = dsamp - idsamp;
6256 long irdphase1 = iwrphase - idsamp;
6257 long irdphase2 = irdphase1 - 1;
6258 long irdphase3 = irdphase1 - 2;
6259 long irdphase0 = irdphase1 + 1;
6260 if (inputsamps > 0) {
6261 thisin = in[i];
6262 --inputsamps;
6263 } else {
6264 thisin = 0.f;
6266 float d0 = dlybuf[irdphase0 & mask];
6267 float d1 = dlybuf[irdphase1 & mask];
6268 float d2 = dlybuf[irdphase2 & mask];
6269 float d3 = dlybuf[irdphase3 & mask];
6270 float value = cubicinterp(frac, d0, d1, d2, d3);
6271 float thiscoef = coef[i];
6272 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6273 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6274 out[i] = lastsamp = onepole;
6275 feedbk += feedbk_slope;
6276 iwrphase++;
6278 unit->m_feedbk = feedbk;
6279 unit->m_dsamp = dsamp;
6280 unit->m_delaytime = delaytime;
6281 unit->m_decaytime = decaytime;
6284 unit->m_prevtrig = prevtrig;
6285 unit->m_inputsamps = inputsamps;
6286 unit->m_lastsamp = zapgremlins(lastsamp);
6287 unit->m_iwrphase = iwrphase;
6292 void Pluck_next_aa_z(Pluck *unit, int inNumSamples)
6294 float *out = OUT(0);
6295 float *in = IN(0);
6296 float *trig = IN(1);
6297 float delaytime = IN0(3);
6298 float decaytime = IN0(4);
6299 float *coef = IN(5);
6300 float lastsamp = unit->m_lastsamp;
6302 float *dlybuf = unit->m_dlybuf;
6303 long iwrphase = unit->m_iwrphase;
6304 float dsamp = unit->m_dsamp;
6305 float feedbk = unit->m_feedbk;
6306 long mask = unit->m_mask;
6307 float d0, d1, d2, d3;
6308 float thisin, curtrig;
6309 unsigned long inputsamps = unit->m_inputsamps;
6310 float prevtrig = unit->m_prevtrig;
6312 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6313 long idsamp = (long)dsamp;
6314 float frac = dsamp - idsamp;
6315 for(int i = 0; i < inNumSamples; i++){
6316 curtrig = trig[i];
6317 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6318 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6320 prevtrig = curtrig;
6321 long irdphase1 = iwrphase - idsamp;
6322 long irdphase2 = irdphase1 - 1;
6323 long irdphase3 = irdphase1 - 2;
6324 long irdphase0 = irdphase1 + 1;
6325 if (inputsamps > 0) {
6326 thisin = in[i];
6327 --inputsamps;
6328 } else {
6329 thisin = 0.f;
6331 if (irdphase0 < 0) {
6332 dlybuf[iwrphase & mask] = thisin;
6333 out[i] = 0.f;
6334 } else {
6335 if (irdphase1 < 0) {
6336 d1 = d2 = d3 = 0.f;
6337 d0 = dlybuf[irdphase0 & mask];
6338 } else if (irdphase2 < 0) {
6339 d1 = d2 = d3 = 0.f;
6340 d0 = dlybuf[irdphase0 & mask];
6341 d1 = dlybuf[irdphase1 & mask];
6342 } else if (irdphase3 < 0) {
6343 d3 = 0.f;
6344 d0 = dlybuf[irdphase0 & mask];
6345 d1 = dlybuf[irdphase1 & mask];
6346 d2 = dlybuf[irdphase2 & mask];
6347 } else {
6348 d0 = dlybuf[irdphase0 & mask];
6349 d1 = dlybuf[irdphase1 & mask];
6350 d2 = dlybuf[irdphase2 & mask];
6351 d3 = dlybuf[irdphase3 & mask];
6353 float value = cubicinterp(frac, d0, d1, d2, d3);
6354 float thiscoef = coef[i];
6355 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6356 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6357 out[i] = lastsamp = onepole;
6359 iwrphase++;
6361 } else {
6363 float next_dsamp = CalcDelay(unit, delaytime);
6364 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6366 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6367 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6369 for(int i = 0; i < inNumSamples; i++) {
6370 curtrig = trig[i];
6371 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6372 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6374 prevtrig = curtrig;
6375 dsamp += dsamp_slope;
6376 long idsamp = (long)dsamp;
6377 float frac = dsamp - idsamp;
6378 long irdphase1 = iwrphase - idsamp;
6379 long irdphase2 = irdphase1 - 1;
6380 long irdphase3 = irdphase1 - 2;
6381 long irdphase0 = irdphase1 + 1;
6382 if (inputsamps > 0) {
6383 thisin = in[i];
6384 --inputsamps;
6385 } else {
6386 thisin = 0.f;
6388 if (irdphase0 < 0) {
6389 dlybuf[iwrphase & mask] = thisin;
6390 out[i] = 0.f;
6391 } else {
6392 if (irdphase1 < 0) {
6393 d1 = d2 = d3 = 0.f;
6394 d0 = dlybuf[irdphase0 & mask];
6395 } else if (irdphase2 < 0) {
6396 d1 = d2 = d3 = 0.f;
6397 d0 = dlybuf[irdphase0 & mask];
6398 d1 = dlybuf[irdphase1 & mask];
6399 } else if (irdphase3 < 0) {
6400 d3 = 0.f;
6401 d0 = dlybuf[irdphase0 & mask];
6402 d1 = dlybuf[irdphase1 & mask];
6403 d2 = dlybuf[irdphase2 & mask];
6404 } else {
6405 d0 = dlybuf[irdphase0 & mask];
6406 d1 = dlybuf[irdphase1 & mask];
6407 d2 = dlybuf[irdphase2 & mask];
6408 d3 = dlybuf[irdphase3 & mask];
6410 float value = cubicinterp(frac, d0, d1, d2, d3);
6411 float thiscoef = coef[i];
6412 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6413 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6414 out[i] = lastsamp = onepole;
6416 feedbk += feedbk_slope;
6417 iwrphase++;
6419 unit->m_feedbk = feedbk;
6420 unit->m_dsamp = dsamp;
6421 unit->m_delaytime = delaytime;
6422 unit->m_decaytime = decaytime;
6425 unit->m_inputsamps = inputsamps;
6426 unit->m_prevtrig = prevtrig;
6427 unit->m_lastsamp = zapgremlins(lastsamp);
6428 unit->m_iwrphase = iwrphase;
6430 unit->m_numoutput += inNumSamples;
6431 if (unit->m_numoutput >= unit->m_idelaylen) {
6432 SETCALC(Pluck_next_aa);
6436 void Pluck_next_kk(Pluck *unit, int inNumSamples)
6438 float *out = OUT(0);
6439 float *in = IN(0);
6440 float trig = IN0(1);
6441 float delaytime = IN0(3);
6442 float decaytime = IN0(4);
6443 float coef = IN0(5);
6444 float lastsamp = unit->m_lastsamp;
6445 unsigned long inputsamps = unit->m_inputsamps;
6447 float *dlybuf = unit->m_dlybuf;
6448 long iwrphase = unit->m_iwrphase;
6449 float dsamp = unit->m_dsamp;
6450 float feedbk = unit->m_feedbk;
6451 long mask = unit->m_mask;
6452 float thisin;
6454 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6455 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6457 unit->m_prevtrig = trig;
6459 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6460 long idsamp = (long)dsamp;
6461 float frac = dsamp - idsamp;
6463 for(int i = 0; i < inNumSamples; i++){
6464 long irdphase1 = iwrphase - idsamp;
6465 long irdphase2 = irdphase1 - 1;
6466 long irdphase3 = irdphase1 - 2;
6467 long irdphase0 = irdphase1 + 1;
6468 if (inputsamps > 0) {
6469 thisin = in[i];
6470 --inputsamps;
6471 } else {
6472 thisin = 0.f;
6474 float d0 = dlybuf[irdphase0 & mask];
6475 float d1 = dlybuf[irdphase1 & mask];
6476 float d2 = dlybuf[irdphase2 & mask];
6477 float d3 = dlybuf[irdphase3 & mask];
6478 float value = cubicinterp(frac, d0, d1, d2, d3);
6479 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6480 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6481 out[i] = lastsamp = onepole; //value;
6482 iwrphase++;
6484 } else {
6486 float next_dsamp = CalcDelay(unit, delaytime);
6487 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6489 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6490 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6492 float curcoef = unit->m_coef;
6493 float coef_slope = CALCSLOPE(coef, curcoef);
6495 for(int i = 0; i < inNumSamples; i++){
6496 dsamp += dsamp_slope;
6497 long idsamp = (long)dsamp;
6498 float frac = dsamp - idsamp;
6499 long irdphase1 = iwrphase - idsamp;
6500 long irdphase2 = irdphase1 - 1;
6501 long irdphase3 = irdphase1 - 2;
6502 long irdphase0 = irdphase1 + 1;
6503 if (inputsamps > 0) {
6504 thisin = in[i];
6505 --inputsamps;
6506 } else {
6507 thisin = 0.f;
6509 float d0 = dlybuf[irdphase0 & mask];
6510 float d1 = dlybuf[irdphase1 & mask];
6511 float d2 = dlybuf[irdphase2 & mask];
6512 float d3 = dlybuf[irdphase3 & mask];
6513 float value = cubicinterp(frac, d0, d1, d2, d3);
6514 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6515 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6516 out[i] = lastsamp = onepole; //value;
6517 feedbk += feedbk_slope;
6518 curcoef += coef_slope;
6519 iwrphase++;
6521 unit->m_feedbk = feedbk;
6522 unit->m_coef = coef;
6523 unit->m_dsamp = dsamp;
6524 unit->m_delaytime = delaytime;
6525 unit->m_decaytime = decaytime;
6528 unit->m_inputsamps = inputsamps;
6529 unit->m_lastsamp = zapgremlins(lastsamp);
6530 unit->m_iwrphase = iwrphase;
6535 void Pluck_next_kk_z(Pluck *unit, int inNumSamples)
6537 float *out = OUT(0);
6538 float *in = IN(0);
6539 float trig = IN0(1);
6540 float delaytime = IN0(3);
6541 float decaytime = IN0(4);
6542 float coef = IN0(5);
6543 float lastsamp = unit->m_lastsamp;
6545 float *dlybuf = unit->m_dlybuf;
6546 long iwrphase = unit->m_iwrphase;
6547 float dsamp = unit->m_dsamp;
6548 float feedbk = unit->m_feedbk;
6549 long mask = unit->m_mask;
6550 float d0, d1, d2, d3;
6551 float thisin;
6552 unsigned long inputsamps = unit->m_inputsamps;
6554 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6555 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6557 unit->m_prevtrig = trig;
6559 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6560 long idsamp = (long)dsamp;
6561 float frac = dsamp - idsamp;
6562 for(int i = 0; i < inNumSamples; i++){
6564 long irdphase1 = iwrphase - idsamp;
6565 long irdphase2 = irdphase1 - 1;
6566 long irdphase3 = irdphase1 - 2;
6567 long irdphase0 = irdphase1 + 1;
6568 if (inputsamps > 0) {
6569 thisin = in[i];
6570 --inputsamps;
6571 } else {
6572 thisin = 0.f;
6574 if (irdphase0 < 0) {
6575 dlybuf[iwrphase & mask] = thisin;
6576 out[i] = 0.f;
6577 } else {
6578 if (irdphase1 < 0) {
6579 d1 = d2 = d3 = 0.f;
6580 d0 = dlybuf[irdphase0 & mask];
6581 } else if (irdphase2 < 0) {
6582 d1 = d2 = d3 = 0.f;
6583 d0 = dlybuf[irdphase0 & mask];
6584 d1 = dlybuf[irdphase1 & mask];
6585 } else if (irdphase3 < 0) {
6586 d3 = 0.f;
6587 d0 = dlybuf[irdphase0 & mask];
6588 d1 = dlybuf[irdphase1 & mask];
6589 d2 = dlybuf[irdphase2 & mask];
6590 } else {
6591 d0 = dlybuf[irdphase0 & mask];
6592 d1 = dlybuf[irdphase1 & mask];
6593 d2 = dlybuf[irdphase2 & mask];
6594 d3 = dlybuf[irdphase3 & mask];
6596 float value = cubicinterp(frac, d0, d1, d2, d3);
6597 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6598 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6599 out[i] = lastsamp = onepole; //value;
6601 iwrphase++;
6603 } else {
6605 float next_dsamp = CalcDelay(unit, delaytime);
6606 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6608 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6609 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6611 float curcoef = unit->m_coef;
6612 float coef_slope = CALCSLOPE(coef, curcoef);
6614 for(int i = 0; i < inNumSamples; i++) {
6615 dsamp += dsamp_slope;
6616 long idsamp = (long)dsamp;
6617 float frac = dsamp - idsamp;
6618 long irdphase1 = iwrphase - idsamp;
6619 long irdphase2 = irdphase1 - 1;
6620 long irdphase3 = irdphase1 - 2;
6621 long irdphase0 = irdphase1 + 1;
6622 if (inputsamps > 0) {
6623 thisin = in[i];
6624 --inputsamps;
6625 } else {
6626 thisin = 0.f;
6628 if (irdphase0 < 0) {
6629 dlybuf[iwrphase & mask] = thisin;
6630 out[i] = 0.f;
6631 } else {
6632 if (irdphase1 < 0) {
6633 d1 = d2 = d3 = 0.f;
6634 d0 = dlybuf[irdphase0 & mask];
6635 } else if (irdphase2 < 0) {
6636 d1 = d2 = d3 = 0.f;
6637 d0 = dlybuf[irdphase0 & mask];
6638 d1 = dlybuf[irdphase1 & mask];
6639 } else if (irdphase3 < 0) {
6640 d3 = 0.f;
6641 d0 = dlybuf[irdphase0 & mask];
6642 d1 = dlybuf[irdphase1 & mask];
6643 d2 = dlybuf[irdphase2 & mask];
6644 } else {
6645 d0 = dlybuf[irdphase0 & mask];
6646 d1 = dlybuf[irdphase1 & mask];
6647 d2 = dlybuf[irdphase2 & mask];
6648 d3 = dlybuf[irdphase3 & mask];
6650 float value = cubicinterp(frac, d0, d1, d2, d3);
6651 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6652 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6653 out[i] = lastsamp = onepole; //value;
6655 feedbk += feedbk_slope;
6656 curcoef += coef_slope;
6657 iwrphase++;
6659 unit->m_feedbk = feedbk;
6660 unit->m_dsamp = dsamp;
6661 unit->m_delaytime = delaytime;
6662 unit->m_decaytime = decaytime;
6663 unit->m_coef = coef;
6666 unit->m_inputsamps = inputsamps;
6667 unit->m_lastsamp = zapgremlins(lastsamp);
6668 unit->m_iwrphase = iwrphase;
6670 unit->m_numoutput += inNumSamples;
6671 if (unit->m_numoutput >= unit->m_idelaylen) {
6672 SETCALC(Pluck_next_kk);
6676 void Pluck_next_ak(Pluck *unit, int inNumSamples)
6678 float *out = OUT(0);
6679 float *in = IN(0);
6680 float *trig = IN(1);
6681 float delaytime = IN0(3);
6682 float decaytime = IN0(4);
6683 float coef = IN0(5);
6684 float lastsamp = unit->m_lastsamp;
6685 unsigned long inputsamps = unit->m_inputsamps;
6687 float *dlybuf = unit->m_dlybuf;
6688 long iwrphase = unit->m_iwrphase;
6689 float dsamp = unit->m_dsamp;
6690 float feedbk = unit->m_feedbk;
6691 long mask = unit->m_mask;
6692 float thisin, curtrig;
6693 float prevtrig = unit->m_prevtrig;
6695 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6696 long idsamp = (long)dsamp;
6697 float frac = dsamp - idsamp;
6698 for(int i = 0; i < inNumSamples; i++){
6699 curtrig = trig[i];
6700 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6701 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6703 prevtrig = curtrig;
6704 long irdphase1 = iwrphase - idsamp;
6705 long irdphase2 = irdphase1 - 1;
6706 long irdphase3 = irdphase1 - 2;
6707 long irdphase0 = irdphase1 + 1;
6708 if (inputsamps > 0) {
6709 thisin = in[i];
6710 --inputsamps;
6711 } else {
6712 thisin = 0.f;
6714 float d0 = dlybuf[irdphase0 & mask];
6715 float d1 = dlybuf[irdphase1 & mask];
6716 float d2 = dlybuf[irdphase2 & mask];
6717 float d3 = dlybuf[irdphase3 & mask];
6718 float value = cubicinterp(frac, d0, d1, d2, d3);
6719 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6720 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6721 out[i] = lastsamp = onepole;
6722 iwrphase++;
6724 } else {
6726 float next_dsamp = CalcDelay(unit, delaytime);
6727 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6729 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6730 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6732 float curcoef = unit->m_coef;
6733 float coef_slope = CALCSLOPE(coef, curcoef);
6735 for(int i = 0; i < inNumSamples; i++){
6736 curtrig = trig[i];
6737 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6738 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6740 prevtrig = curtrig;
6741 dsamp += dsamp_slope;
6742 long idsamp = (long)dsamp;
6743 float frac = dsamp - idsamp;
6744 long irdphase1 = iwrphase - idsamp;
6745 long irdphase2 = irdphase1 - 1;
6746 long irdphase3 = irdphase1 - 2;
6747 long irdphase0 = irdphase1 + 1;
6748 if (inputsamps > 0) {
6749 thisin = in[i];
6750 --inputsamps;
6751 } else {
6752 thisin = 0.f;
6754 float d0 = dlybuf[irdphase0 & mask];
6755 float d1 = dlybuf[irdphase1 & mask];
6756 float d2 = dlybuf[irdphase2 & mask];
6757 float d3 = dlybuf[irdphase3 & mask];
6758 float value = cubicinterp(frac, d0, d1, d2, d3);
6759 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6760 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6761 out[i] = lastsamp = onepole;
6762 feedbk += feedbk_slope;
6763 curcoef += coef_slope;
6764 iwrphase++;
6766 unit->m_feedbk = feedbk;
6767 unit->m_dsamp = dsamp;
6768 unit->m_delaytime = delaytime;
6769 unit->m_decaytime = decaytime;
6770 unit->m_coef = coef;
6773 unit->m_prevtrig = prevtrig;
6774 unit->m_inputsamps = inputsamps;
6775 unit->m_lastsamp = zapgremlins(lastsamp);
6776 unit->m_iwrphase = iwrphase;
6781 void Pluck_next_ak_z(Pluck *unit, int inNumSamples)
6783 float *out = OUT(0);
6784 float *in = IN(0);
6785 float *trig = IN(1);
6786 float delaytime = IN0(3);
6787 float decaytime = IN0(4);
6788 float coef = IN0(5);
6789 float lastsamp = unit->m_lastsamp;
6791 float *dlybuf = unit->m_dlybuf;
6792 long iwrphase = unit->m_iwrphase;
6793 float dsamp = unit->m_dsamp;
6794 float feedbk = unit->m_feedbk;
6795 long mask = unit->m_mask;
6796 float d0, d1, d2, d3;
6797 float thisin, curtrig;
6798 unsigned long inputsamps = unit->m_inputsamps;
6799 float prevtrig = unit->m_prevtrig;
6801 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6802 long idsamp = (long)dsamp;
6803 float frac = dsamp - idsamp;
6804 for(int i = 0; i < inNumSamples; i++){
6805 curtrig = trig[i];
6806 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6807 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6809 prevtrig = curtrig;
6810 long irdphase1 = iwrphase - idsamp;
6811 long irdphase2 = irdphase1 - 1;
6812 long irdphase3 = irdphase1 - 2;
6813 long irdphase0 = irdphase1 + 1;
6814 if (inputsamps > 0) {
6815 thisin = in[i];
6816 --inputsamps;
6817 } else {
6818 thisin = 0.f;
6820 if (irdphase0 < 0) {
6821 dlybuf[iwrphase & mask] = thisin;
6822 out[i] = 0.f;
6823 } else {
6824 if (irdphase1 < 0) {
6825 d1 = d2 = d3 = 0.f;
6826 d0 = dlybuf[irdphase0 & mask];
6827 } else if (irdphase2 < 0) {
6828 d1 = d2 = d3 = 0.f;
6829 d0 = dlybuf[irdphase0 & mask];
6830 d1 = dlybuf[irdphase1 & mask];
6831 } else if (irdphase3 < 0) {
6832 d3 = 0.f;
6833 d0 = dlybuf[irdphase0 & mask];
6834 d1 = dlybuf[irdphase1 & mask];
6835 d2 = dlybuf[irdphase2 & mask];
6836 } else {
6837 d0 = dlybuf[irdphase0 & mask];
6838 d1 = dlybuf[irdphase1 & mask];
6839 d2 = dlybuf[irdphase2 & mask];
6840 d3 = dlybuf[irdphase3 & mask];
6842 float value = cubicinterp(frac, d0, d1, d2, d3);
6843 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6844 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6845 out[i] = lastsamp = onepole;
6847 iwrphase++;
6849 } else {
6851 float next_dsamp = CalcDelay(unit, delaytime);
6852 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6854 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6855 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6857 float curcoef = unit->m_coef;
6858 float coef_slope = CALCSLOPE(coef, curcoef);
6860 for(int i = 0; i < inNumSamples; i++) {
6861 curtrig = trig[i];
6862 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6863 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6865 prevtrig = curtrig;
6866 dsamp += dsamp_slope;
6867 long idsamp = (long)dsamp;
6868 float frac = dsamp - idsamp;
6869 long irdphase1 = iwrphase - idsamp;
6870 long irdphase2 = irdphase1 - 1;
6871 long irdphase3 = irdphase1 - 2;
6872 long irdphase0 = irdphase1 + 1;
6873 if (inputsamps > 0) {
6874 thisin = in[i];
6875 --inputsamps;
6876 } else {
6877 thisin = 0.f;
6879 if (irdphase0 < 0) {
6880 dlybuf[iwrphase & mask] = thisin;
6881 out[i] = 0.f;
6882 } else {
6883 if (irdphase1 < 0) {
6884 d1 = d2 = d3 = 0.f;
6885 d0 = dlybuf[irdphase0 & mask];
6886 } else if (irdphase2 < 0) {
6887 d1 = d2 = d3 = 0.f;
6888 d0 = dlybuf[irdphase0 & mask];
6889 d1 = dlybuf[irdphase1 & mask];
6890 } else if (irdphase3 < 0) {
6891 d3 = 0.f;
6892 d0 = dlybuf[irdphase0 & mask];
6893 d1 = dlybuf[irdphase1 & mask];
6894 d2 = dlybuf[irdphase2 & mask];
6895 } else {
6896 d0 = dlybuf[irdphase0 & mask];
6897 d1 = dlybuf[irdphase1 & mask];
6898 d2 = dlybuf[irdphase2 & mask];
6899 d3 = dlybuf[irdphase3 & mask];
6901 float value = cubicinterp(frac, d0, d1, d2, d3);
6902 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6903 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6904 out[i] = lastsamp = onepole;
6906 feedbk += feedbk_slope;
6907 curcoef +=coef_slope;
6908 iwrphase++;
6910 unit->m_feedbk = feedbk;
6911 unit->m_dsamp = dsamp;
6912 unit->m_delaytime = delaytime;
6913 unit->m_decaytime = decaytime;
6914 unit->m_coef = coef;
6917 unit->m_inputsamps = inputsamps;
6918 unit->m_prevtrig = prevtrig;
6919 unit->m_lastsamp = zapgremlins(lastsamp);
6920 unit->m_iwrphase = iwrphase;
6922 unit->m_numoutput += inNumSamples;
6923 if (unit->m_numoutput >= unit->m_idelaylen) {
6924 SETCALC(Pluck_next_ak);
6929 void Pluck_next_ka(Pluck *unit, int inNumSamples)
6931 float *out = OUT(0);
6932 float *in = IN(0);
6933 float trig = IN0(1);
6934 float delaytime = IN0(3);
6935 float decaytime = IN0(4);
6936 float *coef = IN(5);
6937 float lastsamp = unit->m_lastsamp;
6938 unsigned long inputsamps = unit->m_inputsamps;
6940 float *dlybuf = unit->m_dlybuf;
6941 long iwrphase = unit->m_iwrphase;
6942 float dsamp = unit->m_dsamp;
6943 float feedbk = unit->m_feedbk;
6944 long mask = unit->m_mask;
6945 float thisin;
6947 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6948 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6950 unit->m_prevtrig = trig;
6952 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6953 long idsamp = (long)dsamp;
6954 float frac = dsamp - idsamp;
6955 for(int i = 0; i < inNumSamples; i++){
6956 long irdphase1 = iwrphase - idsamp;
6957 long irdphase2 = irdphase1 - 1;
6958 long irdphase3 = irdphase1 - 2;
6959 long irdphase0 = irdphase1 + 1;
6960 if (inputsamps > 0) {
6961 thisin = in[i];
6962 --inputsamps;
6963 } else {
6964 thisin = 0.f;
6966 float d0 = dlybuf[irdphase0 & mask];
6967 float d1 = dlybuf[irdphase1 & mask];
6968 float d2 = dlybuf[irdphase2 & mask];
6969 float d3 = dlybuf[irdphase3 & mask];
6970 float value = cubicinterp(frac, d0, d1, d2, d3);
6971 float thiscoef = coef[i];
6972 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6973 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6974 out[i] = lastsamp = onepole;
6975 iwrphase++;
6977 } else {
6979 float next_dsamp = CalcDelay(unit, delaytime);
6980 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6982 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6983 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6985 for(int i = 0; i < inNumSamples; i++){
6986 dsamp += dsamp_slope;
6987 long idsamp = (long)dsamp;
6988 float frac = dsamp - idsamp;
6989 long irdphase1 = iwrphase - idsamp;
6990 long irdphase2 = irdphase1 - 1;
6991 long irdphase3 = irdphase1 - 2;
6992 long irdphase0 = irdphase1 + 1;
6993 if (inputsamps > 0) {
6994 thisin = in[i];
6995 --inputsamps;
6996 } else {
6997 thisin = 0.f;
6999 float d0 = dlybuf[irdphase0 & mask];
7000 float d1 = dlybuf[irdphase1 & mask];
7001 float d2 = dlybuf[irdphase2 & mask];
7002 float d3 = dlybuf[irdphase3 & mask];
7003 float value = cubicinterp(frac, d0, d1, d2, d3);
7004 float thiscoef = coef[i];
7005 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7006 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7007 out[i] = lastsamp = onepole;
7008 feedbk += feedbk_slope;
7009 iwrphase++;
7011 unit->m_feedbk = feedbk;
7012 unit->m_dsamp = dsamp;
7013 unit->m_delaytime = delaytime;
7014 unit->m_decaytime = decaytime;
7017 unit->m_inputsamps = inputsamps;
7018 unit->m_lastsamp = zapgremlins(lastsamp);
7019 unit->m_iwrphase = iwrphase;
7024 void Pluck_next_ka_z(Pluck *unit, int inNumSamples)
7026 float *out = OUT(0);
7027 float *in = IN(0);
7028 float trig = IN0(1);
7029 float delaytime = IN0(3);
7030 float decaytime = IN0(4);
7031 float *coef = IN(5);
7032 float lastsamp = unit->m_lastsamp;
7034 float *dlybuf = unit->m_dlybuf;
7035 long iwrphase = unit->m_iwrphase;
7036 float dsamp = unit->m_dsamp;
7037 float feedbk = unit->m_feedbk;
7038 long mask = unit->m_mask;
7039 float d0, d1, d2, d3;
7040 float thisin;
7041 unsigned long inputsamps = unit->m_inputsamps;
7043 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
7044 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
7047 unit->m_prevtrig = trig;
7049 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
7050 long idsamp = (long)dsamp;
7051 float frac = dsamp - idsamp;
7052 for(int i = 0; i < inNumSamples; i++){
7053 long irdphase1 = iwrphase - idsamp;
7054 long irdphase2 = irdphase1 - 1;
7055 long irdphase3 = irdphase1 - 2;
7056 long irdphase0 = irdphase1 + 1;
7057 if (inputsamps > 0) {
7058 thisin = in[i];
7059 --inputsamps;
7060 } else {
7061 thisin = 0.f;
7063 if (irdphase0 < 0) {
7064 dlybuf[iwrphase & mask] = thisin;
7065 out[i] = 0.f;
7066 } else {
7067 if (irdphase1 < 0) {
7068 d1 = d2 = d3 = 0.f;
7069 d0 = dlybuf[irdphase0 & mask];
7070 } else if (irdphase2 < 0) {
7071 d1 = d2 = d3 = 0.f;
7072 d0 = dlybuf[irdphase0 & mask];
7073 d1 = dlybuf[irdphase1 & mask];
7074 } else if (irdphase3 < 0) {
7075 d3 = 0.f;
7076 d0 = dlybuf[irdphase0 & mask];
7077 d1 = dlybuf[irdphase1 & mask];
7078 d2 = dlybuf[irdphase2 & mask];
7079 } else {
7080 d0 = dlybuf[irdphase0 & mask];
7081 d1 = dlybuf[irdphase1 & mask];
7082 d2 = dlybuf[irdphase2 & mask];
7083 d3 = dlybuf[irdphase3 & mask];
7085 float value = cubicinterp(frac, d0, d1, d2, d3);
7086 float thiscoef = coef[i];
7087 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7088 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7089 out[i] = lastsamp = onepole;
7091 iwrphase++;
7093 } else {
7095 float next_dsamp = CalcDelay(unit, delaytime);
7096 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
7098 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
7099 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
7101 for(int i = 0; i < inNumSamples; i++) {
7102 dsamp += dsamp_slope;
7103 long idsamp = (long)dsamp;
7104 float frac = dsamp - idsamp;
7105 long irdphase1 = iwrphase - idsamp;
7106 long irdphase2 = irdphase1 - 1;
7107 long irdphase3 = irdphase1 - 2;
7108 long irdphase0 = irdphase1 + 1;
7109 if (inputsamps > 0) {
7110 thisin = in[i];
7111 --inputsamps;
7112 } else {
7113 thisin = 0.f;
7115 if (irdphase0 < 0) {
7116 dlybuf[iwrphase & mask] = thisin;
7117 out[i] = 0.f;
7118 } else {
7119 if (irdphase1 < 0) {
7120 d1 = d2 = d3 = 0.f;
7121 d0 = dlybuf[irdphase0 & mask];
7122 } else if (irdphase2 < 0) {
7123 d1 = d2 = d3 = 0.f;
7124 d0 = dlybuf[irdphase0 & mask];
7125 d1 = dlybuf[irdphase1 & mask];
7126 } else if (irdphase3 < 0) {
7127 d3 = 0.f;
7128 d0 = dlybuf[irdphase0 & mask];
7129 d1 = dlybuf[irdphase1 & mask];
7130 d2 = dlybuf[irdphase2 & mask];
7131 } else {
7132 d0 = dlybuf[irdphase0 & mask];
7133 d1 = dlybuf[irdphase1 & mask];
7134 d2 = dlybuf[irdphase2 & mask];
7135 d3 = dlybuf[irdphase3 & mask];
7137 float value = cubicinterp(frac, d0, d1, d2, d3);
7138 float thiscoef = coef[i];
7139 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7140 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7141 out[i] = lastsamp = onepole;
7143 feedbk += feedbk_slope;
7144 iwrphase++;
7146 unit->m_feedbk = feedbk;
7147 unit->m_dsamp = dsamp;
7148 unit->m_delaytime = delaytime;
7149 unit->m_decaytime = decaytime;
7152 unit->m_inputsamps = inputsamps;
7153 unit->m_lastsamp = zapgremlins(lastsamp);
7154 unit->m_iwrphase = iwrphase;
7156 unit->m_numoutput += inNumSamples;
7157 if (unit->m_numoutput >= unit->m_idelaylen) {
7158 SETCALC(Pluck_next_ka);
7163 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7166 #define DELTAP_BUF \
7167 World *world = unit->mWorld;\
7168 if (bufnum >= world->mNumSndBufs) { \
7169 int localBufNum = bufnum - world->mNumSndBufs; \
7170 Graph *parent = unit->mParent; \
7171 if(localBufNum <= parent->localBufNum) { \
7172 unit->m_buf = parent->mLocalSndBufs + localBufNum; \
7173 } else { \
7174 bufnum = 0; \
7175 unit->m_buf = world->mSndBufs + bufnum; \
7177 } else { \
7178 unit->m_buf = world->mSndBufs + bufnum; \
7180 SndBuf *buf = unit->m_buf; \
7181 float *bufData __attribute__((__unused__)) = buf->data; \
7182 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
7183 uint32 bufSamples = buf->samples; \
7184 uint32 bufFrames = buf->frames; \
7185 int guardFrame __attribute__((__unused__)) = bufFrames - 2; \
7186 double loopMax __attribute__((__unused__)) = (double)bufSamples;
7188 #define CHECK_DELTAP_BUF \
7189 if ((!bufData) || (bufChannels != 1)) { \
7190 unit->mDone = true; \
7191 ClearUnitOutputs(unit, inNumSamples); \
7192 return; \
7196 static void DelTapWr_first(DelTapWr *unit, int inNumSamples)
7198 float fbufnum = IN0(0);
7199 uint32 bufnum = (uint32)fbufnum;
7200 float* in = IN(1);
7201 float* out = OUT(0);
7203 uint32 phase = unit->m_phase;
7205 DELTAP_BUF
7206 CHECK_DELTAP_BUF
7208 // zero out the buffer!
7209 #ifdef NOVA_SIMD
7210 if (nova::vec<float>::is_aligned(bufData)) {
7211 uint32 unroll = bufSamples & (~(nova::vec<float>::size - 1));
7212 nova::zerovec_simd(bufData, unroll);
7214 uint32 remain = bufSamples - unroll;
7215 Clear(remain, bufData + unroll);
7216 } else
7217 Clear(bufSamples, bufData);
7218 #else
7219 Clear(bufSamples, bufData);
7220 #endif
7222 out[0] = (float)phase;
7223 bufData[phase] = in[0];
7224 phase++;
7225 if(phase == bufSamples)
7226 phase -= bufSamples;
7228 unit->m_phase = phase;
7231 void DelTapWr_Ctor(DelTapWr *unit)
7233 if (BUFLENGTH & 15)
7234 SETCALC(DelTapWr_next);
7235 else
7236 SETCALC(DelTapWr_next_simd);
7237 unit->m_phase = 0;
7238 unit->m_fbufnum = -1e9f;
7239 DelTapWr_first(unit, 1);
7242 template <bool simd>
7243 static inline void DelTapWr_perform(DelTapWr *unit, int inNumSamples)
7245 float fbufnum = IN0(0);
7246 uint32 bufnum = (uint32)fbufnum;
7247 const float* in = ZIN(1);
7248 float* out = ZOUT(0);
7249 uint32 * phase_out = (uint32*)out;
7251 uint32 phase = unit->m_phase;
7253 DELTAP_BUF
7254 CHECK_DELTAP_BUF
7256 LOCK_SNDBUF(buf);
7257 int buf_remain = (int)(bufSamples - phase);
7258 if (inNumSamples < buf_remain)
7260 /* fast-path */
7261 #ifdef NOVA_SIMD
7262 if (simd)
7263 nova::copyvec_an_simd(bufData+phase, IN(1), inNumSamples);
7264 else
7265 #endif
7266 Copy(inNumSamples, bufData + phase, IN(1));
7267 LOOP1 (inNumSamples,
7268 ZXP(phase_out) = phase++;
7270 } else {
7271 LOOP1 (inNumSamples,
7272 bufData[phase] = ZXP(in);
7273 ZXP(phase_out) = phase++;
7274 if(phase == bufSamples)
7275 phase -= bufSamples;
7279 unit->m_phase = phase;
7282 void DelTapWr_next(DelTapWr *unit, int inNumSamples)
7284 DelTapWr_perform<false>(unit, inNumSamples);
7287 void DelTapWr_next_simd(DelTapWr *unit, int inNumSamples)
7289 DelTapWr_perform<true>(unit, inNumSamples);
7293 #define SETUP_TAPDELK \
7294 float delTime = unit->m_delTime; \
7295 float newDelTime = IN0(2) * (float)SAMPLERATE; \
7296 float delTimeInc = CALCSLOPE(newDelTime, delTime); \
7297 float * fPhaseIn = IN(1); \
7298 uint32 * iPhaseIn = (uint32*)fPhaseIn; \
7299 uint32 phaseIn = *iPhaseIn; \
7300 float fbufnum = IN0(0); \
7301 uint32 bufnum = (uint32)fbufnum; \
7302 float* out __attribute__((__unused__)) = ZOUT(0); \
7304 #define SETUP_TAPDELA \
7305 float* delTime = ZIN(2); \
7306 float * fPhaseIn = IN(1); \
7307 uint32 * iPhaseIn = (uint32*)fPhaseIn; \
7308 uint32 phaseIn = *iPhaseIn; \
7309 float fbufnum = IN0(0); \
7310 uint32 bufnum = (uint32)fbufnum; \
7311 float* out = ZOUT(0); \
7313 void DelTapRd_Ctor(DelTapRd *unit)
7315 unit->m_fbufnum = -1e9f;
7316 unit->m_delTime = IN0(2) * SAMPLERATE;
7317 int interp = (int)IN0(3);
7318 if (INRATE(2) == calc_FullRate) {
7319 if (interp == 2)
7320 SETCALC(DelTapRd_next2_a);
7321 else if (interp == 4)
7322 SETCALC(DelTapRd_next4_a);
7323 else
7324 SETCALC(DelTapRd_next1_a);
7325 } else {
7326 if (interp == 2)
7327 SETCALC(DelTapRd_next2_k);
7328 else if (interp == 4)
7329 SETCALC(DelTapRd_next4_k);
7330 else
7331 if (BUFLENGTH & 15)
7332 SETCALC(DelTapRd_next1_k);
7333 else {
7334 SETCALC(DelTapRd_next1_k_simd);
7335 DelTapRd_next1_k(unit, 1);
7336 return;
7339 (unit->mCalcFunc)(unit, 1);
7343 void DelTapRd_next1_a(DelTapRd *unit, int inNumSamples)
7345 SETUP_TAPDELA
7346 DELTAP_BUF
7347 CHECK_DELTAP_BUF
7349 LOCK_SNDBUF_SHARED(buf);
7350 LOOP1(inNumSamples,
7351 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7352 double phase = phaseIn - curDelTimeSamps;
7353 if(phase < 0.) phase += loopMax;
7354 if(phase >=loopMax) phase -= loopMax;
7355 int32 iphase = (int32)phase;
7356 ZXP(out) = bufData[iphase];
7357 phaseIn += 1.;
7361 template <bool simd>
7362 inline void DelTapRd_perform1_k(DelTapRd *unit, int inNumSamples)
7364 SETUP_TAPDELK
7365 DELTAP_BUF
7366 CHECK_DELTAP_BUF
7367 float * zout = ZOUT(0);
7369 LOCK_SNDBUF_SHARED(buf);
7370 if (delTime == newDelTime)
7372 double phase = (double)phaseIn - delTime;
7373 int32 iphase = (int32)phase;
7374 if ( (iphase >= 0) // lower bound
7375 && iphase + inNumSamples < (bufSamples - 1)) //upper bound
7377 #ifdef NOVA_SIMD
7378 if (simd)
7379 nova::copyvec_na_simd(OUT(0), bufData + iphase, inNumSamples);
7380 else
7381 #endif
7382 Copy(inNumSamples, OUT(0), bufData + iphase);
7384 else
7385 LOOP1(inNumSamples,
7386 if(iphase < 0) iphase += bufSamples;
7387 if(iphase >= bufSamples) iphase -= bufSamples;
7388 ZXP(zout) = bufData[iphase];
7389 ++iphase;
7391 } else {
7392 LOOP1(inNumSamples,
7393 double phase = (double)phaseIn - delTime;
7394 if(phase < 0.) phase += loopMax;
7395 if(phase >=loopMax) phase -= loopMax;
7396 int32 iphase = (int32)phase;
7397 ZXP(zout) = bufData[iphase];
7398 delTime += delTimeInc;
7399 ++phaseIn;
7401 unit->m_delTime = delTime;
7405 void DelTapRd_next1_k(DelTapRd *unit, int inNumSamples)
7407 DelTapRd_perform1_k<false>(unit, inNumSamples);
7410 void DelTapRd_next1_k_simd(DelTapRd *unit, int inNumSamples)
7412 DelTapRd_perform1_k<true>(unit, inNumSamples);
7415 void DelTapRd_next2_k(DelTapRd *unit, int inNumSamples)
7417 SETUP_TAPDELK
7418 DELTAP_BUF
7419 CHECK_DELTAP_BUF
7421 int32 iloopMax = (int32)bufSamples;
7423 LOCK_SNDBUF_SHARED(buf);
7425 if (delTime == newDelTime)
7427 double phase = (double)phaseIn - delTime;
7428 double dphase;
7429 float fracphase = std::modf(phase, &dphase);
7430 int32 iphase = (int32)dphase;
7432 if ( (phase >= 0) // lower bound
7433 && phase + inNumSamples < (loopMax - 2)) //upper bound
7435 LOOP1(inNumSamples,
7436 int32 iphase1 = iphase + 1;
7437 float b = bufData[iphase];
7438 float c = bufData[iphase1];
7439 ZXP(out) = (b + fracphase * (c - b));
7440 iphase += 1;
7442 } else {
7443 LOOP1(inNumSamples,
7444 if(iphase < 0) iphase += iloopMax;
7445 else if(iphase >= bufSamples) phase -= iloopMax;
7446 int32 iphase1 = iphase + 1;
7447 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7448 float b = bufData[iphase];
7449 float c = bufData[iphase1];
7450 ZXP(out) = (b + fracphase * (c - b));
7451 ++iphase;
7454 } else {
7455 LOOP1(inNumSamples,
7456 double phase = (double)phaseIn - delTime;
7457 if(phase < 0.) phase += loopMax;
7458 if(phase >= loopMax) phase -= loopMax;
7459 int32 iphase = (int32)phase;
7460 int32 iphase1 = iphase + 1;
7461 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7462 float fracphase = phase - (double)iphase;
7463 float b = bufData[iphase];
7464 float c = bufData[iphase1];
7465 ZXP(out) = (b + fracphase * (c - b));
7466 delTime += delTimeInc;
7467 ++phaseIn;
7469 unit->m_delTime = delTime;
7473 void DelTapRd_next2_a(DelTapRd *unit, int inNumSamples)
7475 SETUP_TAPDELA
7476 DELTAP_BUF
7477 CHECK_DELTAP_BUF
7479 int32 iloopMax = (int32)bufSamples;
7481 LOCK_SNDBUF_SHARED(buf);
7482 LOOP1(inNumSamples,
7483 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7484 double phase = (double)phaseIn - curDelTimeSamps;
7485 if(phase < 0.) phase += loopMax;
7486 if(phase >= loopMax) phase -= loopMax;
7487 int32 iphase = (int32)phase;
7488 int32 iphase1 = iphase + 1;
7489 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7490 float fracphase = phase - (double)iphase;
7491 float b = bufData[iphase];
7492 float c = bufData[iphase1];
7493 ZXP(out) = (b + fracphase * (c - b));
7494 ++phaseIn;
7498 void DelTapRd_next4_k(DelTapRd *unit, int inNumSamples)
7500 SETUP_TAPDELK
7501 DELTAP_BUF
7502 CHECK_DELTAP_BUF
7504 int32 iloopMax = (int32)loopMax;
7506 LOCK_SNDBUF_SHARED(buf);
7509 if (delTime == newDelTime)
7511 double phase = (double)phaseIn - delTime;
7512 double dphase;
7513 float fracphase = std::modf(phase, &dphase);
7514 int32 iphase = (int32)dphase;
7516 if ( (iphase >= 1) // lower bound
7517 && iphase + inNumSamples < (iloopMax - 4)) //upper bound
7519 LOOP1(inNumSamples,
7520 int32 iphase0 = iphase - 1;
7521 int32 iphase1 = iphase + 1;
7522 int32 iphase2 = iphase + 2;
7524 float a = bufData[iphase0];
7525 float b = bufData[iphase];
7526 float c = bufData[iphase1];
7527 float d = bufData[iphase2];
7528 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7529 ++iphase;
7531 } else {
7532 LOOP1(inNumSamples,
7533 if(iphase < 0) iphase += iloopMax;
7534 else if(iphase >= iloopMax) iphase -= iloopMax;
7535 int32 iphase0 = iphase - 1;
7536 int32 iphase1 = iphase + 1;
7537 int32 iphase2 = iphase + 2;
7539 if(iphase0 < 0) iphase0 += iloopMax;
7540 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7541 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7543 float a = bufData[iphase0];
7544 float b = bufData[iphase];
7545 float c = bufData[iphase1];
7546 float d = bufData[iphase2];
7547 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7548 ++iphase;
7551 } else {
7552 LOOP1(inNumSamples,
7553 double phase = (double)phaseIn - delTime;
7554 double dphase;
7555 float fracphase = std::modf(phase, &dphase);
7556 int32 iphase = (int32)dphase;
7558 if(iphase < 0.) iphase += iloopMax;
7559 if(iphase >= iloopMax) iphase -= iloopMax;
7560 int32 iphase0 = iphase - 1;
7561 int32 iphase1 = iphase + 1;
7562 int32 iphase2 = iphase + 2;
7564 if(iphase0 < 0) iphase0 += iloopMax;
7565 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7566 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7568 float a = bufData[iphase0];
7569 float b = bufData[iphase];
7570 float c = bufData[iphase1];
7571 float d = bufData[iphase2];
7572 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7573 delTime += delTimeInc;
7574 ++phaseIn;
7576 unit->m_delTime = delTime;
7580 void DelTapRd_next4_a(DelTapRd *unit, int inNumSamples)
7582 SETUP_TAPDELA
7583 DELTAP_BUF
7584 CHECK_DELTAP_BUF
7586 int32 iloopMax = (int32)loopMax;
7588 LOCK_SNDBUF_SHARED(buf);
7589 LOOP1(inNumSamples,
7590 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7591 double phase = (double)phaseIn - curDelTimeSamps;
7592 if(phase < 0.) phase += loopMax;
7593 if(phase >= loopMax) phase -= loopMax;
7594 int32 iphase = (int32)phase;
7595 int32 iphase0 = iphase - 1;
7596 int32 iphase1 = iphase + 1;
7597 int32 iphase2 = iphase + 2;
7599 if(iphase0 < 0) iphase0 += iloopMax;
7600 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7601 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7603 float fracphase = phase - (double)iphase;
7604 float a = bufData[iphase0];
7605 float b = bufData[iphase];
7606 float c = bufData[iphase1];
7607 float d = bufData[iphase2];
7608 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7609 ++phaseIn;
7614 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7617 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7619 PluginLoad(Delay)
7621 ft = inTable;
7623 #define DefineInfoUnit(name) \
7624 (*ft->fDefineUnit)(#name, sizeof(Unit), (UnitCtorFunc)&name##_Ctor, 0, 0);
7626 DefineInfoUnit(ControlRate);
7627 DefineInfoUnit(SampleRate);
7628 DefineInfoUnit(SampleDur);
7629 DefineInfoUnit(ControlDur);
7630 DefineInfoUnit(SubsampleOffset);
7631 DefineInfoUnit(RadiansPerSample);
7632 DefineInfoUnit(NumInputBuses);
7633 DefineInfoUnit(NumOutputBuses);
7634 DefineInfoUnit(NumAudioBuses);
7635 DefineInfoUnit(NumControlBuses);
7636 DefineInfoUnit(NumBuffers);
7637 DefineInfoUnit(NumRunningSynths);
7639 #define DefineBufInfoUnit(name) \
7640 (*ft->fDefineUnit)(#name, sizeof(BufInfoUnit), (UnitCtorFunc)&name##_Ctor, 0, 0);
7642 DefineBufInfoUnit(BufSampleRate);
7643 DefineBufInfoUnit(BufRateScale);
7644 DefineBufInfoUnit(BufSamples);
7645 DefineBufInfoUnit(BufFrames);
7646 DefineBufInfoUnit(BufChannels);
7647 DefineBufInfoUnit(BufDur);
7649 DefineSimpleCantAliasUnit(PlayBuf);
7650 #if NOTYET
7651 DefineSimpleUnit(SimpleLoopBuf);
7652 #endif
7653 DefineDtorUnit(RecordBuf);
7654 DefineSimpleUnit(BufRd);
7655 DefineSimpleUnit(BufWr);
7656 DefineDtorUnit(Pitch);
7658 DefineSimpleUnit(BufDelayN);
7659 DefineSimpleUnit(BufDelayL);
7660 DefineSimpleUnit(BufDelayC);
7661 DefineSimpleUnit(BufCombN);
7662 DefineSimpleUnit(BufCombL);
7663 DefineSimpleUnit(BufCombC);
7664 DefineSimpleUnit(BufAllpassN);
7665 DefineSimpleUnit(BufAllpassL);
7666 DefineSimpleUnit(BufAllpassC);
7668 #define DefineDelayUnit(name) \
7669 (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
7670 (UnitDtorFunc)&DelayUnit_Dtor, 0);
7672 DefineDelayUnit(DelayN);
7673 DefineDelayUnit(DelayL);
7674 DefineDelayUnit(DelayC);
7675 DefineDelayUnit(CombN);
7676 DefineDelayUnit(CombL);
7677 DefineDelayUnit(CombC);
7678 DefineDelayUnit(AllpassN);
7679 DefineDelayUnit(AllpassL);
7680 DefineDelayUnit(AllpassC);
7682 DefineDtorUnit(PitchShift);
7683 DefineSimpleUnit(GrainTap);
7684 DefineSimpleCantAliasUnit(TGrains);
7685 DefineDtorUnit(ScopeOut);
7686 DefineDtorUnit(ScopeOut2);
7687 DefineDelayUnit(Pluck);
7689 DefineSimpleUnit(DelTapWr);
7690 DefineSimpleUnit(DelTapRd);
7692 DefineDtorUnit(LocalBuf);
7693 DefineSimpleUnit(MaxLocalBufs);
7694 DefineSimpleUnit(SetBuf);
7695 DefineSimpleUnit(ClearBuf);
7698 //////////////////////////////////////////////////////////////////////////////////////////////////