class library: SynthDef - replaceUGen fixes
[supercollider.git] / server / plugins / DelayUGens.cpp
blob269b15ffae4262fdddf9a1653ffe5896cd06007a
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifdef NOVA_SIMD
22 #include "simd_memory.hpp"
23 #endif
25 #include "SC_PlugIn.h"
26 #include <cstdio>
28 using namespace std; // for math functions
31 const int kMAXMEDIANSIZE = 32;
33 static InterfaceTable *ft;
35 struct ScopeOut : public Unit
37 SndBuf *m_buf;
38 SndBufUpdates *m_bufupdates;
39 float m_fbufnum;
40 uint32 m_framepos, m_framecount;
41 float **mIn;
44 struct PlayBuf : public Unit
46 double m_phase;
47 float m_prevtrig;
48 float m_fbufnum;
49 SndBuf *m_buf;
53 struct Grain
55 double phase, rate;
56 double b1, y1, y2; // envelope
57 float pan1, pan2;
58 int counter;
59 int bufnum;
60 int chan;
61 int interp;
64 const int kMaxGrains = 64;
66 struct TGrains : public Unit
68 float mPrevTrig;
69 int mNumActive;
70 Grain mGrains[kMaxGrains];
74 #if NOTYET
75 struct SimpleLoopBuf : public Unit
77 int m_phase;
78 float m_prevtrig;
79 float m_fbufnum;
80 SndBuf *m_buf;
82 #endif
84 struct BufRd : public Unit
86 float m_fbufnum;
87 SndBuf *m_buf;
90 struct BufWr : public Unit
92 float m_fbufnum;
93 SndBuf *m_buf;
96 struct RecordBuf : public Unit
98 float m_fbufnum;
99 SndBuf *m_buf;
100 int32 m_writepos;
101 float m_recLevel, m_preLevel;
102 float m_prevtrig;
103 float **mIn;
106 struct Pitch : public Unit
108 float m_values[kMAXMEDIANSIZE];
109 int m_ages[kMAXMEDIANSIZE];
110 float *m_buffer;
112 float m_freq, m_minfreq, m_maxfreq, m_hasfreq, m_srate, m_ampthresh, m_peakthresh;
113 int m_minperiod, m_maxperiod, m_execPeriod, m_index, m_readp, m_size;
114 int m_downsamp, m_maxlog2bins, m_medianSize;
115 int m_state;
116 bool m_getClarity;
119 struct InterpolationUnit
121 static const int minDelaySamples = 1;
124 struct CubicInterpolationUnit
126 static const int minDelaySamples = 2;
129 struct BufDelayUnit : public Unit
131 float m_fbufnum;
132 SndBuf *m_buf;
133 float m_dsamp;
134 float m_delaytime;
135 int m_iwrphase;
136 uint32 m_numoutput;
139 struct BufDelayN : public BufDelayUnit, InterpolationUnit
142 struct BufDelayL : public BufDelayUnit, InterpolationUnit
145 struct BufDelayC : public BufDelayUnit, CubicInterpolationUnit
148 struct BufFeedbackDelay : public BufDelayUnit
150 float m_feedbk, m_decaytime;
153 struct BufCombN : public BufFeedbackDelay, InterpolationUnit
156 struct BufCombL : public BufFeedbackDelay, InterpolationUnit
159 struct BufCombC : public BufFeedbackDelay, CubicInterpolationUnit
162 struct BufAllpassN : public BufFeedbackDelay, InterpolationUnit
165 struct BufAllpassL : public BufFeedbackDelay, InterpolationUnit
168 struct BufAllpassC : public BufFeedbackDelay, CubicInterpolationUnit
171 struct DelayUnit : public Unit
173 float *m_dlybuf;
175 float m_dsamp, m_fdelaylen;
176 float m_delaytime, m_maxdelaytime;
177 long m_iwrphase, m_idelaylen, m_mask;
178 long m_numoutput;
181 struct DelayN : public DelayUnit, InterpolationUnit
184 struct DelayL : public DelayUnit, InterpolationUnit
187 struct DelayC : public DelayUnit, InterpolationUnit
190 struct FeedbackDelay : public DelayUnit
192 float m_feedbk, m_decaytime;
195 struct CombN : public FeedbackDelay, InterpolationUnit
198 struct CombL : public FeedbackDelay, InterpolationUnit
201 struct CombC : public FeedbackDelay, CubicInterpolationUnit
204 struct AllpassN : public FeedbackDelay, InterpolationUnit
207 struct AllpassL : public FeedbackDelay, InterpolationUnit
210 struct AllpassC : public FeedbackDelay, CubicInterpolationUnit
213 struct BufInfoUnit : public Unit
215 float m_fbufnum;
216 SndBuf *m_buf;
219 struct Pluck : public FeedbackDelay, CubicInterpolationUnit
221 float m_lastsamp, m_prevtrig, m_coef;
222 long m_inputsamps;
225 struct LocalBuf : public Unit
227 float m_fbufnum;
228 SndBuf *m_buf;
231 struct MaxLocalBufs : public Unit
235 struct SetBuf : public Unit
237 float m_fbufnum;
238 SndBuf *m_buf;
241 struct ClearBuf : public Unit
243 float m_fbufnum;
244 SndBuf *m_buf;
247 struct DelTapWr : public Unit
249 SndBuf *m_buf;
250 float m_fbufnum;
251 uint32 m_phase;
254 struct DelTapRd : public Unit
256 SndBuf *m_buf;
257 float m_fbufnum, m_delTime;
261 //////////////////////////////////////////////////////////////////////////////////////////////////
263 extern "C"
266 void SampleRate_Ctor(Unit *unit, int inNumSamples);
267 void ControlRate_Ctor(Unit *unit, int inNumSamples);
268 void SampleDur_Ctor(Unit *unit, int inNumSamples);
269 void ControlDur_Ctor(Unit *unit, int inNumSamples);
270 void SubsampleOffset_Ctor(Unit *unit, int inNumSamples);
271 void RadiansPerSample_Ctor(Unit *unit, int inNumSamples);
272 void NumInputBuses_Ctor(Unit *unit, int inNumSamples);
273 void NumOutputBuses_Ctor(Unit *unit, int inNumSamples);
274 void NumAudioBuses_Ctor(Unit *unit, int inNumSamples);
275 void NumControlBuses_Ctor(Unit *unit, int inNumSamples);
276 void NumBuffers_Ctor(Unit *unit, int inNumSamples);
277 void NumRunningSynths_Ctor(Unit *unit, int inNumSamples);
278 void NumRunningSynths_next(Unit *unit, int inNumSamples);
280 void BufSampleRate_next(BufInfoUnit *unit, int inNumSamples);
281 void BufSampleRate_Ctor(BufInfoUnit *unit, int inNumSamples);
283 void BufFrames_next(BufInfoUnit *unit, int inNumSamples);
284 void BufFrames_Ctor(BufInfoUnit *unit, int inNumSamples);
286 void BufDur_next(BufInfoUnit *unit, int inNumSamples);
287 void BufDur_Ctor(BufInfoUnit *unit, int inNumSamples);
289 void BufChannels_next(BufInfoUnit *unit, int inNumSamples);
290 void BufChannels_Ctor(BufInfoUnit *unit, int inNumSamples);
292 void BufSamples_next(BufInfoUnit *unit, int inNumSamples);
293 void BufSamples_Ctor(BufInfoUnit *unit, int inNumSamples);
295 void BufRateScale_next(BufInfoUnit *unit, int inNumSamples);
296 void BufRateScale_Ctor(BufInfoUnit *unit, int inNumSamples);
298 void PlayBuf_next_aa(PlayBuf *unit, int inNumSamples);
299 void PlayBuf_next_ak(PlayBuf *unit, int inNumSamples);
300 void PlayBuf_next_ka(PlayBuf *unit, int inNumSamples);
301 void PlayBuf_next_kk(PlayBuf *unit, int inNumSamples);
302 void PlayBuf_Ctor(PlayBuf* unit);
304 void TGrains_next(TGrains *unit, int inNumSamples);
305 void TGrains_Ctor(TGrains* unit);
307 #if NOTYET
308 void SimpleLoopBuf_next_kk(SimpleLoopBuf *unit, int inNumSamples);
309 void SimpleLoopBuf_Ctor(SimpleLoopBuf* unit);
310 void SimpleLoopBuf_Dtor(SimpleLoopBuf* unit);
311 #endif
313 void BufRd_Ctor(BufRd *unit);
314 void BufRd_next_4(BufRd *unit, int inNumSamples);
315 void BufRd_next_2(BufRd *unit, int inNumSamples);
316 void BufRd_next_1(BufRd *unit, int inNumSamples);
318 void BufWr_Ctor(BufWr *unit);
319 void BufWr_next(BufWr *unit, int inNumSamples);
321 void RecordBuf_Ctor(RecordBuf *unit);
322 void RecordBuf_Dtor(RecordBuf *unit);
323 void RecordBuf_next(RecordBuf *unit, int inNumSamples);
324 void RecordBuf_next_10(RecordBuf *unit, int inNumSamples);
326 void Pitch_Ctor(Pitch *unit);
327 void Pitch_next_a(Pitch *unit, int inNumSamples);
328 void Pitch_next_k(Pitch *unit, int inNumSamples);
330 void LocalBuf_Ctor(LocalBuf *unit);
331 void LocalBuf_Dtor(LocalBuf *unit);
332 void LocalBuf_next(LocalBuf *unit, int inNumSamples);
334 void MaxLocalBufs_Ctor(MaxLocalBufs *unit);
336 void SetBuf_Ctor(SetBuf *unit);
337 void SetBuf_next(SetBuf *unit, int inNumSamples);
338 void ClearBuf_Ctor(ClearBuf *unit);
339 void ClearBuf_next(ClearBuf *unit, int inNumSamples);
341 void BufDelayN_Ctor(BufDelayN *unit);
342 void BufDelayN_next(BufDelayN *unit, int inNumSamples);
343 void BufDelayN_next_z(BufDelayN *unit, int inNumSamples);
344 void BufDelayN_next_a(BufDelayN *unit, int inNumSamples);
345 void BufDelayN_next_a_z(BufDelayN *unit, int inNumSamples);
347 void BufDelayL_Ctor(BufDelayL *unit);
348 void BufDelayL_next(BufDelayL *unit, int inNumSamples);
349 void BufDelayL_next_z(BufDelayL *unit, int inNumSamples);
350 void BufDelayL_next_a(BufDelayL *unit, int inNumSamples);
351 void BufDelayL_next_a_z(BufDelayL *unit, int inNumSamples);
353 void BufDelayC_Ctor(BufDelayC *unit);
354 void BufDelayC_next(BufDelayC *unit, int inNumSamples);
355 void BufDelayC_next_z(BufDelayC *unit, int inNumSamples);
356 void BufDelayC_next_a(BufDelayC *unit, int inNumSamples);
357 void BufDelayC_next_a_z(BufDelayC *unit, int inNumSamples);
359 void BufCombN_Ctor(BufCombN *unit);
360 void BufCombN_next(BufCombN *unit, int inNumSamples);
361 void BufCombN_next_z(BufCombN *unit, int inNumSamples);
362 void BufCombN_next_a(BufCombN *unit, int inNumSamples);
363 void BufCombN_next_a_z(BufCombN *unit, int inNumSamples);
365 void BufCombL_Ctor(BufCombL *unit);
366 void BufCombL_next(BufCombL *unit, int inNumSamples);
367 void BufCombL_next_z(BufCombL *unit, int inNumSamples);
368 void BufCombL_next_a(BufCombL *unit, int inNumSamples);
369 void BufCombL_next_a_z(BufCombL *unit, int inNumSamples);
371 void BufCombC_Ctor(BufCombC *unit);
372 void BufCombC_next(BufCombC *unit, int inNumSamples);
373 void BufCombC_next_z(BufCombC *unit, int inNumSamples);
374 void BufCombC_next_a(BufCombC *unit, int inNumSamples);
375 void BufCombC_next_a_z(BufCombC *unit, int inNumSamples);
377 void BufAllpassN_Ctor(BufAllpassN *unit);
378 void BufAllpassN_next(BufAllpassN *unit, int inNumSamples);
379 void BufAllpassN_next_z(BufAllpassN *unit, int inNumSamples);
380 void BufAllpassN_next_a(BufAllpassN *unit, int inNumSamples);
381 void BufAllpassN_next_a_z(BufAllpassN *unit, int inNumSamples);
383 void BufAllpassL_Ctor(BufAllpassL *unit);
384 void BufAllpassL_next(BufAllpassL *unit, int inNumSamples);
385 void BufAllpassL_next_z(BufAllpassL *unit, int inNumSamples);
386 void BufAllpassL_next_a(BufAllpassL *unit, int inNumSamples);
387 void BufAllpassL_next_a_z(BufAllpassL *unit, int inNumSamples);
389 void BufAllpassC_Ctor(BufAllpassC *unit);
390 void BufAllpassC_next(BufAllpassC *unit, int inNumSamples);
391 void BufAllpassC_next_z(BufAllpassC *unit, int inNumSamples);
392 void BufAllpassC_next_a(BufAllpassC *unit, int inNumSamples);
393 void BufAllpassC_next_a_z(BufAllpassC *unit, int inNumSamples);
395 void DelayUnit_Dtor(DelayUnit *unit);
397 void DelayN_Ctor(DelayN *unit);
398 void DelayN_next(DelayN *unit, int inNumSamples);
399 void DelayN_next_z(DelayN *unit, int inNumSamples);
400 void DelayN_next_a(DelayN *unit, int inNumSamples);
401 void DelayN_next_a_z(DelayN *unit, int inNumSamples);
403 void DelayL_Ctor(DelayL *unit);
404 void DelayL_next(DelayL *unit, int inNumSamples);
405 void DelayL_next_z(DelayL *unit, int inNumSamples);
406 void DelayL_next_a(DelayL *unit, int inNumSamples);
407 void DelayL_next_a_z(DelayL *unit, int inNumSamples);
409 void DelayC_Ctor(DelayC *unit);
410 void DelayC_next(DelayC *unit, int inNumSamples);
411 void DelayC_next_z(DelayC *unit, int inNumSamples);
412 void DelayC_next_a(DelayC *unit, int inNumSamples);
413 void DelayC_next_a_z(DelayC *unit, int inNumSamples);
415 void CombN_Ctor(CombN *unit);
416 void CombN_next(CombN *unit, int inNumSamples);
417 void CombN_next_z(CombN *unit, int inNumSamples);
418 void CombN_next_a(CombN *unit, int inNumSamples);
419 void CombN_next_a_z(CombN *unit, int inNumSamples);
421 void CombL_Ctor(CombL *unit);
422 void CombL_next(CombL *unit, int inNumSamples);
423 void CombL_next_z(CombL *unit, int inNumSamples);
424 void CombL_next_a(CombL *unit, int inNumSamples);
425 void CombL_next_a_z(CombL *unit, int inNumSamples);
427 void CombC_Ctor(CombC *unit);
428 void CombC_next(CombC *unit, int inNumSamples);
429 void CombC_next_z(CombC *unit, int inNumSamples);
430 void CombC_next_a(CombC *unit, int inNumSamples);
431 void CombC_next_a_z(CombC *unit, int inNumSamples);
433 void AllpassN_Ctor(AllpassN *unit);
434 void AllpassN_next(AllpassN *unit, int inNumSamples);
435 void AllpassN_next_z(AllpassN *unit, int inNumSamples);
436 void AllpassN_next_a(AllpassN *unit, int inNumSamples);
437 void AllpassN_next_a_z(AllpassN *unit, int inNumSamples);
439 void AllpassL_Ctor(AllpassL *unit);
440 void AllpassL_next(AllpassL *unit, int inNumSamples);
441 void AllpassL_next_z(AllpassL *unit, int inNumSamples);
442 void AllpassL_next_a(AllpassL *unit, int inNumSamples);
443 void AllpassL_next_a_z(AllpassL *unit, int inNumSamples);
445 void AllpassC_Ctor(AllpassC *unit);
446 void AllpassC_next(AllpassC *unit, int inNumSamples);
447 void AllpassC_next_z(AllpassC *unit, int inNumSamples);
448 void AllpassC_next_a(AllpassC *unit, int inNumSamples);
449 void AllpassC_next_a_z(AllpassC *unit, int inNumSamples);
451 void ScopeOut_next(ScopeOut *unit, int inNumSamples);
452 void ScopeOut_Ctor(ScopeOut *unit);
453 void ScopeOut_Dtor(ScopeOut *unit);
455 void Pluck_Ctor(Pluck* unit);
456 void Pluck_next_aa(Pluck *unit, int inNumSamples);
457 void Pluck_next_aa_z(Pluck *unit, int inNumSamples);
458 void Pluck_next_kk(Pluck *unit, int inNumSamples);
459 void Pluck_next_kk_z(Pluck *unit, int inNumSamples);
460 void Pluck_next_ka(Pluck *unit, int inNumSamples);
461 void Pluck_next_ka_z(Pluck *unit, int inNumSamples);
462 void Pluck_next_ak(Pluck *unit, int inNumSamples);
463 void Pluck_next_ak_z(Pluck *unit, int inNumSamples);
465 void DelTapWr_Ctor(DelTapWr* unit);
466 void DelTapWr_next(DelTapWr *unit, int inNumSamples);
467 void DelTapWr_next_simd(DelTapWr *unit, int inNumSamples);
469 void DelTapRd_Ctor(DelTapRd* unit);
470 void DelTapRd_next1_a(DelTapRd *unit, int inNumSamples);
471 void DelTapRd_next2_a(DelTapRd *unit, int inNumSamples);
472 void DelTapRd_next4_a(DelTapRd *unit, int inNumSamples);
473 void DelTapRd_next1_k(DelTapRd *unit, int inNumSamples);
474 void DelTapRd_next1_k_simd(DelTapRd *unit, int inNumSamples);
475 void DelTapRd_next2_k(DelTapRd *unit, int inNumSamples);
476 void DelTapRd_next4_k(DelTapRd *unit, int inNumSamples);
479 //////////////////////////////////////////////////////////////////////////////////////////////////
481 void SampleRate_Ctor(Unit *unit, int inNumSamples)
483 ZOUT0(0) = unit->mWorld->mSampleRate;
487 void ControlRate_Ctor(Unit *unit, int inNumSamples)
489 ZOUT0(0) = unit->mWorld->mBufRate.mSampleRate;
493 void SampleDur_Ctor(Unit *unit, int inNumSamples)
495 ZOUT0(0) = unit->mWorld->mFullRate.mSampleDur;
498 void ControlDur_Ctor(Unit *unit, int inNumSamples)
500 ZOUT0(0) = unit->mWorld->mFullRate.mBufDuration;
503 void RadiansPerSample_Ctor(Unit *unit, int inNumSamples)
505 ZOUT0(0) = unit->mWorld->mFullRate.mRadiansPerSample;
508 void SubsampleOffset_Ctor(Unit *unit, int inNumSamples)
510 ZOUT0(0) = unit->mParent->mSubsampleOffset;
514 void NumInputBuses_Ctor(Unit *unit, int inNumSamples)
516 ZOUT0(0) = unit->mWorld->mNumInputs;
519 void NumOutputBuses_Ctor(Unit *unit, int inNumSamples)
521 ZOUT0(0) = unit->mWorld->mNumOutputs;
524 void NumAudioBuses_Ctor(Unit *unit, int inNumSamples)
526 ZOUT0(0) = unit->mWorld->mNumAudioBusChannels;
529 void NumControlBuses_Ctor(Unit *unit, int inNumSamples)
531 ZOUT0(0) = unit->mWorld->mNumControlBusChannels;
534 void NumBuffers_Ctor(Unit *unit, int inNumSamples)
536 ZOUT0(0) = unit->mWorld->mNumSndBufs;
539 //////////////////////////////////////////////////////////////////////////////////////////////////
541 void NumRunningSynths_Ctor(Unit *unit, int inNumSamples)
543 if(INRATE(0) != calc_ScalarRate) { SETCALC(NumRunningSynths_next); }
544 ZOUT0(0) = unit->mWorld->mNumGraphs;
547 void NumRunningSynths_next(Unit *unit, int inNumSamples)
549 ZOUT0(0) = unit->mWorld->mNumGraphs;
553 //////////////////////////////////////////////////////////////////////////////////////////////////
555 void BufSampleRate_next(BufInfoUnit *unit, int inNumSamples)
557 SIMPLE_GET_BUF_SHARED
558 ZOUT0(0) = buf->samplerate;
561 void BufSampleRate_Ctor(BufInfoUnit *unit, int inNumSamples)
563 SETCALC(BufSampleRate_next);
564 unit->m_fbufnum = -1e9f;
565 SIMPLE_GET_BUF_SHARED
566 ZOUT0(0) = buf->samplerate;
570 void BufFrames_next(BufInfoUnit *unit, int inNumSamples)
572 SIMPLE_GET_BUF_SHARED
573 ZOUT0(0) = buf->frames;
576 void BufFrames_Ctor(BufInfoUnit *unit, int inNumSamples)
578 SETCALC(BufFrames_next);
579 unit->m_fbufnum = -1.f;
580 SIMPLE_GET_BUF_SHARED
581 ZOUT0(0) = buf->frames;
585 void BufDur_next(BufInfoUnit *unit, int inNumSamples)
587 SIMPLE_GET_BUF
588 ZOUT0(0) = buf->frames * buf->sampledur;
591 void BufDur_Ctor(BufInfoUnit *unit, int inNumSamples)
593 SETCALC(BufDur_next);
594 unit->m_fbufnum = -1e9f;
595 SIMPLE_GET_BUF_SHARED
596 ZOUT0(0) = buf->frames * buf->sampledur;
600 void BufChannels_next(BufInfoUnit *unit, int inNumSamples)
602 SIMPLE_GET_BUF_SHARED
603 ZOUT0(0) = buf->channels;
606 void BufChannels_Ctor(BufInfoUnit *unit, int inNumSamples)
608 SETCALC(BufChannels_next);
609 unit->m_fbufnum = -1e9f;
610 SIMPLE_GET_BUF_SHARED
611 ZOUT0(0) = buf->channels;
615 void BufSamples_next(BufInfoUnit *unit, int inNumSamples)
617 SIMPLE_GET_BUF_SHARED
618 ZOUT0(0) = buf->samples;
621 void BufSamples_Ctor(BufInfoUnit *unit, int inNumSamples)
623 SETCALC(BufSamples_next);
624 unit->m_fbufnum = -1e9f;
625 SIMPLE_GET_BUF_SHARED
626 ZOUT0(0) = buf->samples;
630 void BufRateScale_next(BufInfoUnit *unit, int inNumSamples)
632 SIMPLE_GET_BUF_SHARED
633 ZOUT0(0) = buf->samplerate * unit->mWorld->mFullRate.mSampleDur;
636 void BufRateScale_Ctor(BufInfoUnit *unit, int inNumSamples)
638 SETCALC(BufRateScale_next);
639 unit->m_fbufnum = -1e9f;
640 SIMPLE_GET_BUF_SHARED
641 ZOUT0(0) = buf->samplerate * unit->mWorld->mFullRate.mSampleDur;
644 //////////////////////////////////////////////////////////////////////////////////////////////////
646 inline int32 BUFMASK(int32 x)
648 return (1 << (31 - CLZ(x))) - 1;
652 static void LocalBuf_allocBuffer(LocalBuf *unit, SndBuf *buf, int numChannels, int numFrames)
654 int numSamples = numFrames * numChannels;
655 // Print("bufnum: %i, allocating %i channels and %i frames. memsize: %i\n", (int)unit->m_fbufnum, numChannels, numFrames, numSamples * sizeof(float));
656 buf->data = (float*)RTAlloc(unit->mWorld, numSamples * sizeof(float));
658 if (!buf->data) {
659 if(unit->mWorld->mVerbosity > -2){
660 Print("failed to allocate memory for LocalBuffer\n");
662 return;
665 buf->channels = numChannels;
666 buf->frames = numFrames;
667 buf->samples = numSamples;
668 buf->mask = BUFMASK(numSamples); // for delay lines
669 buf->mask1 = buf->mask - 1; // for oscillators
670 buf->samplerate = unit->mWorld->mSampleRate;
671 buf->sampledur = 1. / buf->samplerate;
677 void LocalBuf_Ctor(LocalBuf *unit)
679 Graph *parent = unit->mParent;
681 int offset = unit->mWorld->mNumSndBufs;
682 int bufnum = parent->localBufNum;
684 if (parent->localBufNum >= parent->localMaxBufNum) {
685 unit->m_fbufnum = -1.f;
686 if(unit->mWorld->mVerbosity > -2){
687 printf("warning: LocalBuf tried to allocate too many local buffers.\n");
690 } else {
692 unit->m_fbufnum = (float) (bufnum + offset);
693 unit->m_buf = parent->mLocalSndBufs + bufnum;
694 parent->localBufNum = parent->localBufNum + 1;
696 LocalBuf_allocBuffer(unit, unit->m_buf, (int)IN0(0), (int)IN0(1));
699 OUT0(0) = unit->m_fbufnum;
703 void LocalBuf_Dtor(LocalBuf *unit)
705 RTFree(unit->mWorld, unit->m_buf->data);
706 if(unit->mParent->localBufNum <= 1) { // only the last time.
707 for (int i = 0; i != unit->mParent->localMaxBufNum; ++i)
708 unit->mParent->mLocalSndBufs[i].~SndBuf();
709 RTFree(unit->mWorld, unit->mParent->mLocalSndBufs);
710 unit->mParent->localMaxBufNum = 0;
711 } else {
712 unit->mParent->localBufNum = unit->mParent->localBufNum - 1;
716 // dummy for unit size.
717 void LocalBuf_next(LocalBuf *unit, int inNumSamples) {}
720 //////////////////////////////////////////////////////////////////////////////////////////////////
722 void MaxLocalBufs_Ctor(MaxLocalBufs *unit)
724 Graph *parent = unit->mParent;
726 int offset = unit->mWorld->mNumSndBufs;
727 int bufnum = parent->localBufNum;
728 int maxBufNum = (int)(IN0(0) + .5f);
729 if(!parent->localMaxBufNum) {
730 parent->mLocalSndBufs = (SndBuf*)RTAlloc(unit->mWorld, maxBufNum * sizeof(SndBuf));
731 #ifdef SUPERNOVA
732 for (int i = 0; i != maxBufNum; ++i)
733 new(&parent->mLocalSndBufs[i]) SndBuf();
734 #endif
735 parent->localMaxBufNum = maxBufNum;
736 } else {
737 printf("warning: MaxLocalBufs - maximum number of local buffers is already declared (%i) and must remain unchanged.\n", parent->localMaxBufNum);
742 //////////////////////////////////////////////////////////////////////////////////////////////////
745 void SetBuf_next(SetBuf *unit, int inNumSamples)
747 GET_BUF
748 if (!bufData) {
749 if(unit->mWorld->mVerbosity > -2){
750 Print("SetBuf: no valid buffer\n");
752 return;
755 int offset = (int)IN0(1);
756 int numArgs = (int)IN0(2);
757 int end = sc_min(buf->samples, numArgs + offset);
759 int j = 3;
760 for(int i=offset; i<end; ++j, ++i) {
761 bufData[i] = (float)IN0(j);
766 void SetBuf_Ctor(SetBuf *unit)
768 unit->m_fbufnum = -1.f;
769 SETCALC(SetBuf_next);
770 OUT0(0) = 0.f;
771 SetBuf_next(unit, 0);
775 //////////////////////////////////////////////////////////////////////////////////////////////////
778 void ClearBuf_next(ClearBuf *unit, int inNumSamples)
780 GET_BUF
781 if (!bufData) {
782 if(unit->mWorld->mVerbosity > -2){
783 Print("ClearBuf: no valid buffer\n");
785 return;
787 int n = unit->m_buf->samples;
789 //bzero(unit->m_buf->data, unit->m_buf->samples * sizeof(float));
790 for (int i=0; i<n; ++i) {
791 bufData[i] = 0.f;
795 void ClearBuf_Ctor(ClearBuf *unit)
797 unit->m_fbufnum = -1.f;
798 SETCALC(ClearBuf_next);
799 OUT0(0) = 0.f;
800 ClearBuf_next(unit, 0);
804 ////////////////////////////////////////////////////////////////////////////////////////////////////////
806 inline double sc_loop(Unit *unit, double in, double hi, int loop)
808 // avoid the divide if possible
809 if (in >= hi) {
810 if (!loop) {
811 unit->mDone = true;
812 return hi;
814 in -= hi;
815 if (in < hi) return in;
816 } else if (in < 0.) {
817 if (!loop) {
818 unit->mDone = true;
819 return 0.;
821 in += hi;
822 if (in >= 0.) return in;
823 } else return in;
825 return in - hi * floor(in/hi);
828 #define CHECK_BUF \
829 if (!bufData) { \
830 unit->mDone = true; \
831 ClearUnitOutputs(unit, inNumSamples); \
832 return; \
835 static inline bool checkBuffer(Unit * unit, const float * bufData, uint32 bufChannels,
836 uint32 expectedChannels, int inNumSamples)
838 if (!bufData)
839 goto handle_failure;
841 if (expectedChannels > bufChannels) {
842 if(unit->mWorld->mVerbosity > -1 && !unit->mDone)
843 Print("Buffer UGen channel mismatch: expected %i, yet buffer has %i channels\n",
844 expectedChannels, bufChannels);
845 goto handle_failure;
847 return true;
849 handle_failure:
850 unit->mDone = true;
851 ClearUnitOutputs(unit, inNumSamples);
852 return false;
855 #define SETUP_IN(offset) \
856 uint32 numInputs = unit->mNumInputs - (uint32)offset; \
857 if (numInputs != bufChannels) { \
858 if(unit->mWorld->mVerbosity > -1 && !unit->mDone){ \
859 Print("buffer-writing UGen channel mismatch: numInputs %i, yet buffer has %i channels\n", numInputs, bufChannels); \
861 unit->mDone = true; \
862 ClearUnitOutputs(unit, inNumSamples); \
863 return; \
865 if(!unit->mIn){ \
866 unit->mIn = (float**)RTAlloc(unit->mWorld, numInputs * sizeof(float*)); \
867 if (unit->mIn == NULL) { \
868 unit->mDone = true; \
869 ClearUnitOutputs(unit, inNumSamples); \
870 return; \
873 float **in = unit->mIn; \
874 for (uint32 i=0; i<numInputs; ++i) { \
875 in[i] = ZIN(i+offset); \
878 #define TAKEDOWN_IN \
879 if(unit->mIn){ \
880 RTFree(unit->mWorld, unit->mIn); \
884 #define LOOP_BODY_4(SAMPLE_INDEX) \
885 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
886 int32 iphase = (int32)phase; \
887 const float* table1 = bufData + iphase * bufChannels; \
888 const float* table0 = table1 - bufChannels; \
889 const float* table2 = table1 + bufChannels; \
890 const float* table3 = table2 + bufChannels; \
891 if (iphase == 0) { \
892 if (loop) { \
893 table0 += bufSamples; \
894 } else { \
895 table0 += bufChannels; \
897 } else if (iphase >= guardFrame) { \
898 if (iphase == guardFrame) { \
899 if (loop) { \
900 table3 -= bufSamples; \
901 } else { \
902 table3 -= bufChannels; \
904 } else { \
905 if (loop) { \
906 table2 -= bufSamples; \
907 table3 -= bufSamples; \
908 } else { \
909 table2 -= bufChannels; \
910 table3 -= 2 * bufChannels; \
914 int32 index = 0; \
915 float fracphase = phase - (double)iphase; \
916 for (uint32 channel=0; channel<numOutputs; ++channel) { \
917 float a = table0[index]; \
918 float b = table1[index]; \
919 float c = table2[index]; \
920 float d = table3[index]; \
921 OUT(channel)[SAMPLE_INDEX] = cubicinterp(fracphase, a, b, c, d); \
922 index++; \
925 #define LOOP_BODY_2(SAMPLE_INDEX) \
926 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
927 int32 iphase = (int32)phase; \
928 const float* table1 = bufData + iphase * bufChannels; \
929 const float* table2 = table1 + bufChannels; \
930 if (iphase > guardFrame) { \
931 if (loop) { \
932 table2 -= bufSamples; \
933 } else { \
934 table2 -= bufChannels; \
937 int32 index = 0; \
938 float fracphase = phase - (double)iphase; \
939 for (uint32 channel=0; channel<numOutputs; ++channel) { \
940 float b = table1[index]; \
941 float c = table2[index]; \
942 OUT(channel)[SAMPLE_INDEX] = b + fracphase * (c - b); \
943 index++; \
946 #define LOOP_BODY_1(SAMPLE_INDEX) \
947 phase = sc_loop((Unit*)unit, phase, loopMax, loop); \
948 int32 iphase = (int32)phase; \
949 const float* table1 = bufData + iphase * bufChannels; \
950 int32 index = 0; \
951 for (uint32 channel=0; channel<numOutputs; ++channel) { \
952 OUT(channel)[SAMPLE_INDEX] = table1[index++]; \
956 void PlayBuf_Ctor(PlayBuf *unit)
958 if (INRATE(1) == calc_FullRate) {
959 if (INRATE(2) == calc_FullRate) {
960 SETCALC(PlayBuf_next_aa);
961 } else {
962 SETCALC(PlayBuf_next_ak);
964 } else {
965 if (INRATE(2) == calc_FullRate) {
966 SETCALC(PlayBuf_next_ka);
967 } else {
968 SETCALC(PlayBuf_next_kk);
972 unit->m_fbufnum = -1e9f;
973 unit->m_prevtrig = 0.;
974 unit->m_phase = ZIN0(3);
976 ClearUnitOutputs(unit, 1);
979 void PlayBuf_next_aa(PlayBuf *unit, int inNumSamples)
981 float *ratein = ZIN(1);
982 float *trigin = ZIN(2);
983 int32 loop = (int32)ZIN0(4);
985 float fbufnum = ZIN0(0);
986 if (fbufnum != unit->m_fbufnum) {
987 uint32 bufnum = (int)fbufnum;
988 World *world = unit->mWorld;
989 if (bufnum >= world->mNumSndBufs) bufnum = 0;
990 unit->m_fbufnum = fbufnum;
991 unit->m_buf = world->mSndBufs + bufnum;
993 const SndBuf *buf = unit->m_buf;
994 ACQUIRE_SNDBUF_SHARED(buf);
995 const float *bufData __attribute__((__unused__)) = buf->data;
996 uint32 bufChannels __attribute__((__unused__)) = buf->channels;
997 uint32 bufSamples __attribute__((__unused__)) = buf->samples;
998 uint32 bufFrames = buf->frames;
999 int mask __attribute__((__unused__)) = buf->mask;
1000 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
1002 int numOutputs = unit->mNumOutputs;
1003 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1004 return;
1006 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1007 double phase = unit->m_phase;
1008 float prevtrig = unit->m_prevtrig;
1010 for (int i=0; i<inNumSamples; ++i) {
1011 float trig = ZXP(trigin);
1012 if (trig > 0.f && prevtrig <= 0.f) {
1013 unit->mDone = false;
1014 phase = ZIN0(3);
1016 prevtrig = trig;
1018 LOOP_BODY_4(i)
1020 phase += ZXP(ratein);
1022 RELEASE_SNDBUF_SHARED(buf);
1024 if(unit->mDone)
1025 DoneAction((int)ZIN0(5), unit);
1026 unit->m_phase = phase;
1027 unit->m_prevtrig = prevtrig;
1030 void PlayBuf_next_ak(PlayBuf *unit, int inNumSamples)
1032 float *ratein = ZIN(1);
1033 float trig = ZIN0(2);
1034 int32 loop = (int32)ZIN0(4);
1036 float fbufnum = ZIN0(0);
1037 if (fbufnum != unit->m_fbufnum) {
1038 uint32 bufnum = (int)fbufnum;
1039 World *world = unit->mWorld;
1040 if (bufnum >= world->mNumSndBufs) bufnum = 0;
1041 unit->m_fbufnum = fbufnum;
1042 unit->m_buf = world->mSndBufs + bufnum;
1044 const SndBuf *buf = unit->m_buf;
1045 ACQUIRE_SNDBUF_SHARED(buf);
1046 const float *bufData __attribute__((__unused__)) = buf->data;
1047 uint32 bufChannels __attribute__((__unused__)) = buf->channels;
1048 uint32 bufSamples __attribute__((__unused__)) = buf->samples;
1049 uint32 bufFrames = buf->frames;
1050 int mask __attribute__((__unused__)) = buf->mask;
1051 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
1053 int numOutputs = unit->mNumOutputs;
1054 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1055 return;
1057 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1058 double phase = unit->m_phase;
1059 if(phase == -1.) phase = bufFrames;
1060 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1061 unit->mDone = false;
1062 phase = ZIN0(3);
1064 unit->m_prevtrig = trig;
1065 for (int i=0; i<inNumSamples; ++i) {
1067 LOOP_BODY_4(i)
1069 phase += ZXP(ratein);
1071 RELEASE_SNDBUF_SHARED(buf);
1072 if(unit->mDone)
1073 DoneAction((int)ZIN0(5), unit);
1074 unit->m_phase = phase;
1077 void PlayBuf_next_kk(PlayBuf *unit, int inNumSamples)
1079 float rate = ZIN0(1);
1080 float trig = ZIN0(2);
1081 int32 loop = (int32)ZIN0(4);
1083 GET_BUF_SHARED
1084 int numOutputs = unit->mNumOutputs;
1085 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1086 return;
1088 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1089 double phase = unit->m_phase;
1090 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1091 unit->mDone = false;
1092 phase = ZIN0(3);
1094 unit->m_prevtrig = trig;
1095 for (int i=0; i<inNumSamples; ++i) {
1096 LOOP_BODY_4(i)
1098 phase += rate;
1100 if(unit->mDone)
1101 DoneAction((int)ZIN0(5), unit);
1102 unit->m_phase = phase;
1105 void PlayBuf_next_ka(PlayBuf *unit, int inNumSamples)
1107 float rate = ZIN0(1);
1108 float *trigin = ZIN(2);
1109 int32 loop = (int32)ZIN0(4);
1111 GET_BUF_SHARED
1112 int numOutputs = unit->mNumOutputs;
1113 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1114 return;
1116 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1117 double phase = unit->m_phase;
1118 float prevtrig = unit->m_prevtrig;
1119 for (int i=0; i<inNumSamples; ++i) {
1120 float trig = ZXP(trigin);
1121 if (trig > 0.f && prevtrig <= 0.f) {
1122 unit->mDone = false;
1123 if (INRATE(3) == calc_FullRate) phase = IN(3)[i];
1124 else phase = ZIN0(3);
1126 prevtrig = trig;
1128 LOOP_BODY_4(i)
1130 phase += rate;
1132 if(unit->mDone)
1133 DoneAction((int)ZIN0(5), unit);
1134 unit->m_phase = phase;
1135 unit->m_prevtrig = prevtrig;
1139 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1141 void BufRd_Ctor(BufRd *unit)
1143 int interp = (int)ZIN0(3);
1144 switch (interp) {
1145 case 1 : SETCALC(BufRd_next_1); break;
1146 case 2 : SETCALC(BufRd_next_2); break;
1147 default : SETCALC(BufRd_next_4); break;
1150 unit->m_fbufnum = -1e9f;
1152 BufRd_next_1(unit, 1);
1155 void BufRd_next_4(BufRd *unit, int inNumSamples)
1157 float *phasein = ZIN(1);
1158 int32 loop = (int32)ZIN0(2);
1160 GET_BUF_SHARED
1161 uint32 numOutputs = unit->mNumOutputs;
1162 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1163 return;
1165 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1167 for (int i=0; i<inNumSamples; ++i) {
1168 double phase = ZXP(phasein);
1169 LOOP_BODY_4(i)
1173 void BufRd_next_2(BufRd *unit, int inNumSamples)
1175 float *phasein = ZIN(1);
1176 int32 loop = (int32)ZIN0(2);
1178 GET_BUF_SHARED
1179 uint32 numOutputs = unit->mNumOutputs;
1180 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1181 return;
1183 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1185 for (int i=0; i<inNumSamples; ++i) {
1186 double phase = ZXP(phasein);
1187 LOOP_BODY_2(i)
1191 void BufRd_next_1(BufRd *unit, int inNumSamples)
1193 float *phasein = ZIN(1);
1194 int32 loop = (int32)ZIN0(2);
1196 GET_BUF_SHARED
1197 uint32 numOutputs = unit->mNumOutputs;
1198 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
1199 return;
1201 double loopMax = (double)(loop ? bufFrames : bufFrames - 1);
1203 for (int i=0; i<inNumSamples; ++i) {
1204 double phase = ZXP(phasein);
1205 LOOP_BODY_1(i)
1209 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1211 void BufWr_Ctor(BufWr *unit)
1213 SETCALC(BufWr_next);
1215 unit->m_fbufnum = -1e9f;
1217 ClearUnitOutputs(unit, 1);
1220 void BufWr_next(BufWr *unit, int inNumSamples)
1222 float *phasein = ZIN(1);
1223 int32 loop = (int32)ZIN0(2);
1225 GET_BUF
1226 uint32 numInputChannels = unit->mNumInputs - 3;
1227 if (!checkBuffer(unit, bufData, bufChannels, numInputChannels, inNumSamples))
1228 return;
1230 double loopMax = (double)(bufFrames - (loop ? 0 : 1));
1232 for (int32 k=0; k<inNumSamples; ++k) {
1233 double phase = sc_loop((Unit*)unit, ZXP(phasein), loopMax, loop);
1234 int32 iphase = (int32)phase;
1235 float* table0 = bufData + iphase * bufChannels;
1236 for (uint32 channel=0; channel<numInputChannels; ++channel)
1237 table0[channel] = IN(channel+3)[k];
1241 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1243 //bufnum=0, offset=0.0, recLevel=1.0, preLevel=0.0, run=1.0, loop=1.0, trigger=1.0
1245 void RecordBuf_Ctor(RecordBuf *unit)
1248 uint32 numInputs = unit->mNumInputs - 8;
1249 unit->m_fbufnum = -1e9f;
1250 unit->mIn = 0;
1251 unit->m_writepos = (int32)ZIN0(1) * numInputs;
1252 unit->m_recLevel = ZIN0(2);
1253 unit->m_preLevel = ZIN0(3);
1255 if (INRATE(2) == calc_ScalarRate && INRATE(3) == calc_ScalarRate
1256 && unit->m_recLevel == 1.0 && unit->m_preLevel == 0.0)
1258 SETCALC(RecordBuf_next_10);
1259 } else {
1260 SETCALC(RecordBuf_next);
1263 ClearUnitOutputs(unit, 1);
1266 void RecordBuf_Dtor(RecordBuf *unit)
1268 TAKEDOWN_IN
1271 void RecordBuf_next(RecordBuf *unit, int inNumSamples)
1273 //printf("RecordBuf_next\n");
1274 GET_BUF
1275 CHECK_BUF
1276 SETUP_IN(8)
1278 float recLevel = ZIN0(2);
1279 float preLevel = ZIN0(3);
1280 float run = ZIN0(4);
1281 int32 loop = (int32)ZIN0(5);
1282 float trig = ZIN0(6);
1283 //printf("loop %d run %g\n", loop, run);
1285 int32 writepos = unit->m_writepos;
1287 float recLevel_slope = CALCSLOPE(recLevel, unit->m_recLevel);
1288 float preLevel_slope = CALCSLOPE(preLevel, unit->m_preLevel);
1290 /* reset recLevel and preLevel to use the previous value ... bug fix */
1291 recLevel = unit->m_recLevel;
1292 preLevel = unit->m_preLevel;
1294 if (loop) {
1295 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1296 unit->mDone = false;
1297 writepos = (int32)ZIN0(1) * bufChannels;
1299 if (writepos < 0) writepos = bufSamples - bufChannels;
1300 else if (writepos >= (int32)bufSamples) writepos = 0;
1301 if (run > 0.f) {
1302 if (bufChannels == 1) {
1303 for (int32 k=0; k<inNumSamples; ++k) {
1304 float* table0 = bufData + writepos;
1305 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1306 writepos += 1;
1307 if (writepos >= (int32)bufSamples) writepos = 0;
1309 recLevel += recLevel_slope;
1310 preLevel += preLevel_slope;
1312 } else if (bufChannels == 2 && numInputs == 2) {
1313 for (int32 k=0; k<inNumSamples; ++k) {
1314 float* table0 = bufData + writepos;
1315 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1316 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1317 writepos += 2;
1318 if (writepos >= (int32)bufSamples) writepos = 0;
1320 recLevel += recLevel_slope;
1321 preLevel += preLevel_slope;
1323 } else {
1324 for (int32 k=0; k<inNumSamples; ++k) {
1325 float* table0 = bufData + writepos;
1326 for (uint32 i=0; i<numInputs; ++i) {
1327 float *samp = table0 + i;
1328 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1330 writepos += bufChannels;
1331 if (writepos >= (int32)bufSamples) writepos = 0;
1333 recLevel += recLevel_slope;
1334 preLevel += preLevel_slope;
1337 } else if (run < 0.f) {
1338 if (bufChannels == 1) {
1339 for (int32 k=0; k<inNumSamples; ++k) {
1340 float* table0 = bufData + writepos;
1341 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1342 writepos -= 1;
1343 if (writepos < 0) writepos = bufSamples - bufChannels;
1345 recLevel += recLevel_slope;
1346 preLevel += preLevel_slope;
1348 } else if (bufChannels == 2 && numInputs == 2) {
1349 for (int32 k=0; k<inNumSamples; ++k) {
1350 float* table0 = bufData + writepos;
1351 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1352 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1353 writepos -= 2;
1354 if (writepos < 0) writepos = bufSamples - bufChannels;
1356 recLevel += recLevel_slope;
1357 preLevel += preLevel_slope;
1359 } else {
1360 for (int32 k=0; k<inNumSamples; ++k) {
1361 float* table0 = bufData + writepos;
1362 for (uint32 i=0; i<numInputs; ++i) {
1363 float *samp = table0 + i;
1364 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1366 writepos -= bufChannels;
1367 if (writepos < 0) writepos = bufSamples - bufChannels;
1369 recLevel += recLevel_slope;
1370 preLevel += preLevel_slope;
1374 } else {
1375 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1376 unit->mDone = false;
1377 writepos = (int32)ZIN0(1) * bufChannels;
1379 if (run > 0.f) {
1380 int nsmps = bufSamples - writepos;
1381 nsmps = sc_clip(nsmps, 0, inNumSamples);
1382 if (bufChannels == 1) {
1383 for (int32 k=0; k<nsmps; ++k) {
1384 float* table0 = bufData + writepos;
1385 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1386 writepos += 1;
1388 recLevel += recLevel_slope;
1389 preLevel += preLevel_slope;
1391 } else if (bufChannels == 2 && numInputs == 2) {
1392 for (int32 k=0; k<nsmps; ++k) {
1393 float* table0 = bufData + writepos;
1394 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1395 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1396 writepos += 2;
1398 recLevel += recLevel_slope;
1399 preLevel += preLevel_slope;
1401 } else {
1402 for (int32 k=0; k<nsmps; ++k) {
1403 float* table0 = bufData + writepos;
1404 for (uint32 i=0; i<numInputs; ++i) {
1405 float *samp = table0 + i;
1406 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1408 writepos += bufChannels;
1410 recLevel += recLevel_slope;
1411 preLevel += preLevel_slope;
1414 } else if (run < 0.f) {
1415 int nsmps = writepos;
1416 nsmps = sc_clip(nsmps, 0, inNumSamples);
1417 if (bufChannels == 1) {
1418 for (int32 k=0; k<inNumSamples; ++k) {
1419 float* table0 = bufData + writepos;
1420 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1421 writepos -= bufChannels;
1423 recLevel += recLevel_slope;
1424 preLevel += preLevel_slope;
1426 } else if (bufChannels == 2 && numInputs == 2) {
1427 for (int32 k=0; k<inNumSamples; ++k) {
1428 float* table0 = bufData + writepos;
1429 table0[0] = *++(in[0]) * recLevel + table0[0] * preLevel;
1430 table0[1] = *++(in[1]) * recLevel + table0[1] * preLevel;
1431 writepos -= bufChannels;
1433 recLevel += recLevel_slope;
1434 preLevel += preLevel_slope;
1436 } else {
1437 for (int32 k=0; k<inNumSamples; ++k) {
1438 float* table0 = bufData + writepos;
1439 for (uint32 i=0; i<numInputs; ++i) {
1440 float *samp = table0 + i;
1441 *samp = *++(in[i]) * recLevel + *samp * preLevel;
1443 writepos -= bufChannels;
1445 recLevel += recLevel_slope;
1446 preLevel += preLevel_slope;
1450 if (writepos >= (int32)bufSamples){
1451 unit->mDone = true;
1452 DoneAction(IN0(7), unit);
1455 unit->m_prevtrig = trig;
1456 unit->m_writepos = writepos;
1457 unit->m_recLevel = recLevel;
1458 unit->m_preLevel = preLevel;
1461 void RecordBuf_next_10(RecordBuf *unit, int inNumSamples)
1463 // printf("RecordBuf_next_10\n");
1464 GET_BUF
1465 CHECK_BUF
1466 SETUP_IN(8)
1468 float run = ZIN0(4);
1469 int32 loop = (int32)ZIN0(5);
1470 float trig = ZIN0(6);
1471 //printf("loop %d run %g\n", loop, run);
1473 int32 writepos = unit->m_writepos;
1475 if (loop) {
1476 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1477 unit->mDone = false;
1478 writepos = (int32)ZIN0(1) * bufChannels;
1480 if (writepos < 0) writepos = bufSamples - bufChannels;
1481 else if (writepos >= (int32)bufSamples) writepos = 0;
1482 if (run > 0.f) {
1483 if (bufChannels == 1) {
1484 for (int32 k=0; k<inNumSamples; ++k) {
1485 float* table0 = bufData + writepos;
1486 table0[0] = *++(in[0]);
1487 writepos += 1;
1488 if (writepos >= (int32)bufSamples) writepos = 0;
1490 } else if (bufChannels == 2) {
1491 for (int32 k=0; k<inNumSamples; ++k) {
1492 float* table0 = bufData + writepos;
1493 table0[0] = *++(in[0]);
1494 table0[1] = *++(in[1]);
1495 writepos += 2;
1496 if (writepos >= (int32)bufSamples) writepos = 0;
1498 } else {
1499 for (int32 k=0; k<inNumSamples; ++k) {
1500 float* table0 = bufData + writepos;
1501 for (uint32 i=0; i<bufChannels; ++i) {
1502 float *samp = table0 + i;
1503 *samp = *++(in[i]);
1505 writepos += bufChannels;
1506 if (writepos >= (int32)bufSamples) writepos = 0;
1509 } else if (run < 0.f) {
1510 if (bufChannels == 1) {
1511 for (int32 k=0; k<inNumSamples; ++k) {
1512 float* table0 = bufData + writepos;
1513 table0[0] = *++(in[0]);
1514 writepos -= 1;
1515 if (writepos < 0) writepos = bufSamples - bufChannels;
1517 } else if (bufChannels == 2) {
1518 for (int32 k=0; k<inNumSamples; ++k) {
1519 float* table0 = bufData + writepos;
1520 table0[0] = *++(in[0]);
1521 table0[1] = *++(in[1]);
1522 writepos -= 2;
1523 if (writepos < 0) writepos = bufSamples - bufChannels;
1525 } else {
1526 for (int32 k=0; k<inNumSamples; ++k) {
1527 float* table0 = bufData + writepos;
1528 for (uint32 i=0; i<bufChannels; ++i) {
1529 float *samp = table0 + i;
1530 *samp = *++(in[i]);
1532 writepos -= bufChannels;
1533 if (writepos < 0) writepos = bufSamples - bufChannels;
1537 } else {
1538 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
1539 unit->mDone = false;
1540 writepos = (int32)ZIN0(1) * bufChannels;
1542 if (run > 0.f) {
1543 int nsmps = bufSamples - writepos;
1544 nsmps = sc_clip(nsmps, 0, inNumSamples);
1545 if (bufChannels == 1) {
1546 for (int32 k=0; k<nsmps; ++k) {
1547 float* table0 = bufData + writepos;
1548 table0[0] = *++(in[0]);
1549 writepos += 1;
1551 } else if (bufChannels == 2) {
1552 for (int32 k=0; k<nsmps; ++k) {
1553 float* table0 = bufData + writepos;
1554 table0[0] = *++(in[0]);
1555 table0[1] = *++(in[1]);
1556 writepos += 2;
1557 if (writepos >= (int32)bufSamples) writepos = (int32)bufSamples - 2; // added by jrhb
1559 } else {
1560 for (int32 k=0; k<nsmps; ++k) {
1561 float* table0 = bufData + writepos;
1562 for (uint32 i=0; i<bufChannels; ++i) {
1563 float *samp = table0 + i;
1564 *samp = *++(in[i]);
1566 writepos += bufChannels;
1567 if (writepos >= (int32)bufSamples) writepos = (int32)bufSamples - bufChannels; // added by jrhb
1570 } else if (run < 0.f) {
1571 int nsmps = writepos;
1572 nsmps = sc_clip(nsmps, 0, inNumSamples);
1573 if (bufChannels == 1) {
1574 for (int32 k=0; k<inNumSamples; ++k) {
1575 float* table0 = bufData + writepos;
1576 table0[0] = *++(in[0]);
1577 writepos -= 1;
1579 } else if (bufChannels == 2) {
1580 for (int32 k=0; k<inNumSamples; ++k) {
1581 float* table0 = bufData + writepos;
1582 table0[0] = *++(in[0]);
1583 table0[1] = *++(in[1]);
1584 writepos -= 2;
1586 } else {
1587 for (int32 k=0; k<inNumSamples; ++k) {
1588 float* table0 = bufData + writepos;
1589 for (uint32 i=0; i<bufChannels; ++i) {
1590 float *samp = table0 + i;
1591 *samp = *++(in[i]);
1593 writepos -= bufChannels;
1597 if (writepos >= (int32)bufSamples){
1598 unit->mDone = true;
1599 DoneAction(IN0(7), unit);
1602 unit->m_prevtrig = trig;
1603 unit->m_writepos = writepos;
1607 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1609 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1613 static float insertMedian(float* values, int* ages, int size, float value)
1615 int pos=-1;
1617 // keeps a sorted list of the previous n=size values
1618 // the oldest is removed and the newest is inserted.
1619 // values between the oldest and the newest are shifted over by one.
1621 // values and ages are both arrays that are 'size' int.
1622 // the median value is always values[size>>1]
1624 int last = size - 1;
1625 // find oldest bin and age the other bins.
1626 for (int i=0; i<size; ++i) {
1627 if (ages[i] == last) { // is it the oldest bin ?
1628 pos = i;
1629 } else {
1630 ages[i]++; // age the bin
1633 // move values to fill in place of the oldest and make a space for the newest
1634 // search lower if value is too small for the open space
1635 while (pos != 0 && value < values[pos-1]) {
1636 values[pos] = values[pos-1];
1637 ages[pos] = ages[pos-1];
1638 pos--;
1640 // search higher if value is too big for the open space
1641 while (pos != last && value > values[pos+1]) {
1642 values[pos] = values[pos+1];
1643 ages[pos] = ages[pos+1];
1644 pos++;
1646 values[pos] = value;
1647 ages[pos] = 0; // this is the newest bin, age = 0
1648 return values[size>>1];
1651 static void initMedian(float* values, int* ages, int size, float value)
1653 // initialize the arrays with the first value
1654 for (int i=0; i<size; ++i) {
1655 values[i] = value;
1656 ages[i] = i;
1663 enum {
1664 kPitchIn,
1665 kPitchInitFreq,
1666 kPitchMinFreq,
1667 kPitchMaxFreq,
1668 kPitchExecFreq,
1669 kPitchMaxBins,
1670 kPitchMedian,
1671 kPitchAmpThreshold,
1672 kPitchPeakThreshold,
1673 kPitchDownsamp,
1674 kPitchGetClarity
1677 void Pitch_Ctor(Pitch *unit)
1679 unit->m_freq = ZIN0(kPitchInitFreq);
1680 unit->m_minfreq = ZIN0(kPitchMinFreq);
1681 unit->m_maxfreq = ZIN0(kPitchMaxFreq);
1683 float execfreq = ZIN0(kPitchExecFreq);
1684 execfreq = sc_clip(execfreq, unit->m_minfreq, unit->m_maxfreq);
1686 int maxbins = (int)ZIN0(kPitchMaxBins);
1687 unit->m_maxlog2bins = LOG2CEIL(maxbins);
1689 unit->m_medianSize = sc_clip((int)ZIN0(0), 0, kMAXMEDIANSIZE); // (int)ZIN0(kPitchMedian);
1690 unit->m_ampthresh = ZIN0(kPitchAmpThreshold);
1691 unit->m_peakthresh = ZIN0(kPitchPeakThreshold);
1693 int downsamp = (int)ZIN0(kPitchDownsamp);
1695 if (INRATE(kPitchIn) == calc_FullRate) {
1696 SETCALC(Pitch_next_a);
1697 unit->m_downsamp = sc_clip(downsamp, 1, unit->mWorld->mFullRate.mBufLength);
1698 unit->m_srate = FULLRATE / (float)unit->m_downsamp;
1699 } else {
1700 SETCALC(Pitch_next_k);
1701 unit->m_downsamp = sc_max(downsamp, 1);
1702 unit->m_srate = FULLRATE / (float) (unit->mWorld->mFullRate.mBufLength*unit->m_downsamp);
1705 unit->m_minperiod = (long)(unit->m_srate / unit->m_maxfreq);
1706 unit->m_maxperiod = (long)(unit->m_srate / unit->m_minfreq);
1708 unit->m_execPeriod = (int)(unit->m_srate / execfreq);
1709 unit->m_execPeriod = sc_max(unit->m_execPeriod, unit->mWorld->mFullRate.mBufLength);
1711 unit->m_size = sc_max(unit->m_maxperiod << 1, unit->m_execPeriod);
1713 unit->m_buffer = (float*)RTAlloc(unit->mWorld, unit->m_size * sizeof(float));
1715 unit->m_index = 0;
1716 unit->m_readp = 0;
1717 unit->m_hasfreq = 0.f;
1719 initMedian(unit->m_values, unit->m_ages, unit->m_medianSize, unit->m_freq);
1721 unit->m_getClarity = ZIN0(kPitchGetClarity) > 0.f;
1723 ZOUT0(0) = 0.f;
1724 ZOUT0(1) = 0.f;
1727 void Pitch_Dtor(Pitch *unit)
1729 RTFree(unit->mWorld, unit->m_buffer);
1732 void Pitch_next_a(Pitch *unit, int inNumSamples)
1734 bool foundPeak;
1736 float* in = ZIN(kPitchIn);
1737 uint32 size = unit->m_size;
1738 uint32 index = unit->m_index;
1739 int downsamp = unit->m_downsamp;
1740 int readp = unit->m_readp;
1741 int ksamps = unit->mWorld->mFullRate.mBufLength;
1743 float *bufData = unit->m_buffer;
1745 float freq = unit->m_freq;
1746 float hasfreq = unit->m_hasfreq;
1747 //printf("> %d %d readp %d ksamps %d ds %d\n", index, size, readp, ksamps, downsamp);
1748 do {
1749 float z = in[readp];
1750 bufData[index++] = z;
1751 readp += downsamp;
1753 if (index >= size) {
1754 float ampthresh = unit->m_ampthresh;
1755 bool ampok = false;
1757 hasfreq = 0.f; // assume failure
1759 int minperiod = unit->m_minperiod;
1760 int maxperiod = unit->m_maxperiod;
1761 //float maxamp = 0.f;
1762 // check for amp threshold
1763 for (int j = 0; j < maxperiod; ++j) {
1764 if (fabs(bufData[j]) >= ampthresh) {
1765 ampok = true;
1766 break;
1768 //if (fabs(bufData[j]) > maxamp) maxamp = fabs(bufData[j]);
1770 //printf("ampok %d maxperiod %d maxamp %g\n", ampok, maxperiod, maxamp);
1772 // if amplitude is too small then don't even look for pitch
1773 float ampsum;
1774 if (ampok) {
1775 int maxlog2bins = unit->m_maxlog2bins;
1776 int octave;
1777 // calculate the zero lag value and compute the threshold based on that
1778 float zerolagval = 0.f;
1779 for (int j = 0; j < maxperiod; ++j) {
1780 zerolagval += bufData[j] * bufData[j];
1782 float threshold = zerolagval * unit->m_peakthresh;
1784 // skip until drop below threshold
1785 int binstep, peakbinstep = 0;
1786 int i;
1787 for (i = 1; i <= maxperiod; i += binstep) {
1788 // compute sum of one lag
1789 ampsum = 0.f;
1790 for (int j = 0; j < maxperiod; ++j) {
1791 ampsum += bufData[i+j] * bufData[j];
1793 if (ampsum < threshold) break;
1795 octave = LOG2CEIL(i);
1796 if (octave <= maxlog2bins) {
1797 binstep = 1;
1798 } else {
1799 binstep = 1L << (octave - maxlog2bins);
1802 int startperiod = i;
1803 int period = startperiod;
1804 //printf("startperiod %d\n", startperiod);
1806 // find the first peak
1807 float maxsum = threshold;
1808 foundPeak = false;
1809 for (i = startperiod; i <= maxperiod; i += binstep) {
1810 if (i >= minperiod) {
1811 ampsum = 0.f;
1812 for (int j = 0; j < maxperiod; ++j) {
1813 ampsum += bufData[i+j] * bufData[j];
1815 if (ampsum > threshold) {
1816 if (ampsum > maxsum) {
1817 foundPeak = true;
1818 maxsum = ampsum;
1819 peakbinstep = binstep;
1820 period = i;
1822 } else if (foundPeak) break;
1824 octave = LOG2CEIL(i);
1825 if (octave <= maxlog2bins) {
1826 binstep = 1;
1827 } else {
1828 binstep = 1L << (octave - maxlog2bins);
1832 //printf("found %d thr %g maxs %g per %d bs %d\n", foundPeak, threshold, maxsum, period, peakbinstep);
1833 if (foundPeak) {
1834 float prevampsum, nextampsum;
1836 // find amp sums immediately surrounding max
1837 prevampsum = 0.f;
1838 if (period > 0) {
1839 i = period - 1;
1840 for (int j = 0; j < maxperiod; ++j) {
1841 prevampsum += bufData[i+j] * bufData[j];
1845 nextampsum = 0.f;
1846 if (period < maxperiod) {
1847 i = period + 1;
1848 for (int j = 0; j < maxperiod; ++j) {
1849 nextampsum += bufData[i+j] * bufData[j];
1853 //printf("prevnext %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1854 // not on a peak yet. This can happen if binstep > 1
1855 while (prevampsum > maxsum && period > 0) {
1856 nextampsum = maxsum;
1857 maxsum = prevampsum;
1858 period--;
1859 i = period - 1;
1860 prevampsum = 0.f;
1861 for (int j = 0; j < maxperiod; ++j) {
1862 prevampsum += bufData[i+j] * bufData[j];
1864 //printf("slide left %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1866 while (nextampsum > maxsum && period < maxperiod) {
1867 prevampsum = maxsum;
1868 maxsum = nextampsum;
1869 period++;
1870 i = period + 1;
1871 nextampsum = 0.f;
1872 for (int j = 0; j < maxperiod; ++j) {
1873 nextampsum += bufData[i+j] * bufData[j];
1875 //printf("slide right %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
1878 // make a fractional period
1879 float beta = 0.5f * (nextampsum - prevampsum);
1880 float gamma = 2.f * maxsum - nextampsum - prevampsum;
1881 float fperiod = (float)period + (beta/gamma);
1883 // calculate frequency
1884 float tempfreq = unit->m_srate / fperiod;
1886 //printf("freq %g %g / %g %g %g %d\n", tempfreq, unit->m_srate, fperiod,
1887 // unit->m_minfreq, unit->m_maxfreq,
1888 // tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq);
1890 if (tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq) {
1891 freq = tempfreq;
1893 // median filter
1894 if (unit->m_medianSize > 1) {
1895 freq = insertMedian(unit->m_values, unit->m_ages, unit->m_medianSize, freq);
1897 if(unit->m_getClarity)
1898 hasfreq = maxsum / zerolagval; // "clarity" measure is normalised size of first peak
1899 else
1900 hasfreq = 1.f;
1902 startperiod = (ksamps+downsamp-1)/downsamp;
1905 }/* else {
1906 printf("amp too low \n");
1909 // shift buffer for next fill
1910 int execPeriod = unit->m_execPeriod;
1911 int interval = size - execPeriod;
1912 //printf("interval %d sz %d ep %d\n", interval, size, execPeriod);
1913 for (int i = 0; i < interval; i++) {
1914 bufData[i] = bufData[i + execPeriod];
1916 index = interval;
1918 } while (readp < ksamps);
1920 ZOUT0(0) = freq;
1921 ZOUT0(1) = hasfreq;
1922 unit->m_readp = readp - ksamps;
1923 unit->m_index = index;
1924 unit->m_freq = freq;
1925 unit->m_hasfreq = hasfreq;
1929 // control rate pitch tracking (nescivi 11/2008)
1930 void Pitch_next_k(Pitch *unit, int inNumSamples)
1932 bool foundPeak;
1934 float in = ZIN0(kPitchIn); // one sample, current input
1935 uint32 size = unit->m_size;
1936 uint32 index = unit->m_index;
1937 int downsamp = unit->m_downsamp;
1938 int readp = unit->m_readp;
1939 // int ksamps = unit->mWorld->mFullRate.mBufLength;
1941 float *bufData = unit->m_buffer;
1943 float freq = unit->m_freq;
1944 float hasfreq = unit->m_hasfreq;
1945 // printf("> %d %d readp %d downsamp %d exec %d\n", index, size, readp, downsamp, unit->m_execPeriod);
1946 readp++;
1947 if ( readp == downsamp ){
1948 // do {
1949 // float z = in[readp];
1950 float z = in;
1951 bufData[index++] = z;
1952 readp = 0;
1953 // readp += downsamp;
1955 if (index >= size) {
1956 float ampthresh = unit->m_ampthresh;
1957 bool ampok = false;
1959 hasfreq = 0.f; // assume failure
1961 int minperiod = unit->m_minperiod;
1962 int maxperiod = unit->m_maxperiod;
1963 //float maxamp = 0.f;
1964 // check for amp threshold
1965 for (int j = 0; j < maxperiod; ++j) {
1966 if (fabs(bufData[j]) >= ampthresh) {
1967 ampok = true;
1968 break;
1970 //if (fabs(bufData[j]) > maxamp) maxamp = fabs(bufData[j]);
1972 //printf("ampok %d maxperiod %d maxamp %g\n", ampok, maxperiod, maxamp);
1974 // if amplitude is too small then don't even look for pitch
1975 float ampsum;
1976 if (ampok) {
1977 int maxlog2bins = unit->m_maxlog2bins;
1978 int octave;
1979 // calculate the zero lag value and compute the threshold based on that
1980 float zerolagval = 0.f;
1981 for (int j = 0; j < maxperiod; ++j) {
1982 zerolagval += bufData[j] * bufData[j];
1984 float threshold = zerolagval * unit->m_peakthresh;
1986 // skip until drop below threshold
1987 int binstep, peakbinstep = 0;
1988 int i;
1989 for (i = 1; i <= maxperiod; i += binstep) {
1990 // compute sum of one lag
1991 ampsum = 0.f;
1992 for (int j = 0; j < maxperiod; ++j) {
1993 ampsum += bufData[i+j] * bufData[j];
1995 if (ampsum < threshold) break;
1997 octave = LOG2CEIL(i);
1998 if (octave <= maxlog2bins) {
1999 binstep = 1;
2000 } else {
2001 binstep = 1L << (octave - maxlog2bins);
2004 int startperiod = i;
2005 int period = startperiod;
2006 //printf("startperiod %d\n", startperiod);
2008 // find the first peak
2009 float maxsum = threshold;
2010 foundPeak = false;
2011 for (i = startperiod; i <= maxperiod; i += binstep) {
2012 if (i >= minperiod) {
2013 ampsum = 0.f;
2014 for (int j = 0; j < maxperiod; ++j) {
2015 ampsum += bufData[i+j] * bufData[j];
2017 if (ampsum > threshold) {
2018 if (ampsum > maxsum) {
2019 foundPeak = true;
2020 maxsum = ampsum;
2021 peakbinstep = binstep;
2022 period = i;
2024 } else if (foundPeak) break;
2026 octave = LOG2CEIL(i);
2027 if (octave <= maxlog2bins) {
2028 binstep = 1;
2029 } else {
2030 binstep = 1L << (octave - maxlog2bins);
2034 //printf("found %d thr %g maxs %g per %d bs %d\n", foundPeak, threshold, maxsum, period, peakbinstep);
2035 if (foundPeak) {
2036 float prevampsum, nextampsum;
2038 // find amp sums immediately surrounding max
2039 prevampsum = 0.f;
2040 if (period > 0) {
2041 i = period - 1;
2042 for (int j = 0; j < maxperiod; ++j) {
2043 prevampsum += bufData[i+j] * bufData[j];
2047 nextampsum = 0.f;
2048 if (period < maxperiod) {
2049 i = period + 1;
2050 for (int j = 0; j < maxperiod; ++j) {
2051 nextampsum += bufData[i+j] * bufData[j];
2055 //printf("prevnext %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2056 // not on a peak yet. This can happen if binstep > 1
2057 while (prevampsum > maxsum && period > 0) {
2058 nextampsum = maxsum;
2059 maxsum = prevampsum;
2060 period--;
2061 i = period - 1;
2062 prevampsum = 0.f;
2063 for (int j = 0; j < maxperiod; ++j) {
2064 prevampsum += bufData[i+j] * bufData[j];
2066 //printf("slide left %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2068 while (nextampsum > maxsum && period < maxperiod) {
2069 prevampsum = maxsum;
2070 maxsum = nextampsum;
2071 period++;
2072 i = period + 1;
2073 nextampsum = 0.f;
2074 for (int j = 0; j < maxperiod; ++j) {
2075 nextampsum += bufData[i+j] * bufData[j];
2077 //printf("slide right %g %g %g %d\n", prevampsum, maxsum, nextampsum, period);
2080 // make a fractional period
2081 float beta = 0.5 * (nextampsum - prevampsum);
2082 float gamma = 2.0 * maxsum - nextampsum - prevampsum;
2083 float fperiod = (float)period + (beta/gamma);
2085 // calculate frequency
2086 float tempfreq = unit->m_srate / fperiod;
2088 //printf("freq %g %g / %g %g %g %d\n", tempfreq, unit->m_srate, fperiod,
2089 // unit->m_minfreq, unit->m_maxfreq,
2090 // tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq);
2092 if (tempfreq >= unit->m_minfreq && tempfreq <= unit->m_maxfreq) {
2093 freq = tempfreq;
2095 // median filter
2096 if (unit->m_medianSize > 1) {
2097 freq = insertMedian(unit->m_values, unit->m_ages, unit->m_medianSize, freq);
2099 if(unit->m_getClarity)
2100 hasfreq = maxsum / zerolagval; // "clarity" measure is normalised size of first peak
2101 else
2102 hasfreq = 1.f;
2104 // nescivi: not sure about this one?
2105 startperiod = 1; // (ksamps+downsamp-1)/downsamp;
2108 }/* else {
2109 printf("amp too low \n");
2112 // shift buffer for next fill
2113 int execPeriod = unit->m_execPeriod;
2114 int interval = size - execPeriod;
2115 //printf("interval %d sz %d ep %d\n", interval, size, execPeriod);
2116 for (int i = 0; i < interval; i++) {
2117 bufData[i] = bufData[i + execPeriod];
2119 index = interval;
2122 //while (readp < ksamps);
2124 ZOUT0(0) = freq;
2125 ZOUT0(1) = hasfreq;
2126 // unit->m_readp = readp - ksamps;
2127 unit->m_readp = readp;
2128 unit->m_index = index;
2129 unit->m_freq = freq;
2130 unit->m_hasfreq = hasfreq;
2133 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2136 #if 0
2137 void DelayUnit_AllocDelayLine(DelayUnit *unit)
2139 long delaybufsize = (long)ceil(unit->m_maxdelaytime * SAMPLERATE + 1.f);
2140 delaybufsize = delaybufsize + BUFLENGTH;
2141 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
2142 unit->m_fdelaylen = unit->m_idelaylen = delaybufsize;
2144 RTFree(unit->mWorld, unit->m_dlybuf);
2145 int size = delaybufsize * sizeof(float);
2146 //Print("->RTAlloc %d\n", size);
2147 unit->m_dlybuf = (float*)RTAlloc(unit->mWorld, size);
2148 //Print("<-RTAlloc %p\n", unit->m_dlybuf);
2149 unit->m_mask = delaybufsize - 1;
2151 #endif
2154 template <typename Unit>
2155 static float BufCalcDelay(const Unit * unit, int bufSamples, float delayTime)
2157 float minDelay = Unit::minDelaySamples;
2158 return sc_clip(delayTime * (float)SAMPLERATE, minDelay, (float)(PREVIOUSPOWEROFTWO(bufSamples))-1);
2161 template <typename Unit>
2162 static void BufDelayUnit_Reset(Unit *unit)
2164 //Print("->DelayUnit_Reset\n");
2165 //unit->m_maxdelaytime = ZIN0(1);
2166 unit->m_delaytime = ZIN0(2);
2167 //Print("unit->m_delaytime %g\n", unit->m_delaytime);
2168 //unit->m_dlybuf = 0;
2169 unit->m_fbufnum = -1e9f;
2171 //DelayUnit_AllocDelayLine(unit);
2172 //Print("->GET_BUF\n");
2173 GET_BUF
2174 //Print("<-GET_BUF\n");
2175 unit->m_dsamp = BufCalcDelay(unit, bufSamples, unit->m_delaytime);
2176 unit->m_numoutput = 0;
2177 unit->m_iwrphase = 0;
2180 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2182 template <typename Unit>
2183 static void BufFeedbackDelay_Reset(Unit *unit)
2185 BufDelayUnit_Reset(unit);
2187 unit->m_decaytime = ZIN0(3);
2188 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
2191 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2193 namespace {
2195 /* helper classes for delay functionality */
2196 template <bool Checked = false>
2197 struct DelayN_helper
2199 static const bool checked = false;
2201 static inline void perform(const float *& in, float *& out, float * bufData,
2202 long & iwrphase, long idsamp, long mask)
2204 long irdphase = iwrphase - idsamp;
2205 bufData[iwrphase & mask] = ZXP(in);
2206 ZXP(out) = bufData[irdphase & mask];
2207 iwrphase++;
2210 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2211 static inline void perform(const float *& in, float *& out, float * bufData,
2212 long & iwrphase, long idsamp, float frac, long mask)
2214 perform(in, out, bufData, iwrphase, idsamp, mask);
2218 template <>
2219 struct DelayN_helper<true>
2221 static const bool checked = true;
2223 static inline void perform(const float *& in, float *& out, float * bufData,
2224 long & iwrphase, long idsamp, long mask)
2226 long irdphase = iwrphase - idsamp;
2228 bufData[iwrphase & mask] = ZXP(in);
2229 if (irdphase < 0)
2230 ZXP(out) = 0.f;
2231 else
2232 ZXP(out) = bufData[irdphase & mask];
2234 iwrphase++;
2237 static inline void perform(const float *& in, float *& out, float * bufData,
2238 long & iwrphase, long idsamp, float frac, long mask)
2240 perform(in, out, bufData, iwrphase, idsamp, mask);
2244 template <bool initializing>
2245 static inline void DelayN_delay_loop(float * out, const float * in, long & iwrphase, float dsamp, long mask,
2246 float * dlybuf, int inNumSamples, int idelaylen)
2248 long irdphase = iwrphase - (long)dsamp;
2249 float* dlybuf1 = dlybuf - ZOFF;
2250 float* dlyrd = dlybuf1 + (irdphase & mask);
2251 float* dlywr = dlybuf1 + (iwrphase & mask);
2252 float* dlyN = dlybuf1 + idelaylen;
2253 long remain = inNumSamples;
2254 while (remain) {
2255 long rdspace = dlyN - dlyrd;
2256 long wrspace = dlyN - dlywr;
2257 if (initializing) {
2258 long nsmps = sc_min(rdspace, wrspace);
2259 nsmps = sc_min(remain, nsmps);
2260 remain -= nsmps;
2261 if (irdphase < 0) {
2262 if ((dlywr - dlyrd) > nsmps) {
2263 #ifdef NOVA_SIMD
2264 if ((nsmps & (nova::vec<float>::size - 1)) == 0) {
2265 nova::copyvec_nn_simd(dlywr + ZOFF, in + ZOFF, nsmps);
2266 nova::zerovec_na_simd(out + ZOFF, nsmps);
2267 } else
2268 #endif
2270 ZCopy(nsmps, dlywr, in);
2271 ZClear(nsmps, out);
2273 out += nsmps;
2274 in += nsmps;
2275 dlyrd += nsmps;
2276 dlywr += nsmps;
2277 } else
2278 LOOP(nsmps,
2279 ZXP(dlywr) = ZXP(in);
2280 ZXP(out) = 0.f;
2281 ZXP(dlyrd);
2283 } else {
2284 LOOP(nsmps,
2285 ZXP(dlywr) = ZXP(in);
2286 ZXP(out) = ZXP(dlyrd);
2289 irdphase += nsmps;
2290 if (dlyrd == dlyN) dlyrd = dlybuf1;
2291 if (dlywr == dlyN) dlywr = dlybuf1;
2293 else {
2294 long nsmps = sc_min(rdspace, wrspace);
2295 nsmps = sc_min(remain, nsmps);
2296 remain -= nsmps;
2298 if (std::abs((float)(dlyrd - dlywr)) > nsmps) {
2299 #ifdef NOVA_SIMD
2300 if ((nsmps & 15) == 0) {
2301 nova::copyvec_nn_simd(dlywr + ZOFF, in + ZOFF, nsmps);
2302 nova::copyvec_nn_simd(out + ZOFF, dlyrd + ZOFF, nsmps);
2303 } else
2304 #endif
2306 ZCopy(nsmps, dlywr, in);
2307 ZCopy(nsmps, out, dlyrd);
2309 out += nsmps;
2310 in += nsmps;
2311 dlyrd += nsmps;
2312 dlywr += nsmps;
2313 } else
2314 LOOP(nsmps,
2315 ZXP(dlywr) = ZXP(in);
2316 ZXP(out) = ZXP(dlyrd);
2318 if (dlyrd == dlyN) dlyrd = dlybuf1;
2319 if (dlywr == dlyN) dlywr = dlybuf1;
2322 iwrphase += inNumSamples;
2326 template <bool Checked = false>
2327 struct DelayL_helper
2329 static const bool checked = false;
2331 static inline void perform(const float *& in, float *& out, float * bufData,
2332 long & iwrphase, long idsamp, float frac, long mask)
2334 bufData[iwrphase & mask] = ZXP(in);
2335 long irdphase = iwrphase - idsamp;
2336 long irdphaseb = irdphase - 1;
2337 float d1 = bufData[irdphase & mask];
2338 float d2 = bufData[irdphaseb & mask];
2339 ZXP(out) = lininterp(frac, d1, d2);
2340 iwrphase++;
2344 template <>
2345 struct DelayL_helper<true>
2347 static const bool checked = true;
2349 static inline void perform(const float *& in, float *& out, float * bufData,
2350 long & iwrphase, long idsamp, float frac, long mask)
2352 bufData[iwrphase & mask] = ZXP(in);
2353 long irdphase = iwrphase - idsamp;
2354 long irdphaseb = irdphase - 1;
2356 if (irdphase < 0) {
2357 ZXP(out) = 0.f;
2358 } else if (irdphaseb < 0) {
2359 float d1 = bufData[irdphase & mask];
2360 ZXP(out) = d1 - frac * d1;
2361 } else {
2362 float d1 = bufData[irdphase & mask];
2363 float d2 = bufData[irdphaseb & mask];
2364 ZXP(out) = lininterp(frac, d1, d2);
2366 iwrphase++;
2370 template <bool Checked = false>
2371 struct DelayC_helper
2373 static const bool checked = false;
2375 static inline void perform(const float *& in, float *& out, float * bufData,
2376 long & iwrphase, long idsamp, float frac, long mask)
2378 bufData[iwrphase & mask] = ZXP(in);
2379 long irdphase1 = iwrphase - idsamp;
2380 long irdphase2 = irdphase1 - 1;
2381 long irdphase3 = irdphase1 - 2;
2382 long irdphase0 = irdphase1 + 1;
2383 float d0 = bufData[irdphase0 & mask];
2384 float d1 = bufData[irdphase1 & mask];
2385 float d2 = bufData[irdphase2 & mask];
2386 float d3 = bufData[irdphase3 & mask];
2387 ZXP(out) = cubicinterp(frac, d0, d1, d2, d3);
2388 iwrphase++;
2392 template <>
2393 struct DelayC_helper<true>
2395 static const bool checked = true;
2397 static inline void perform(const float *& in, float *& out, float * bufData,
2398 long & iwrphase, long idsamp, float frac, long mask)
2400 long irdphase1 = iwrphase - idsamp;
2401 long irdphase2 = irdphase1 - 1;
2402 long irdphase3 = irdphase1 - 2;
2403 long irdphase0 = irdphase1 + 1;
2405 bufData[iwrphase & mask] = ZXP(in);
2406 if (irdphase0 < 0) {
2407 ZXP(out) = 0.f;
2408 } else {
2409 float d0, d1, d2, d3;
2410 if (irdphase1 < 0) {
2411 d1 = d2 = d3 = 0.f;
2412 d0 = bufData[irdphase0 & mask];
2413 } else if (irdphase2 < 0) {
2414 d1 = d2 = d3 = 0.f;
2415 d0 = bufData[irdphase0 & mask];
2416 d1 = bufData[irdphase1 & mask];
2417 } else if (irdphase3 < 0) {
2418 d3 = 0.f;
2419 d0 = bufData[irdphase0 & mask];
2420 d1 = bufData[irdphase1 & mask];
2421 d2 = bufData[irdphase2 & mask];
2422 } else {
2423 d0 = bufData[irdphase0 & mask];
2424 d1 = bufData[irdphase1 & mask];
2425 d2 = bufData[irdphase2 & mask];
2426 d3 = bufData[irdphase3 & mask];
2428 ZXP(out) = cubicinterp(frac, d0, d1, d2, d3);
2430 iwrphase++;
2434 template <bool Checked = false>
2435 struct CombN_helper
2437 static const bool checked = false;
2439 static inline void perform(const float *& in, float *& out, float * bufData,
2440 long & iwrphase, long idsamp, long mask, float feedbk)
2442 long irdphase = iwrphase - idsamp;
2443 float value = bufData[irdphase & mask];
2444 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2445 ZXP(out) = value;
2446 ++iwrphase;
2449 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2450 static inline void perform(const float *& in, float *& out, float * bufData,
2451 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2453 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2457 template <>
2458 struct CombN_helper<true>
2460 static const bool checked = true;
2462 static inline void perform(const float *& in, float *& out, float * bufData,
2463 long & iwrphase, long idsamp, long mask, float feedbk)
2465 long irdphase = iwrphase - idsamp;
2467 if (irdphase < 0) {
2468 bufData[iwrphase & mask] = ZXP(in);
2469 ZXP(out) = 0.f;
2470 } else {
2471 float value = bufData[irdphase & mask];
2472 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2473 ZXP(out) = value;
2476 iwrphase++;
2479 static inline void perform(const float *& in, float *& out, float * bufData,
2480 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2482 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2486 template <bool Checked = false>
2487 struct CombL_helper
2489 static const bool checked = false;
2491 static inline void perform(const float *& in, float *& out, float * bufData,
2492 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2494 long irdphase = iwrphase - idsamp;
2495 long irdphaseb = irdphase - 1;
2496 float d1 = bufData[irdphase & mask];
2497 float d2 = bufData[irdphaseb & mask];
2498 float value = lininterp(frac, d1, d2);
2499 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2500 ZXP(out) = value;
2501 iwrphase++;
2505 template <>
2506 struct CombL_helper<true>
2508 static const bool checked = true;
2510 static inline void perform(const float *& in, float *& out, float * bufData,
2511 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2513 long irdphase = iwrphase - idsamp;
2514 long irdphaseb = irdphase - 1;
2516 float zin = ZXP(in);
2517 if (irdphase < 0) {
2518 bufData[iwrphase & mask] = zin;
2519 ZXP(out) = 0.f;
2520 } else if (irdphaseb < 0) {
2521 float d1 = bufData[irdphase & mask];
2522 float value = d1 - frac * d1;
2523 bufData[iwrphase & mask] = zin + feedbk * value;
2524 ZXP(out) = value;
2525 } else {
2526 float d1 = bufData[irdphase & mask];
2527 float d2 = bufData[irdphaseb & mask];
2528 float value = lininterp(frac, d1, d2);
2529 bufData[iwrphase & mask] = zin + feedbk * value;
2530 ZXP(out) = value;
2532 iwrphase++;
2536 template <bool Checked = false>
2537 struct CombC_helper
2539 static const bool checked = false;
2541 static inline void perform(const float *& in, float *& out, float * bufData,
2542 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2544 long irdphase1 = iwrphase - idsamp;
2545 long irdphase2 = irdphase1 - 1;
2546 long irdphase3 = irdphase1 - 2;
2547 long irdphase0 = irdphase1 + 1;
2548 float d0 = bufData[irdphase0 & mask];
2549 float d1 = bufData[irdphase1 & mask];
2550 float d2 = bufData[irdphase2 & mask];
2551 float d3 = bufData[irdphase3 & mask];
2552 float value = cubicinterp(frac, d0, d1, d2, d3);
2553 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2554 ZXP(out) = value;
2555 iwrphase++;
2559 template <>
2560 struct CombC_helper<true>
2562 static const bool checked = true;
2564 static inline void perform(const float *& in, float *& out, float * bufData,
2565 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2567 long irdphase1 = iwrphase - idsamp;
2568 long irdphase2 = irdphase1 - 1;
2569 long irdphase3 = irdphase1 - 2;
2570 long irdphase0 = irdphase1 + 1;
2572 if (irdphase0 < 0) {
2573 bufData[iwrphase & mask] = ZXP(in);
2574 ZXP(out) = 0.f;
2575 } else {
2576 float d0, d1, d2, d3;
2577 if (irdphase1 < 0) {
2578 d1 = d2 = d3 = 0.f;
2579 d0 = bufData[irdphase0 & mask];
2580 } else if (irdphase2 < 0) {
2581 d1 = d2 = d3 = 0.f;
2582 d0 = bufData[irdphase0 & mask];
2583 d1 = bufData[irdphase1 & mask];
2584 } else if (irdphase3 < 0) {
2585 d3 = 0.f;
2586 d0 = bufData[irdphase0 & mask];
2587 d1 = bufData[irdphase1 & mask];
2588 d2 = bufData[irdphase2 & mask];
2589 } else {
2590 d0 = bufData[irdphase0 & mask];
2591 d1 = bufData[irdphase1 & mask];
2592 d2 = bufData[irdphase2 & mask];
2593 d3 = bufData[irdphase3 & mask];
2595 float value = cubicinterp(frac, d0, d1, d2, d3);
2596 bufData[iwrphase & mask] = ZXP(in) + feedbk * value;
2597 ZXP(out) = value;
2599 iwrphase++;
2603 template <bool Checked = false>
2604 struct AllpassN_helper
2606 static const bool checked = false;
2608 static inline void perform(const float *& in, float *& out, float * bufData,
2609 long & iwrphase, long idsamp, long mask, float feedbk)
2611 long irdphase = iwrphase - idsamp;
2612 float value = bufData[irdphase & mask];
2613 float dwr = value * feedbk + ZXP(in);
2614 bufData[iwrphase & mask] = dwr;
2615 ZXP(out) = value - feedbk * dwr;
2616 ++iwrphase;
2619 /* the frac argument is unneeded. the compiler should make sure, that it won't be computed */
2620 static inline void perform(const float *& in, float *& out, float * bufData,
2621 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2623 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2627 template <>
2628 struct AllpassN_helper<true>
2630 static const bool checked = true;
2632 static inline void perform(const float *& in, float *& out, float * bufData,
2633 long & iwrphase, long idsamp, long mask, float feedbk)
2635 long irdphase = iwrphase - idsamp;
2637 if (irdphase < 0) {
2638 float dwr = ZXP(in);
2639 bufData[iwrphase & mask] = dwr;
2640 ZXP(out) = -feedbk * dwr;
2641 } else {
2642 float value = bufData[irdphase & mask];
2643 float dwr = feedbk * value + ZXP(in);
2644 bufData[iwrphase & mask] = dwr;
2645 ZXP(out) = value - feedbk * dwr;
2647 ++iwrphase;
2650 static inline void perform(const float *& in, float *& out, float * bufData,
2651 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2653 perform(in, out, bufData, iwrphase, idsamp, mask, feedbk);
2657 template <bool Checked = false>
2658 struct AllpassL_helper
2660 static const bool checked = false;
2662 static inline void perform(const float *& in, float *& out, float * bufData,
2663 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2665 long irdphase = iwrphase - idsamp;
2666 long irdphaseb = irdphase - 1;
2667 float d1 = bufData[irdphase & mask];
2668 float d2 = bufData[irdphaseb & mask];
2669 float value = lininterp(frac, d1, d2);
2670 float dwr = ZXP(in) + feedbk * value;
2671 bufData[iwrphase & mask] = dwr;
2672 ZXP(out) = value - feedbk * dwr;
2673 iwrphase++;
2677 template <>
2678 struct AllpassL_helper<true>
2680 static const bool checked = true;
2682 static inline void perform(const float *& in, float *& out, float * bufData,
2683 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2685 long irdphase = iwrphase - idsamp;
2686 long irdphaseb = irdphase - 1;
2688 float zin = ZXP(in);
2689 if (irdphase < 0) {
2690 bufData[iwrphase & mask] = zin;
2691 ZXP(out) = - feedbk * zin;
2692 } else if (irdphaseb < 0) {
2693 float d1 = bufData[irdphase & mask];
2694 float value = d1 - frac * d1;
2695 float dwr = zin + feedbk * value;
2696 bufData[iwrphase & mask] = dwr;
2697 ZXP(out) = value - feedbk * dwr;
2698 } else {
2699 float d1 = bufData[irdphase & mask];
2700 float d2 = bufData[irdphaseb & mask];
2701 float value = lininterp(frac, d1, d2);
2702 float dwr = zin + feedbk * value;
2703 bufData[iwrphase & mask] = dwr;
2704 ZXP(out) = value - feedbk * dwr;
2706 iwrphase++;
2710 template <bool Checked = false>
2711 struct AllpassC_helper
2713 static const bool checked = false;
2715 static inline void perform(const float *& in, float *& out, float * bufData,
2716 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2718 long irdphase1 = iwrphase - idsamp;
2719 long irdphase2 = irdphase1 - 1;
2720 long irdphase3 = irdphase1 - 2;
2721 long irdphase0 = irdphase1 + 1;
2722 float d0 = bufData[irdphase0 & mask];
2723 float d1 = bufData[irdphase1 & mask];
2724 float d2 = bufData[irdphase2 & mask];
2725 float d3 = bufData[irdphase3 & mask];
2726 float value = cubicinterp(frac, d0, d1, d2, d3);
2727 float dwr = ZXP(in) + feedbk * value;
2728 bufData[iwrphase & mask] = dwr;
2729 ZXP(out) = value - feedbk * dwr;
2730 iwrphase++;
2734 template <>
2735 struct AllpassC_helper<true>
2737 static const bool checked = true;
2739 static inline void perform(const float *& in, float *& out, float * bufData,
2740 long & iwrphase, long idsamp, float frac, long mask, float feedbk)
2742 long irdphase1 = iwrphase - idsamp;
2743 long irdphase2 = irdphase1 - 1;
2744 long irdphase3 = irdphase1 - 2;
2745 long irdphase0 = irdphase1 + 1;
2747 if (irdphase0 < 0) {
2748 bufData[iwrphase & mask] = ZXP(in);
2749 ZXP(out) = 0.f;
2750 } else {
2751 float d0, d1, d2, d3;
2752 if (irdphase1 < 0) {
2753 d1 = d2 = d3 = 0.f;
2754 d0 = bufData[irdphase0 & mask];
2755 } else if (irdphase2 < 0) {
2756 d1 = d2 = d3 = 0.f;
2757 d0 = bufData[irdphase0 & mask];
2758 d1 = bufData[irdphase1 & mask];
2759 } else if (irdphase3 < 0) {
2760 d3 = 0.f;
2761 d0 = bufData[irdphase0 & mask];
2762 d1 = bufData[irdphase1 & mask];
2763 d2 = bufData[irdphase2 & mask];
2764 } else {
2765 d0 = bufData[irdphase0 & mask];
2766 d1 = bufData[irdphase1 & mask];
2767 d2 = bufData[irdphase2 & mask];
2768 d3 = bufData[irdphase3 & mask];
2770 float value = cubicinterp(frac, d0, d1, d2, d3);
2771 float dwr = ZXP(in) + feedbk * value;
2772 bufData[iwrphase & mask] = dwr;
2773 ZXP(out) = value - feedbk * dwr;
2775 iwrphase++;
2781 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2783 /* template function to generate buffer-based delay ugen function, control-rate delay time */
2784 template <typename PerformClass,
2785 typename BufDelayX
2787 inline void BufDelayX_perform(BufDelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
2789 float *out = ZOUT(0);
2790 const float *in = ZIN(1);
2791 float delaytime = ZIN0(2);
2793 GET_BUF
2794 CHECK_BUF
2795 long iwrphase = unit->m_iwrphase;
2796 float dsamp = unit->m_dsamp;
2798 if (delaytime == unit->m_delaytime) {
2799 long idsamp = (long)dsamp;
2800 float frac = dsamp - idsamp;
2801 LOOP1(inNumSamples,
2802 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2804 } else {
2805 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2806 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2808 LOOP1(inNumSamples,
2809 dsamp += dsamp_slope;
2810 long idsamp = (long)dsamp;
2811 float frac = dsamp - idsamp;
2812 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2814 unit->m_dsamp = dsamp;
2815 unit->m_delaytime = delaytime;
2818 unit->m_iwrphase = iwrphase;
2820 if (PerformClass::checked) {
2821 unit->m_numoutput += inNumSamples;
2822 if (unit->m_numoutput >= bufSamples)
2823 unit->mCalcFunc = resetFunc;
2828 /* template function to generate buffer-based delay ugen function, audio-rate delay time */
2829 template <typename PerformClass,
2830 typename BufDelayX
2832 inline void BufDelayX_perform_a(BufDelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
2834 float *out = ZOUT(0);
2835 const float *in = ZIN(1);
2836 float * delaytime = ZIN(2);
2838 GET_BUF
2839 CHECK_BUF
2840 long iwrphase = unit->m_iwrphase;
2842 LOOP1(inNumSamples,
2843 float dsamp = BufCalcDelay(unit, bufSamples, ZXP(delaytime));
2844 long idsamp = (long)dsamp;
2846 float frac = dsamp - idsamp;
2847 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask);
2850 unit->m_iwrphase = iwrphase;
2852 if (PerformClass::checked)
2854 unit->m_numoutput += inNumSamples;
2855 if (unit->m_numoutput >= bufSamples)
2856 unit->mCalcFunc = resetFunc;
2860 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2862 void BufDelayN_Ctor(BufDelayN *unit)
2864 if(INRATE(2) == calc_FullRate)
2865 SETCALC(BufDelayN_next_a_z);
2866 else
2867 SETCALC(BufDelayN_next_z);
2868 BufDelayUnit_Reset(unit);
2869 ZOUT0(0) = 0.f;
2872 void BufDelayN_next(BufDelayN *unit, int inNumSamples)
2874 float *out = ZOUT(0);
2875 const float *in = ZIN(1);
2876 float delaytime = ZIN0(2);
2878 GET_BUF
2879 CHECK_BUF
2880 long iwrphase = unit->m_iwrphase;
2881 float dsamp = unit->m_dsamp;
2883 if (delaytime == unit->m_delaytime) {
2884 DelayN_delay_loop<false>(out, in, iwrphase, dsamp, mask, bufData, inNumSamples, PREVIOUSPOWEROFTWO(bufSamples));
2885 } else {
2886 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2887 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2889 LOOP1(inNumSamples,
2890 dsamp += dsamp_slope;
2891 long idsamp = (long)dsamp;
2892 DelayN_helper<false>::perform(in, out, bufData, iwrphase, idsamp, mask);
2894 unit->m_dsamp = dsamp;
2895 unit->m_delaytime = delaytime;
2898 unit->m_iwrphase = iwrphase;
2902 void BufDelayN_next_z(BufDelayN *unit, int inNumSamples)
2904 float *out = ZOUT(0);
2905 const float *in = ZIN(1);
2906 float delaytime = ZIN0(2);
2908 GET_BUF
2909 CHECK_BUF
2910 long iwrphase = unit->m_iwrphase;
2911 float dsamp = unit->m_dsamp;
2913 if (delaytime == unit->m_delaytime) {
2914 DelayN_delay_loop<true>(out, in, iwrphase, dsamp, mask, bufData, inNumSamples, PREVIOUSPOWEROFTWO(bufSamples));
2915 } else {
2916 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
2917 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
2919 LOOP1(inNumSamples,
2920 dsamp += dsamp_slope;
2921 long idsamp = (long)dsamp;
2922 DelayN_helper<true>::perform(in, out, bufData, iwrphase, idsamp, mask);
2924 unit->m_dsamp = dsamp;
2925 unit->m_delaytime = delaytime;
2928 unit->m_iwrphase = iwrphase;
2930 unit->m_numoutput += inNumSamples;
2931 if (unit->m_numoutput >= bufSamples)
2932 SETCALC(BufDelayN_next);
2935 template <bool checked>
2936 inline void BufDelayN_perform_a(BufDelayN *unit, int inNumSamples)
2938 BufDelayX_perform_a<DelayN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayN_next_a);
2941 void BufDelayN_next_a(BufDelayN *unit, int inNumSamples)
2943 BufDelayN_perform_a<false>(unit, inNumSamples);
2946 void BufDelayN_next_a_z(BufDelayN *unit, int inNumSamples)
2948 BufDelayN_perform_a<true>(unit, inNumSamples);
2951 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2952 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2954 void BufDelayL_Ctor(BufDelayL *unit)
2956 BufDelayUnit_Reset(unit);
2957 if(INRATE(2) == calc_FullRate)
2958 SETCALC(BufDelayL_next_a_z);
2959 else
2960 SETCALC(BufDelayL_next_z);
2961 ZOUT0(0) = 0.f;
2965 template <bool checked>
2966 inline void BufDelayL_perform(BufDelayL *unit, int inNumSamples)
2968 BufDelayX_perform<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next);
2971 void BufDelayL_next(BufDelayL *unit, int inNumSamples)
2973 BufDelayL_perform<false>(unit, inNumSamples);
2976 void BufDelayL_next_z(BufDelayL *unit, int inNumSamples)
2978 BufDelayL_perform<true>(unit, inNumSamples);
2981 template <bool checked>
2982 inline void BufDelayL_perform_a(BufDelayL *unit, int inNumSamples)
2984 BufDelayX_perform_a<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next_a);
2987 void BufDelayL_next_a(BufDelayL *unit, int inNumSamples)
2989 BufDelayL_perform_a<false>(unit, inNumSamples);
2992 void BufDelayL_next_a_z(BufDelayL *unit, int inNumSamples)
2994 BufDelayL_perform_a<true>(unit, inNumSamples);
2997 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2999 void BufDelayC_Ctor(BufDelayC *unit)
3001 BufDelayUnit_Reset(unit);
3002 if(INRATE(2) == calc_FullRate)
3003 SETCALC(BufDelayC_next_a_z);
3004 else
3005 SETCALC(BufDelayC_next_z);
3006 ZOUT0(0) = 0.f;
3009 template <bool checked>
3010 inline void BufDelayC_perform(BufDelayC *unit, int inNumSamples)
3012 BufDelayX_perform<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayC_next);
3015 void BufDelayC_next(BufDelayC *unit, int inNumSamples)
3017 BufDelayC_perform<false>(unit, inNumSamples);
3020 void BufDelayC_next_z(BufDelayC *unit, int inNumSamples)
3022 BufDelayC_perform<true>(unit, inNumSamples);
3025 template <bool checked>
3026 inline void BufDelayC_perform_a(BufDelayC *unit, int inNumSamples)
3028 BufDelayX_perform_a<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufDelayL_next_a);
3031 void BufDelayC_next_a(BufDelayC *unit, int inNumSamples)
3033 BufDelayC_perform_a<false>(unit, inNumSamples);
3036 void BufDelayC_next_a_z(BufDelayC *unit, int inNumSamples)
3038 BufDelayC_perform_a<true>(unit, inNumSamples);
3041 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3042 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3044 template <typename PerformClass,
3045 typename BufCombX
3047 inline void BufFilterX_perform(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3049 float *out = ZOUT(0);
3050 const float *in = ZIN(1);
3051 float delaytime = ZIN0(2);
3052 float decaytime = ZIN0(3);
3054 GET_BUF
3055 CHECK_BUF
3056 long iwrphase = unit->m_iwrphase;
3057 float dsamp = unit->m_dsamp;
3058 float feedbk = unit->m_feedbk;
3060 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
3061 long idsamp = (long)dsamp;
3062 float frac = dsamp - idsamp;
3063 LOOP1(inNumSamples,
3064 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3066 } else {
3067 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3068 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3070 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3071 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3073 LOOP1(inNumSamples,
3074 dsamp += dsamp_slope;
3075 feedbk += feedbk_slope;
3076 long idsamp = (long)dsamp;
3077 float frac = dsamp - idsamp;
3078 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3080 unit->m_feedbk = feedbk;
3081 unit->m_dsamp = dsamp;
3082 unit->m_delaytime = delaytime;
3083 unit->m_decaytime = decaytime;
3086 unit->m_iwrphase = iwrphase;
3088 if (PerformClass::checked) {
3089 unit->m_numoutput += inNumSamples;
3090 if (unit->m_numoutput >= bufSamples)
3091 unit->mCalcFunc = resetFunc;
3095 template <typename PerformClass,
3096 typename BufCombX
3098 inline void BufFilterX_perform_a(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3100 float *out = ZOUT(0);
3101 const float *in = ZIN(1);
3102 float * delaytime = ZIN(2);
3103 float decaytime = ZIN0(3);
3105 GET_BUF
3106 CHECK_BUF
3107 long iwrphase = unit->m_iwrphase;
3109 LOOP1(inNumSamples,
3110 float del = ZXP(delaytime);
3111 float dsamp = BufCalcDelay(unit, bufSamples, del);
3112 float feedbk = sc_CalcFeedback(del, decaytime);
3114 long idsamp = (long)dsamp;
3115 float frac = dsamp - idsamp;
3116 PerformClass::perform(in, out, bufData, iwrphase, idsamp, frac, mask, feedbk);
3119 unit->m_iwrphase = iwrphase;
3121 if (PerformClass::checked)
3123 unit->m_numoutput += inNumSamples;
3124 if (unit->m_numoutput >= bufSamples)
3125 unit->mCalcFunc = resetFunc;
3130 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3132 void BufCombN_Ctor(BufCombN *unit)
3134 BufFeedbackDelay_Reset(unit);
3135 if(INRATE(2) == calc_FullRate)
3136 SETCALC(BufCombN_next_a_z);
3137 else
3138 SETCALC(BufCombN_next_z);
3139 ZOUT0(0) = 0.f;
3142 void BufCombN_next(BufCombN *unit, int inNumSamples)
3144 float *out = ZOUT(0);
3145 const float *in = ZIN(1);
3146 float delaytime = ZIN0(2);
3147 float decaytime = ZIN0(3);
3149 GET_BUF
3150 CHECK_BUF
3151 long iwrphase = unit->m_iwrphase;
3152 float dsamp = unit->m_dsamp;
3153 float feedbk = unit->m_feedbk;
3155 //postbuf("BufCombN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3156 if (delaytime == unit->m_delaytime) {
3157 long irdphase = iwrphase - (long)dsamp;
3158 float* dlybuf1 = bufData - ZOFF;
3159 float* dlyrd = dlybuf1 + (irdphase & mask);
3160 float* dlywr = dlybuf1 + (iwrphase & mask);
3161 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3162 if (decaytime == unit->m_decaytime) {
3163 long remain = inNumSamples;
3164 while (remain) {
3165 long rdspace = dlyN - dlyrd;
3166 long wrspace = dlyN - dlywr;
3167 long nsmps = sc_min(rdspace, wrspace);
3168 nsmps = sc_min(remain, nsmps);
3169 remain -= nsmps;
3170 LOOP1(nsmps,
3171 float value = ZXP(dlyrd);
3172 ZXP(dlywr) = value * feedbk + ZXP(in);
3173 ZXP(out) = value;
3175 if (dlyrd == dlyN) dlyrd = dlybuf1;
3176 if (dlywr == dlyN) dlywr = dlybuf1;
3178 } else {
3179 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3180 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3181 long remain = inNumSamples;
3182 while (remain) {
3183 long rdspace = dlyN - dlyrd;
3184 long wrspace = dlyN - dlywr;
3185 long nsmps = sc_min(rdspace, wrspace);
3186 nsmps = sc_min(remain, nsmps);
3187 remain -= nsmps;
3189 LOOP1(nsmps,
3190 float value = ZXP(dlyrd);
3191 ZXP(dlywr) = value * feedbk + ZXP(in);
3192 ZXP(out) = value;
3193 feedbk += feedbk_slope;
3195 if (dlyrd == dlyN) dlyrd = dlybuf1;
3196 if (dlywr == dlyN) dlywr = dlybuf1;
3198 unit->m_feedbk = feedbk;
3199 unit->m_decaytime = decaytime;
3201 iwrphase += inNumSamples;
3202 } else {
3203 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3204 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3206 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3207 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3208 LOOP1(inNumSamples,
3209 dsamp += dsamp_slope;
3210 feedbk += feedbk_slope;
3211 CombN_helper<false>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3213 unit->m_feedbk = feedbk;
3214 unit->m_dsamp = dsamp;
3215 unit->m_delaytime = delaytime;
3216 unit->m_decaytime = decaytime;
3219 unit->m_iwrphase = iwrphase;
3222 void BufCombN_next_z(BufCombN *unit, int inNumSamples)
3224 float *out = ZOUT(0);
3225 const float *in = ZIN(1);
3226 float delaytime = ZIN0(2);
3227 float decaytime = ZIN0(3);
3229 GET_BUF
3230 CHECK_BUF
3231 long iwrphase = unit->m_iwrphase;
3232 float dsamp = unit->m_dsamp;
3233 float feedbk = unit->m_feedbk;
3235 //Print("BufCombN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3236 if (delaytime == unit->m_delaytime) {
3237 long irdphase = iwrphase - (long)dsamp;
3238 float* dlybuf1 = bufData - ZOFF;
3239 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3240 if (decaytime == unit->m_decaytime) {
3241 long remain = inNumSamples;
3242 while (remain) {
3243 float* dlywr = dlybuf1 + (iwrphase & mask);
3244 float* dlyrd = dlybuf1 + (irdphase & mask);
3245 long rdspace = dlyN - dlyrd;
3246 long wrspace = dlyN - dlywr;
3247 long nsmps = sc_min(rdspace, wrspace);
3248 nsmps = sc_min(remain, nsmps);
3249 remain -= nsmps;
3250 if (irdphase < 0) {
3251 LOOP1(nsmps,
3252 ZXP(dlywr) = ZXP(in);
3253 ZXP(out) = 0.f;
3255 } else {
3256 LOOP1(nsmps,
3257 float value = ZXP(dlyrd);
3258 ZXP(dlywr) = value * feedbk + ZXP(in);
3259 ZXP(out) = value;
3262 iwrphase += nsmps;
3263 irdphase += nsmps;
3265 } else {
3266 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3267 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3268 long remain = inNumSamples;
3269 while (remain) {
3270 float* dlyrd = dlybuf1 + (irdphase & mask);
3271 float* dlywr = dlybuf1 + (iwrphase & mask);
3272 long rdspace = dlyN - dlyrd;
3273 long wrspace = dlyN - dlywr;
3274 long nsmps = sc_min(rdspace, wrspace);
3275 nsmps = sc_min(remain, nsmps);
3276 remain -= nsmps;
3278 if (irdphase < 0) {
3279 feedbk += nsmps * feedbk_slope;
3280 dlyrd += nsmps;
3281 LOOP1(nsmps,
3282 ZXP(dlywr) = ZXP(in);
3283 ZXP(out) = 0.f;
3285 } else {
3286 LOOP1(nsmps,
3287 float value = ZXP(dlyrd);
3288 ZXP(dlywr) = value * feedbk + ZXP(in);
3289 ZXP(out) = value;
3290 feedbk += feedbk_slope;
3293 iwrphase += nsmps;
3294 irdphase += nsmps;
3296 unit->m_feedbk = feedbk;
3297 unit->m_decaytime = decaytime;
3299 } else {
3300 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3301 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3303 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3304 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3306 LOOP1(inNumSamples,
3307 dsamp += dsamp_slope;
3308 feedbk += feedbk_slope;
3309 CombN_helper<true>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3311 unit->m_feedbk = feedbk;
3312 unit->m_dsamp = dsamp;
3313 unit->m_delaytime = delaytime;
3314 unit->m_decaytime = decaytime;
3317 unit->m_iwrphase = iwrphase;
3319 unit->m_numoutput += inNumSamples;
3320 if (unit->m_numoutput >= bufSamples)
3321 SETCALC(BufCombN_next);
3324 template <bool checked>
3325 inline void BufCombN_perform_a(BufCombN *unit, int inNumSamples)
3327 BufFilterX_perform_a<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombN_next_a);
3330 void BufCombN_next_a(BufCombN *unit, int inNumSamples)
3332 BufCombN_perform_a<false>(unit, inNumSamples);
3335 void BufCombN_next_a_z(BufCombN *unit, int inNumSamples)
3337 BufCombN_perform_a<true>(unit, inNumSamples);
3340 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3341 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3343 void BufCombL_Ctor(BufCombL *unit)
3345 BufFeedbackDelay_Reset(unit);
3346 if(INRATE(2) == calc_FullRate)
3347 SETCALC(BufCombL_next_a_z);
3348 else
3349 SETCALC(BufCombL_next_z);
3350 ZOUT0(0) = 0.f;
3353 template <bool checked>
3354 inline void BufCombL_perform(BufCombL *unit, int inNumSamples)
3356 BufFilterX_perform<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombL_next);
3359 void BufCombL_next(BufCombL *unit, int inNumSamples)
3361 BufCombL_perform<false>(unit, inNumSamples);
3364 void BufCombL_next_z(BufCombL *unit, int inNumSamples)
3366 BufCombL_perform<true>(unit, inNumSamples);
3369 template <bool checked>
3370 inline void BufCombL_perform_a(BufCombL *unit, int inNumSamples)
3372 BufFilterX_perform_a<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombL_next_a);
3375 void BufCombL_next_a(BufCombL *unit, int inNumSamples)
3377 BufCombL_perform_a<false>(unit, inNumSamples);
3380 void BufCombL_next_a_z(BufCombL *unit, int inNumSamples)
3382 BufCombL_perform_a<true>(unit, inNumSamples);
3386 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3388 void BufCombC_Ctor(BufCombC *unit)
3390 BufFeedbackDelay_Reset(unit);
3391 if(INRATE(2) == calc_FullRate)
3392 SETCALC(BufCombC_next_a_z);
3393 else
3394 SETCALC(BufCombC_next_z);
3395 ZOUT0(0) = 0.f;
3399 template <bool checked>
3400 inline void BufCombC_perform(BufCombC *unit, int inNumSamples)
3402 BufFilterX_perform<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombC_next);
3405 void BufCombC_next(BufCombC *unit, int inNumSamples)
3407 BufCombC_perform<false>(unit, inNumSamples);
3410 void BufCombC_next_z(BufCombC *unit, int inNumSamples)
3412 BufCombC_perform<true>(unit, inNumSamples);
3415 template <bool checked>
3416 inline void BufCombC_perform_a(BufCombC *unit, int inNumSamples)
3418 BufFilterX_perform_a<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufCombC_next_a);
3421 void BufCombC_next_a(BufCombC *unit, int inNumSamples)
3423 BufCombC_perform_a<false>(unit, inNumSamples);
3426 void BufCombC_next_a_z(BufCombC *unit, int inNumSamples)
3428 BufCombC_perform_a<true>(unit, inNumSamples);
3432 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3433 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3435 void BufAllpassN_Ctor(BufAllpassN *unit)
3437 BufFeedbackDelay_Reset(unit);
3438 if(INRATE(2) == calc_FullRate)
3439 SETCALC(BufAllpassN_next_a_z);
3440 else
3441 SETCALC(BufAllpassN_next_z);
3442 ZOUT0(0) = 0.f;
3445 void BufAllpassN_next(BufAllpassN *unit, int inNumSamples)
3447 float *out = ZOUT(0);
3448 const float *in = ZIN(1);
3449 float delaytime = ZIN0(2);
3450 float decaytime = ZIN0(3);
3452 GET_BUF
3453 CHECK_BUF
3454 long iwrphase = unit->m_iwrphase;
3455 float dsamp = unit->m_dsamp;
3456 float feedbk = unit->m_feedbk;
3458 //postbuf("BufAllpassN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3459 if (delaytime == unit->m_delaytime) {
3460 long irdphase = iwrphase - (long)dsamp;
3461 float* dlybuf1 = bufData - ZOFF;
3462 float* dlyrd = dlybuf1 + (irdphase & mask);
3463 float* dlywr = dlybuf1 + (iwrphase & mask);
3464 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3465 if (decaytime == unit->m_decaytime) {
3466 long remain = inNumSamples;
3467 while (remain) {
3468 long rdspace = dlyN - dlyrd;
3469 long wrspace = dlyN - dlywr;
3470 long nsmps = sc_min(rdspace, wrspace);
3471 nsmps = sc_min(remain, nsmps);
3472 remain -= nsmps;
3473 LOOP1(nsmps,
3474 float value = ZXP(dlyrd);
3475 float dwr = value * feedbk + ZXP(in);
3476 ZXP(dlywr) = dwr;
3477 ZXP(out) = value - feedbk * dwr;
3479 if (dlyrd == dlyN) dlyrd = dlybuf1;
3480 if (dlywr == dlyN) dlywr = dlybuf1;
3482 } else {
3483 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3484 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3485 long remain = inNumSamples;
3486 while (remain) {
3487 long rdspace = dlyN - dlyrd;
3488 long wrspace = dlyN - dlywr;
3489 long nsmps = sc_min(rdspace, wrspace);
3490 nsmps = sc_min(remain, nsmps);
3491 remain -= nsmps;
3493 LOOP1(nsmps,
3494 float value = ZXP(dlyrd);
3495 float dwr = value * feedbk + ZXP(in);
3496 ZXP(dlywr) = dwr;
3497 ZXP(out) = value - feedbk * dwr;
3498 feedbk += feedbk_slope;
3500 if (dlyrd == dlyN) dlyrd = dlybuf1;
3501 if (dlywr == dlyN) dlywr = dlybuf1;
3503 unit->m_feedbk = feedbk;
3504 unit->m_decaytime = decaytime;
3506 iwrphase += inNumSamples;
3507 } else {
3508 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3509 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3511 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3512 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3513 LOOP1(inNumSamples,
3514 dsamp += dsamp_slope;
3515 feedbk += feedbk_slope;
3516 AllpassN_helper<false>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3518 unit->m_feedbk = feedbk;
3519 unit->m_dsamp = dsamp;
3520 unit->m_delaytime = delaytime;
3521 unit->m_decaytime = decaytime;
3524 unit->m_iwrphase = iwrphase;
3528 void BufAllpassN_next_z(BufAllpassN *unit, int inNumSamples)
3530 float *out = ZOUT(0);
3531 const float *in = ZIN(1);
3532 float delaytime = ZIN0(2);
3533 float decaytime = ZIN0(3);
3535 GET_BUF
3536 CHECK_BUF
3537 long iwrphase = unit->m_iwrphase;
3538 float dsamp = unit->m_dsamp;
3539 float feedbk = unit->m_feedbk;
3541 //postbuf("BufAllpassN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
3542 if (delaytime == unit->m_delaytime) {
3543 long irdphase = iwrphase - (long)dsamp;
3544 float* dlybuf1 = bufData - ZOFF;
3545 float* dlyN = dlybuf1 + PREVIOUSPOWEROFTWO(bufSamples);
3546 if (decaytime == unit->m_decaytime) {
3547 long remain = inNumSamples;
3548 while (remain) {
3549 float* dlywr = dlybuf1 + (iwrphase & mask);
3550 float* dlyrd = dlybuf1 + (irdphase & mask);
3551 long rdspace = dlyN - dlyrd;
3552 long wrspace = dlyN - dlywr;
3553 long nsmps = sc_min(rdspace, wrspace);
3554 nsmps = sc_min(remain, nsmps);
3555 remain -= nsmps;
3556 if (irdphase < 0) {
3557 feedbk = -feedbk;
3558 LOOP1(nsmps,
3559 float dwr = ZXP(in);
3560 ZXP(dlywr) = dwr;
3561 ZXP(out) = feedbk * dwr;
3563 feedbk = -feedbk;
3564 } else {
3565 LOOP1(nsmps,
3566 float x1 = ZXP(dlyrd);
3567 float dwr = x1 * feedbk + ZXP(in);
3568 ZXP(dlywr) = dwr;
3569 ZXP(out) = x1 - feedbk * dwr;
3572 iwrphase += nsmps;
3573 irdphase += nsmps;
3575 } else {
3576 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3577 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3578 long remain = inNumSamples;
3579 while (remain) {
3580 float* dlyrd = dlybuf1 + (irdphase & mask);
3581 float* dlywr = dlybuf1 + (iwrphase & mask);
3582 long rdspace = dlyN - dlyrd;
3583 long wrspace = dlyN - dlywr;
3584 long nsmps = sc_min(rdspace, wrspace);
3585 nsmps = sc_min(remain, nsmps);
3586 remain -= nsmps;
3588 if (irdphase < 0) {
3589 dlyrd += nsmps;
3590 LOOP1(nsmps,
3591 float dwr = ZXP(in);
3592 ZXP(dlywr) = dwr;
3593 ZXP(out) = -feedbk * dwr;
3594 feedbk += feedbk_slope;
3596 } else {
3597 LOOP1(nsmps,
3598 float x1 = ZXP(dlyrd);
3599 float dwr = x1 * feedbk + ZXP(in);
3600 ZXP(dlywr) = dwr;
3601 ZXP(out) = x1 - feedbk * dwr;
3602 feedbk += feedbk_slope;
3605 iwrphase += nsmps;
3606 irdphase += nsmps;
3608 unit->m_feedbk = feedbk;
3609 unit->m_decaytime = decaytime;
3611 } else {
3612 float next_dsamp = BufCalcDelay(unit, bufSamples, delaytime);
3613 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3615 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
3616 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
3618 LOOP1(inNumSamples,
3619 dsamp += dsamp_slope;
3620 feedbk += feedbk_slope;
3621 AllpassN_helper<true>::perform(in, out, bufData, iwrphase, (long)dsamp, mask, feedbk);
3623 unit->m_feedbk = feedbk;
3624 unit->m_dsamp = dsamp;
3625 unit->m_delaytime = delaytime;
3626 unit->m_decaytime = decaytime;
3629 unit->m_iwrphase = iwrphase;
3631 unit->m_numoutput += inNumSamples;
3632 if (unit->m_numoutput >= bufSamples)
3633 SETCALC(BufAllpassN_next);
3636 template <bool checked>
3637 inline void BufAllpassN_perform_a(BufAllpassN *unit, int inNumSamples)
3639 BufFilterX_perform_a<AllpassN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassN_next_a);
3642 void BufAllpassN_next_a(BufAllpassN *unit, int inNumSamples)
3644 BufAllpassN_perform_a<false>(unit, inNumSamples);
3647 void BufAllpassN_next_a_z(BufAllpassN *unit, int inNumSamples)
3649 BufAllpassN_perform_a<true>(unit, inNumSamples);
3653 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3654 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3656 void BufAllpassL_Ctor(BufAllpassL *unit)
3658 BufFeedbackDelay_Reset(unit);
3659 if(INRATE(2) == calc_FullRate)
3660 SETCALC(BufAllpassL_next_a_z);
3661 else
3662 SETCALC(BufAllpassL_next_z);
3663 ZOUT0(0) = 0.f;
3666 template <bool checked>
3667 inline void BufAllpassL_perform(BufAllpassL *unit, int inNumSamples)
3669 BufFilterX_perform<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassL_next);
3672 void BufAllpassL_next(BufAllpassL *unit, int inNumSamples)
3674 BufAllpassL_perform<false>(unit, inNumSamples);
3677 void BufAllpassL_next_z(BufAllpassL *unit, int inNumSamples)
3679 BufAllpassL_perform<true>(unit, inNumSamples);
3682 template <bool checked>
3683 inline void BufAllpassL_perform_a(BufAllpassL *unit, int inNumSamples)
3685 BufFilterX_perform_a<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassL_next_a);
3688 void BufAllpassL_next_a(BufAllpassL *unit, int inNumSamples)
3690 BufAllpassL_perform_a<false>(unit, inNumSamples);
3693 void BufAllpassL_next_a_z(BufAllpassL *unit, int inNumSamples)
3695 BufAllpassL_perform_a<true>(unit, inNumSamples);
3699 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3700 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3702 void BufAllpassC_Ctor(BufAllpassC *unit)
3704 BufFeedbackDelay_Reset(unit);
3705 if(INRATE(2) == calc_FullRate)
3706 SETCALC(BufAllpassC_next_a_z);
3707 else
3708 SETCALC(BufAllpassC_next_z);
3709 ZOUT0(0) = 0.f;
3712 template <bool checked>
3713 inline void BufAllpassC_perform(BufAllpassC *unit, int inNumSamples)
3715 BufFilterX_perform<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassC_next);
3718 void BufAllpassC_next(BufAllpassC *unit, int inNumSamples)
3720 BufAllpassC_perform<false>(unit, inNumSamples);
3723 void BufAllpassC_next_z(BufAllpassC *unit, int inNumSamples)
3725 BufAllpassC_perform<true>(unit, inNumSamples);
3728 template <bool checked>
3729 inline void BufAllpassC_perform_a(BufAllpassC *unit, int inNumSamples)
3731 BufFilterX_perform_a<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)BufAllpassC_next_a);
3734 void BufAllpassC_next_a(BufAllpassC *unit, int inNumSamples)
3736 BufAllpassC_perform_a<false>(unit, inNumSamples);
3739 void BufAllpassC_next_a_z(BufAllpassC *unit, int inNumSamples)
3741 BufAllpassC_perform_a<true>(unit, inNumSamples);
3744 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3745 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3746 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3747 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3749 static bool DelayUnit_AllocDelayLine(DelayUnit *unit, const char * className)
3751 long delaybufsize = (long)ceil(unit->m_maxdelaytime * SAMPLERATE + 1.f);
3752 delaybufsize = delaybufsize + BUFLENGTH;
3753 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
3754 unit->m_fdelaylen = unit->m_idelaylen = delaybufsize;
3756 if (unit->m_dlybuf)
3757 RTFree(unit->mWorld, unit->m_dlybuf);
3758 unit->m_dlybuf = (float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
3760 if (unit->m_dlybuf == NULL) {
3761 SETCALC(ft->fClearUnitOutputs);
3762 ClearUnitOutputs(unit, 1);
3764 if(unit->mWorld->mVerbosity > -2)
3765 Print("Failed to allocate memory for %s ugen.\n", className);
3768 unit->m_mask = delaybufsize - 1;
3769 return (unit->m_dlybuf != NULL);
3772 template <typename Unit>
3773 static float CalcDelay(Unit *unit, float delaytime)
3775 float minDelay = Unit::minDelaySamples;
3776 float next_dsamp = delaytime * (float)SAMPLERATE;
3777 return sc_clip(next_dsamp, minDelay, unit->m_fdelaylen);
3780 template <typename Unit>
3781 static bool DelayUnit_Reset(Unit *unit, const char * className)
3783 unit->m_maxdelaytime = ZIN0(1);
3784 unit->m_delaytime = ZIN0(2);
3785 unit->m_dlybuf = 0;
3787 if (!DelayUnit_AllocDelayLine(unit, className))
3788 return false;
3790 unit->m_dsamp = CalcDelay(unit, unit->m_delaytime);
3792 unit->m_numoutput = 0;
3793 unit->m_iwrphase = 0;
3794 return true;
3798 void DelayUnit_Dtor(DelayUnit *unit)
3800 RTFree(unit->mWorld, unit->m_dlybuf);
3803 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3805 template <typename Unit>
3806 static bool FeedbackDelay_Reset(Unit *unit, const char * className)
3808 unit->m_decaytime = ZIN0(3);
3810 bool allocationSucessful = DelayUnit_Reset(unit, className);
3811 if (!allocationSucessful)
3812 return false;
3814 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
3815 return true;
3818 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3820 /* template function to generate delay ugen function, control-rate delay time */
3821 template <typename PerformClass,
3822 typename DelayX
3824 inline void DelayX_perform(DelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3826 float *out = ZOUT(0);
3827 const float *in = ZIN(0);
3828 float delaytime = ZIN0(2);
3830 float *dlybuf = unit->m_dlybuf;
3831 long iwrphase = unit->m_iwrphase;
3832 float dsamp = unit->m_dsamp;
3833 long mask = unit->m_mask;
3835 if (delaytime == unit->m_delaytime) {
3836 long idsamp = (long)dsamp;
3837 float frac = dsamp - idsamp;
3838 LOOP1(inNumSamples,
3839 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3841 } else {
3842 float next_dsamp = CalcDelay(unit, delaytime);
3843 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3845 LOOP1(inNumSamples,
3846 dsamp += dsamp_slope;
3847 long idsamp = (long)dsamp;
3848 float frac = dsamp - idsamp;
3849 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3851 unit->m_dsamp = dsamp;
3852 unit->m_delaytime = delaytime;
3855 unit->m_iwrphase = iwrphase;
3857 if (PerformClass::checked) {
3858 unit->m_numoutput += inNumSamples;
3859 if (unit->m_numoutput >= unit->m_idelaylen)
3860 unit->mCalcFunc = resetFunc;
3864 /* template function to generate delay ugen function, audio-rate delay time */
3865 template <typename PerformClass,
3866 typename DelayX
3868 inline void DelayX_perform_a(DelayX *unit, int inNumSamples, UnitCalcFunc resetFunc)
3870 float *out = ZOUT(0);
3871 const float *in = ZIN(0);
3872 float * delaytime = ZIN(2);
3874 float *dlybuf = unit->m_dlybuf;
3875 long iwrphase = unit->m_iwrphase;
3876 long mask = unit->m_mask;
3878 LOOP1(inNumSamples,
3879 float dsamp = CalcDelay(unit, ZXP(delaytime));
3880 long idsamp = (long)dsamp;
3882 float frac = dsamp - idsamp;
3883 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask);
3886 unit->m_iwrphase = iwrphase;
3888 if (PerformClass::checked)
3890 unit->m_numoutput += inNumSamples;
3891 if (unit->m_numoutput >= unit->m_idelaylen)
3892 unit->mCalcFunc = resetFunc;
3897 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3899 void Delay_next_0(DelayUnit *unit, int inNumSamples)
3901 float *out = OUT(0);
3902 const float *in = IN(0);
3904 memcpy(out, in, inNumSamples * sizeof(float));
3907 void Delay_next_0_nop(DelayUnit *unit, int inNumSamples)
3910 #ifdef NOVA_SIMD
3911 void Delay_next_0_nova(DelayUnit *unit, int inNumSamples)
3913 nova::copyvec_simd(OUT(0), IN(0), inNumSamples);
3915 #endif
3917 static bool DelayUnit_init_0(DelayUnit *unit)
3919 if (INRATE(2) == calc_ScalarRate && ZIN0(2) == 0) {
3920 if (ZIN(0) == ZOUT(0))
3921 SETCALC(Delay_next_0_nop);
3922 #ifdef NOVA_SIMD
3923 else if (!(BUFLENGTH & 15))
3924 SETCALC(Delay_next_0_nova);
3925 #endif
3926 else
3927 SETCALC(Delay_next_0);
3929 ZOUT0(0) = ZIN0(0);
3930 return true;
3931 } else
3932 return false;
3935 enum {
3936 initializationComplete,
3937 initializationIncomplete
3940 template <typename Delay>
3941 static int Delay_Ctor(Delay *unit, const char *className)
3943 bool allocationSucessful = DelayUnit_Reset(unit, className);
3944 if (!allocationSucessful)
3945 return initializationComplete;
3947 // optimize for a constant delay of zero
3948 if (DelayUnit_init_0(unit))
3949 return initializationComplete;
3950 return initializationIncomplete;
3953 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3955 void DelayN_Ctor(DelayN *unit)
3957 if (Delay_Ctor(unit, "DelayN") == initializationComplete)
3958 return;
3960 if (INRATE(2) == calc_FullRate)
3961 SETCALC(DelayN_next_a_z);
3962 else
3963 SETCALC(DelayN_next_z);
3964 ZOUT0(0) = 0.f;
3967 void DelayN_next(DelayN *unit, int inNumSamples)
3969 float *out = ZOUT(0);
3970 const float *in = ZIN(0);
3971 float delaytime = ZIN0(2);
3973 float *dlybuf = unit->m_dlybuf;
3974 long iwrphase = unit->m_iwrphase;
3975 float dsamp = unit->m_dsamp;
3976 long mask = unit->m_mask;
3978 //Print("DelayN_next %p %g %g %d %d\n", unit, delaytime, dsamp, mask, iwrphase);
3979 if (delaytime == unit->m_delaytime) {
3980 DelayN_delay_loop<false>(out, in, iwrphase, dsamp, mask, dlybuf, inNumSamples, unit->m_idelaylen);
3981 } else {
3982 float next_dsamp = CalcDelay(unit, delaytime);
3983 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
3985 LOOP1(inNumSamples,
3986 dsamp += dsamp_slope;
3987 DelayN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask);
3989 unit->m_dsamp = dsamp;
3990 unit->m_delaytime = delaytime;
3993 unit->m_iwrphase = iwrphase;
3997 void DelayN_next_z(DelayN *unit, int inNumSamples)
3999 float *out = ZOUT(0);
4000 const float *in = ZIN(0);
4001 float delaytime = ZIN0(2);
4003 float *dlybuf = unit->m_dlybuf;
4004 long iwrphase = unit->m_iwrphase;
4005 float dsamp = unit->m_dsamp;
4006 long mask = unit->m_mask;
4008 if (delaytime == unit->m_delaytime) {
4009 DelayN_delay_loop<true>(out, in, iwrphase, dsamp, mask, dlybuf, inNumSamples, unit->m_idelaylen);
4010 } else {
4011 float next_dsamp = CalcDelay(unit, delaytime);
4012 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4014 LOOP1(inNumSamples,
4015 dsamp += dsamp_slope;
4016 DelayN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask);
4018 unit->m_dsamp = dsamp;
4019 unit->m_delaytime = delaytime;
4022 unit->m_iwrphase = iwrphase;
4024 unit->m_numoutput += inNumSamples;
4025 if (unit->m_numoutput >= unit->m_idelaylen)
4026 SETCALC(DelayN_next);
4029 template <bool checked>
4030 inline void DelayN_perform_a(DelayN *unit, int inNumSamples)
4032 DelayX_perform_a<DelayN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayN_next_a);
4035 void DelayN_next_a(DelayN *unit, int inNumSamples)
4037 DelayN_perform_a<false>(unit, inNumSamples);
4040 void DelayN_next_a_z(DelayN *unit, int inNumSamples)
4042 DelayN_perform_a<true>(unit, inNumSamples);
4046 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4048 void DelayL_Ctor(DelayL *unit)
4050 if (Delay_Ctor(unit, "DelayL") == initializationComplete)
4051 return;
4053 if (INRATE(2) == calc_FullRate)
4054 SETCALC(DelayL_next_a_z);
4055 else
4056 SETCALC(DelayL_next_z);
4057 ZOUT0(0) = 0.f;
4060 template <bool checked>
4061 inline void DelayL_perform(DelayL *unit, int inNumSamples)
4063 DelayX_perform<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayL_next);
4066 void DelayL_next(DelayL *unit, int inNumSamples)
4068 DelayL_perform<false>(unit, inNumSamples);
4071 void DelayL_next_z(DelayL *unit, int inNumSamples)
4073 DelayL_perform<true>(unit, inNumSamples);
4076 template <bool checked>
4077 inline void DelayL_perform_a(DelayL *unit, int inNumSamples)
4079 DelayX_perform_a<DelayL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayL_next_a);
4082 void DelayL_next_a(DelayL *unit, int inNumSamples)
4084 DelayL_perform_a<false>(unit, inNumSamples);
4087 void DelayL_next_a_z(DelayL *unit, int inNumSamples)
4089 DelayL_perform_a<true>(unit, inNumSamples);
4093 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4095 void DelayC_Ctor(DelayC *unit)
4097 if (Delay_Ctor(unit, "DelayC") == initializationComplete)
4098 return;
4100 if (INRATE(2) == calc_FullRate)
4101 SETCALC(DelayC_next_a_z);
4102 else
4103 SETCALC(DelayC_next_z);
4104 ZOUT0(0) = 0.f;
4107 template <bool checked>
4108 inline void DelayC_perform(DelayC *unit, int inNumSamples)
4110 DelayX_perform<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayC_next);
4113 void DelayC_next(DelayC *unit, int inNumSamples)
4115 DelayC_perform<false>(unit, inNumSamples);
4118 void DelayC_next_z(DelayC *unit, int inNumSamples)
4120 DelayC_perform<true>(unit, inNumSamples);
4124 template <bool checked>
4125 inline void DelayC_perform_a(DelayC *unit, int inNumSamples)
4127 DelayX_perform_a<DelayC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)DelayC_next_a);
4130 void DelayC_next_a(DelayC *unit, int inNumSamples)
4132 DelayC_perform_a<false>(unit, inNumSamples);
4135 void DelayC_next_a_z(DelayC *unit, int inNumSamples)
4137 DelayC_perform_a<true>(unit, inNumSamples);
4140 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4141 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4143 template <typename PerformClass,
4144 typename BufCombX
4146 inline void FilterX_perform(BufCombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
4148 float *out = ZOUT(0);
4149 const float *in = ZIN(0);
4150 float delaytime = ZIN0(2);
4151 float decaytime = ZIN0(3);
4153 float *dlybuf = unit->m_dlybuf;
4154 long iwrphase = unit->m_iwrphase;
4155 float dsamp = unit->m_dsamp;
4156 float feedbk = unit->m_feedbk;
4157 long mask = unit->m_mask;
4159 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
4160 long idsamp = (long)dsamp;
4161 float frac = dsamp - idsamp;
4162 LOOP1(inNumSamples,
4163 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4165 } else {
4166 float next_dsamp = CalcDelay(unit, delaytime);
4167 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4169 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4170 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4172 LOOP1(inNumSamples,
4173 dsamp += dsamp_slope;
4174 feedbk += feedbk_slope;
4175 long idsamp = (long)dsamp;
4176 float frac = dsamp - idsamp;
4177 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4179 unit->m_feedbk = feedbk;
4180 unit->m_dsamp = dsamp;
4181 unit->m_delaytime = delaytime;
4182 unit->m_decaytime = decaytime;
4185 unit->m_iwrphase = iwrphase;
4187 if (PerformClass::checked) {
4188 unit->m_numoutput += inNumSamples;
4189 if (unit->m_numoutput >= unit->m_idelaylen)
4190 unit->mCalcFunc = resetFunc;
4194 template <typename PerformClass,
4195 typename CombX
4197 inline void FilterX_perform_a(CombX *unit, int inNumSamples, UnitCalcFunc resetFunc)
4199 float *out = ZOUT(0);
4200 const float *in = ZIN(0);
4201 float * delaytime = ZIN(2);
4202 float decaytime = ZIN0(3);
4204 float *dlybuf = unit->m_dlybuf;
4205 long iwrphase = unit->m_iwrphase;
4206 float dsamp = unit->m_dsamp;
4207 float feedbk = unit->m_feedbk;
4208 long mask = unit->m_mask;
4210 LOOP1(inNumSamples,
4211 float del = ZXP(delaytime);
4212 float dsamp = CalcDelay(unit, del);
4213 float feedbk = sc_CalcFeedback(del, decaytime);
4215 long idsamp = (long)dsamp;
4216 float frac = dsamp - idsamp;
4217 PerformClass::perform(in, out, dlybuf, iwrphase, idsamp, frac, mask, feedbk);
4220 unit->m_iwrphase = iwrphase;
4222 if (PerformClass::checked)
4224 unit->m_numoutput += inNumSamples;
4225 if (unit->m_numoutput >= unit->m_idelaylen)
4226 unit->mCalcFunc = resetFunc;
4230 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4232 void CombN_Ctor(CombN *unit)
4234 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombN");
4235 if (!allocationSucessful)
4236 return;
4238 if(INRATE(2) == calc_FullRate)
4239 SETCALC(CombN_next_a_z);
4240 else
4241 SETCALC(CombN_next_z);
4242 ZOUT0(0) = 0.f;
4245 void CombN_next(CombN *unit, int inNumSamples)
4247 float *out = ZOUT(0);
4248 const float *in = ZIN(0);
4249 float delaytime = ZIN0(2);
4250 float decaytime = ZIN0(3);
4252 float *dlybuf = unit->m_dlybuf;
4253 long iwrphase = unit->m_iwrphase;
4254 float dsamp = unit->m_dsamp;
4255 float feedbk = unit->m_feedbk;
4256 long mask = unit->m_mask;
4258 //postbuf("CombN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4259 if (delaytime == unit->m_delaytime) {
4260 long irdphase = iwrphase - (long)dsamp;
4261 float* dlybuf1 = dlybuf - ZOFF;
4262 float* dlyrd = dlybuf1 + (irdphase & mask);
4263 float* dlywr = dlybuf1 + (iwrphase & mask);
4264 float* dlyN = dlybuf1 + unit->m_idelaylen;
4265 if (decaytime == unit->m_decaytime) {
4266 long remain = inNumSamples;
4267 while (remain) {
4268 long rdspace = dlyN - dlyrd;
4269 long wrspace = dlyN - dlywr;
4270 long nsmps = sc_min(rdspace, wrspace);
4271 nsmps = sc_min(remain, nsmps);
4272 remain -= nsmps;
4273 LOOP(nsmps,
4274 float value = ZXP(dlyrd);
4275 ZXP(dlywr) = value * feedbk + ZXP(in);
4276 ZXP(out) = value;
4278 if (dlyrd == dlyN) dlyrd = dlybuf1;
4279 if (dlywr == dlyN) dlywr = dlybuf1;
4281 } else {
4282 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4283 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4284 long remain = inNumSamples;
4285 while (remain) {
4286 long rdspace = dlyN - dlyrd;
4287 long wrspace = dlyN - dlywr;
4288 long nsmps = sc_min(rdspace, wrspace);
4289 nsmps = sc_min(remain, nsmps);
4290 remain -= nsmps;
4292 LOOP(nsmps,
4293 float value = ZXP(dlyrd);
4294 ZXP(dlywr) = value * feedbk + ZXP(in);
4295 ZXP(out) = value;
4296 feedbk += feedbk_slope;
4298 if (dlyrd == dlyN) dlyrd = dlybuf1;
4299 if (dlywr == dlyN) dlywr = dlybuf1;
4301 unit->m_feedbk = feedbk;
4302 unit->m_decaytime = decaytime;
4304 iwrphase += inNumSamples;
4305 } else {
4306 float next_dsamp = CalcDelay(unit, delaytime);
4307 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4309 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4310 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4311 LOOP1(inNumSamples,
4312 dsamp += dsamp_slope;
4313 feedbk += feedbk_slope;
4314 CombN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4316 unit->m_feedbk = feedbk;
4317 unit->m_dsamp = dsamp;
4318 unit->m_delaytime = delaytime;
4319 unit->m_decaytime = decaytime;
4322 unit->m_iwrphase = iwrphase;
4326 void CombN_next_z(CombN *unit, int inNumSamples)
4328 float *out = ZOUT(0);
4329 const float *in = ZIN(0);
4330 float delaytime = ZIN0(2);
4331 float decaytime = ZIN0(3);
4333 float *dlybuf = unit->m_dlybuf;
4334 long iwrphase = unit->m_iwrphase;
4335 float dsamp = unit->m_dsamp;
4336 float feedbk = unit->m_feedbk;
4337 long mask = unit->m_mask;
4339 //postbuf("CombN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4340 if (delaytime == unit->m_delaytime) {
4341 long irdphase = iwrphase - (long)dsamp;
4342 float* dlybuf1 = dlybuf - ZOFF;
4343 float* dlyN = dlybuf1 + unit->m_idelaylen;
4344 if (decaytime == unit->m_decaytime) {
4345 long remain = inNumSamples;
4346 while (remain) {
4347 float* dlywr = dlybuf1 + (iwrphase & mask);
4348 float* dlyrd = dlybuf1 + (irdphase & mask);
4349 long rdspace = dlyN - dlyrd;
4350 long wrspace = dlyN - dlywr;
4351 long nsmps = sc_min(rdspace, wrspace);
4352 nsmps = sc_min(remain, nsmps);
4353 remain -= nsmps;
4354 if (irdphase < 0) {
4355 LOOP(nsmps,
4356 ZXP(dlywr) = ZXP(in);
4357 ZXP(out) = 0.f;
4359 } else {
4360 LOOP(nsmps,
4361 float value = ZXP(dlyrd);
4362 ZXP(dlywr) = value * feedbk + ZXP(in);
4363 ZXP(out) = value;
4366 iwrphase += nsmps;
4367 irdphase += nsmps;
4369 } else {
4370 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4371 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4372 long remain = inNumSamples;
4373 while (remain) {
4374 float* dlyrd = dlybuf1 + (irdphase & mask);
4375 float* dlywr = dlybuf1 + (iwrphase & mask);
4376 long rdspace = dlyN - dlyrd;
4377 long wrspace = dlyN - dlywr;
4378 long nsmps = sc_min(rdspace, wrspace);
4379 nsmps = sc_min(remain, nsmps);
4380 remain -= nsmps;
4382 if (irdphase < 0) {
4383 feedbk += nsmps * feedbk_slope;
4384 dlyrd += nsmps;
4385 LOOP(nsmps,
4386 ZXP(dlywr) = ZXP(in);
4387 ZXP(out) = 0.f;
4389 } else {
4390 LOOP(nsmps,
4391 float value = ZXP(dlyrd);
4392 ZXP(dlywr) = value * feedbk + ZXP(in);
4393 ZXP(out) = value;
4394 feedbk += feedbk_slope;
4397 iwrphase += nsmps;
4398 irdphase += nsmps;
4400 unit->m_feedbk = feedbk;
4401 unit->m_decaytime = decaytime;
4403 } else {
4405 float next_dsamp = CalcDelay(unit, delaytime);
4406 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4408 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4409 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4411 LOOP1(inNumSamples,
4412 dsamp += dsamp_slope;
4413 feedbk += feedbk_slope;
4414 CombN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4416 unit->m_feedbk = feedbk;
4417 unit->m_dsamp = dsamp;
4418 unit->m_delaytime = delaytime;
4419 unit->m_decaytime = decaytime;
4422 unit->m_iwrphase = iwrphase;
4424 unit->m_numoutput += inNumSamples;
4425 if (unit->m_numoutput >= unit->m_idelaylen)
4426 SETCALC(CombN_next);
4429 template <bool checked>
4430 inline void CombN_perform_a(CombN *unit, int inNumSamples)
4432 FilterX_perform_a<CombN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombN_next_a);
4435 void CombN_next_a(CombN *unit, int inNumSamples)
4437 CombN_perform_a<false>(unit, inNumSamples);
4440 void CombN_next_a_z(CombN *unit, int inNumSamples)
4442 CombN_perform_a<true>(unit, inNumSamples);
4446 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4447 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4449 void CombL_Ctor(CombL *unit)
4451 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombL");
4452 if (!allocationSucessful)
4453 return;
4455 if(INRATE(2) == calc_FullRate)
4456 SETCALC(CombL_next_a_z);
4457 else
4458 SETCALC(CombL_next_z);
4459 ZOUT0(0) = 0.f;
4462 template <bool checked>
4463 inline void CombL_perform(CombL *unit, int inNumSamples)
4465 FilterX_perform<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombL_next);
4468 void CombL_next(CombL *unit, int inNumSamples)
4470 CombL_perform<false>(unit, inNumSamples);
4473 void CombL_next_z(CombL *unit, int inNumSamples)
4475 CombL_perform<true>(unit, inNumSamples);
4478 template <bool checked>
4479 inline void CombL_perform_a(CombL *unit, int inNumSamples)
4481 FilterX_perform_a<CombL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombL_next_a);
4484 void CombL_next_a(CombL *unit, int inNumSamples)
4486 CombL_perform_a<false>(unit, inNumSamples);
4489 void CombL_next_a_z(CombL *unit, int inNumSamples)
4491 CombL_perform_a<true>(unit, inNumSamples);
4494 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4496 void CombC_Ctor(CombC *unit)
4498 bool allocationSucessful = FeedbackDelay_Reset(unit, "CombC");
4499 if (!allocationSucessful)
4500 return;
4502 if(INRATE(2) == calc_FullRate)
4503 SETCALC(CombC_next_a_z);
4504 else
4505 SETCALC(CombC_next_z);
4506 ZOUT0(0) = 0.f;
4509 template <bool checked>
4510 inline void CombC_perform(CombC *unit, int inNumSamples)
4512 FilterX_perform<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombC_next);
4515 void CombC_next(CombC *unit, int inNumSamples)
4517 CombC_perform<false>(unit, inNumSamples);
4520 void CombC_next_z(CombC *unit, int inNumSamples)
4522 CombC_perform<true>(unit, inNumSamples);
4525 template <bool checked>
4526 inline void CombC_perform_a(CombC *unit, int inNumSamples)
4528 FilterX_perform_a<CombC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)CombC_next_a);
4531 void CombC_next_a(CombC *unit, int inNumSamples)
4533 CombC_perform_a<false>(unit, inNumSamples);
4536 void CombC_next_a_z(CombC *unit, int inNumSamples)
4538 CombC_perform_a<true>(unit, inNumSamples);
4542 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4543 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4545 void AllpassN_Ctor(AllpassN *unit)
4547 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassN");
4548 if (!allocationSucessful)
4549 return;
4551 if(INRATE(2) == calc_FullRate)
4552 SETCALC(AllpassN_next_a_z);
4553 else
4554 SETCALC(AllpassN_next_z);
4555 ZOUT0(0) = 0.f;
4558 void AllpassN_next(AllpassN *unit, int inNumSamples)
4560 float *out = ZOUT(0);
4561 const float *in = ZIN(0);
4562 float delaytime = ZIN0(2);
4563 float decaytime = ZIN0(3);
4565 float *dlybuf = unit->m_dlybuf;
4566 long iwrphase = unit->m_iwrphase;
4567 float dsamp = unit->m_dsamp;
4568 float feedbk = unit->m_feedbk;
4569 long mask = unit->m_mask;
4571 //postbuf("AllpassN_next %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4572 if (delaytime == unit->m_delaytime) {
4573 long irdphase = iwrphase - (long)dsamp;
4574 float* dlybuf1 = dlybuf - ZOFF;
4575 float* dlyrd = dlybuf1 + (irdphase & mask);
4576 float* dlywr = dlybuf1 + (iwrphase & mask);
4577 float* dlyN = dlybuf1 + unit->m_idelaylen;
4578 if (decaytime == unit->m_decaytime) {
4579 long remain = inNumSamples;
4580 while (remain) {
4581 long rdspace = dlyN - dlyrd;
4582 long wrspace = dlyN - dlywr;
4583 long nsmps = sc_min(rdspace, wrspace);
4584 nsmps = sc_min(remain, nsmps);
4585 remain -= nsmps;
4586 LOOP(nsmps,
4587 float value = ZXP(dlyrd);
4588 float dwr = value * feedbk + ZXP(in);
4589 ZXP(dlywr) = dwr;
4590 ZXP(out) = value - feedbk * dwr;
4592 if (dlyrd == dlyN) dlyrd = dlybuf1;
4593 if (dlywr == dlyN) dlywr = dlybuf1;
4595 } else {
4596 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4597 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4598 long remain = inNumSamples;
4599 while (remain) {
4600 long rdspace = dlyN - dlyrd;
4601 long wrspace = dlyN - dlywr;
4602 long nsmps = sc_min(rdspace, wrspace);
4603 nsmps = sc_min(remain, nsmps);
4604 remain -= nsmps;
4606 LOOP(nsmps,
4607 float value = ZXP(dlyrd);
4608 float dwr = value * feedbk + ZXP(in);
4609 ZXP(dlywr) = dwr;
4610 ZXP(out) = value - feedbk * dwr;
4611 feedbk += feedbk_slope;
4613 if (dlyrd == dlyN) dlyrd = dlybuf1;
4614 if (dlywr == dlyN) dlywr = dlybuf1;
4616 unit->m_feedbk = feedbk;
4617 unit->m_decaytime = decaytime;
4619 iwrphase += inNumSamples;
4620 } else {
4621 float next_dsamp = CalcDelay(unit, delaytime);
4622 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4624 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4625 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4626 LOOP1(inNumSamples,
4627 dsamp += dsamp_slope;
4628 feedbk += feedbk_slope;
4629 AllpassN_helper<false>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4631 unit->m_feedbk = feedbk;
4632 unit->m_dsamp = dsamp;
4633 unit->m_delaytime = delaytime;
4634 unit->m_decaytime = decaytime;
4637 unit->m_iwrphase = iwrphase;
4641 void AllpassN_next_z(AllpassN *unit, int inNumSamples)
4643 float *out = ZOUT(0);
4644 const float *in = ZIN(0);
4645 float delaytime = ZIN0(2);
4646 float decaytime = ZIN0(3);
4648 float *dlybuf = unit->m_dlybuf;
4649 long iwrphase = unit->m_iwrphase;
4650 float dsamp = unit->m_dsamp;
4651 float feedbk = unit->m_feedbk;
4652 long mask = unit->m_mask;
4654 //postbuf("AllpassN_next_z %g %g %g %g %d %d %d\n", delaytime, decaytime, feedbk, dsamp, mask, iwrphase, zorg);
4655 if (delaytime == unit->m_delaytime) {
4656 long irdphase = iwrphase - (long)dsamp;
4657 float* dlybuf1 = dlybuf - ZOFF;
4658 float* dlyN = dlybuf1 + unit->m_idelaylen;
4659 if (decaytime == unit->m_decaytime) {
4660 long remain = inNumSamples;
4661 while (remain) {
4662 float* dlywr = dlybuf1 + (iwrphase & mask);
4663 float* dlyrd = dlybuf1 + (irdphase & mask);
4664 long rdspace = dlyN - dlyrd;
4665 long wrspace = dlyN - dlywr;
4666 long nsmps = sc_min(rdspace, wrspace);
4667 nsmps = sc_min(remain, nsmps);
4668 remain -= nsmps;
4669 if (irdphase < 0) {
4670 feedbk = -feedbk;
4671 LOOP(nsmps,
4672 float dwr = ZXP(in);
4673 ZXP(dlywr) = dwr;
4674 ZXP(out) = feedbk * dwr;
4676 feedbk = -feedbk;
4677 } else {
4678 LOOP(nsmps,
4679 float x1 = ZXP(dlyrd);
4680 float dwr = x1 * feedbk + ZXP(in);
4681 ZXP(dlywr) = dwr;
4682 ZXP(out) = x1 - feedbk * dwr;
4685 iwrphase += nsmps;
4686 irdphase += nsmps;
4688 } else {
4689 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4690 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4691 long remain = inNumSamples;
4692 while (remain) {
4693 float* dlyrd = dlybuf1 + (irdphase & mask);
4694 float* dlywr = dlybuf1 + (iwrphase & mask);
4695 long rdspace = dlyN - dlyrd;
4696 long wrspace = dlyN - dlywr;
4697 long nsmps = sc_min(rdspace, wrspace);
4698 nsmps = sc_min(remain, nsmps);
4699 remain -= nsmps;
4701 if (irdphase < 0) {
4702 dlyrd += nsmps;
4703 LOOP(nsmps,
4704 float dwr = ZXP(in);
4705 ZXP(dlywr) = dwr;
4706 ZXP(out) = -feedbk * dwr;
4707 feedbk += feedbk_slope;
4709 } else {
4710 LOOP(nsmps,
4711 float x1 = ZXP(dlyrd);
4712 float dwr = x1 * feedbk + ZXP(in);
4713 ZXP(dlywr) = dwr;
4714 ZXP(out) = x1 - feedbk * dwr;
4715 feedbk += feedbk_slope;
4718 iwrphase += nsmps;
4719 irdphase += nsmps;
4721 unit->m_feedbk = feedbk;
4722 unit->m_decaytime = decaytime;
4724 } else {
4725 float next_dsamp = CalcDelay(unit, delaytime);
4726 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
4728 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
4729 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
4731 LOOP1(inNumSamples,
4732 dsamp += dsamp_slope;
4733 feedbk += feedbk_slope;
4734 AllpassN_helper<true>::perform(in, out, dlybuf, iwrphase, (long)dsamp, mask, feedbk);
4736 unit->m_feedbk = feedbk;
4737 unit->m_dsamp = dsamp;
4738 unit->m_delaytime = delaytime;
4739 unit->m_decaytime = decaytime;
4742 unit->m_iwrphase = iwrphase;
4744 unit->m_numoutput += inNumSamples;
4745 if (unit->m_numoutput >= unit->m_idelaylen)
4746 SETCALC(AllpassN_next);
4749 template <bool checked>
4750 inline void AllpassN_perform_a(AllpassN *unit, int inNumSamples)
4752 FilterX_perform_a<AllpassN_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassN_next_a);
4755 void AllpassN_next_a(AllpassN *unit, int inNumSamples)
4757 AllpassN_perform_a<false>(unit, inNumSamples);
4760 void AllpassN_next_a_z(AllpassN *unit, int inNumSamples)
4762 AllpassN_perform_a<true>(unit, inNumSamples);
4766 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4767 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4769 void AllpassL_Ctor(AllpassL *unit)
4771 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassL");
4772 if (!allocationSucessful)
4773 return;
4775 if(INRATE(2) == calc_FullRate)
4776 SETCALC(AllpassL_next_a_z);
4777 else
4778 SETCALC(AllpassL_next_z);
4779 ZOUT0(0) = 0.f;
4782 template <bool checked>
4783 inline void AllpassL_perform(AllpassL *unit, int inNumSamples)
4785 FilterX_perform<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassL_next);
4788 void AllpassL_next(AllpassL *unit, int inNumSamples)
4790 AllpassL_perform<false>(unit, inNumSamples);
4793 void AllpassL_next_z(AllpassL *unit, int inNumSamples)
4795 AllpassL_perform<true>(unit, inNumSamples);
4798 template <bool checked>
4799 inline void AllpassL_perform_a(AllpassL *unit, int inNumSamples)
4801 FilterX_perform_a<AllpassL_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassL_next_a);
4804 void AllpassL_next_a(AllpassL *unit, int inNumSamples)
4806 AllpassL_perform_a<false>(unit, inNumSamples);
4809 void AllpassL_next_a_z(AllpassL *unit, int inNumSamples)
4811 AllpassL_perform_a<true>(unit, inNumSamples);
4814 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4815 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4817 void AllpassC_Ctor(AllpassC *unit)
4819 bool allocationSucessful = FeedbackDelay_Reset(unit, "AllpassC");
4820 if (!allocationSucessful)
4821 return;
4823 if(INRATE(2) == calc_FullRate)
4824 SETCALC(AllpassC_next_a_z);
4825 else
4826 SETCALC(AllpassC_next_z);
4827 ZOUT0(0) = 0.f;
4830 template <bool checked>
4831 inline void AllpassC_perform(AllpassC *unit, int inNumSamples)
4833 FilterX_perform<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassC_next);
4836 void AllpassC_next(AllpassC *unit, int inNumSamples)
4838 AllpassC_perform<false>(unit, inNumSamples);
4841 void AllpassC_next_z(AllpassC *unit, int inNumSamples)
4843 AllpassC_perform<true>(unit, inNumSamples);
4846 template <bool checked>
4847 inline void AllpassC_perform_a(AllpassC *unit, int inNumSamples)
4849 FilterX_perform_a<AllpassC_helper<checked> >(unit, inNumSamples, (UnitCalcFunc)AllpassC_next_a);
4852 void AllpassC_next_a(AllpassC *unit, int inNumSamples)
4854 AllpassC_perform_a<false>(unit, inNumSamples);
4857 void AllpassC_next_a_z(AllpassC *unit, int inNumSamples)
4859 AllpassC_perform_a<true>(unit, inNumSamples);
4862 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4865 inline double sc_loop1(int32 in, int32 lo, int32 hi)
4867 // avoid the divide if possible
4868 if (in >= hi) {
4869 in -= hi;
4870 if (in < hi) return in;
4871 } else if (in < lo) {
4872 in += hi;
4873 if (in >= lo) return in;
4874 } else return in;
4876 int32 range = hi - lo;
4877 return lo + range * (in-lo) / range;
4880 #if NOTYET
4882 void SimpleLoopBuf_next_kk(SimpleLoopBuf *unit, int inNumSamples)
4884 float trig = ZIN0(1);
4885 double loopstart = (double)ZIN0(2);
4886 double loopend = (double)ZIN0(3);
4887 GET_BUF
4889 int numOutputs = unit->mNumOutputs;
4890 if (!checkBuffer(unit, bufData, bufChannels, numOutputs, inNumSamples))
4891 return;
4894 loopend = sc_max(loopend, bufFrames);
4895 int32 phase = unit->m_phase;
4896 if (trig > 0.f && unit->m_prevtrig <= 0.f) {
4897 unit->mDone = false;
4898 phase = (int32)ZIN0(2);
4900 unit->m_prevtrig = trig;
4901 for (int i=0; i<inNumSamples; ++i) {
4902 phase = sc_loop1(phase, loopstart, loopend);
4903 int32 iphase = (int32)phase;
4904 float* table1 = bufData + iphase * bufChannels;
4905 int32 index = 0;
4906 for (uint32 channel=0; channel<bufChannels; ++channel) {
4907 OUT(channel[i]) = table1[index++];
4910 phase++;
4912 unit->m_phase = phase;
4916 void SimpleLoopBuf_Ctor(SimpleLoopBuf *unit)
4918 SETCALC(SimpleLoopBuf_next_kk);
4920 unit->m_fbufnum = -1e9f;
4921 unit->m_prevtrig = 0.;
4922 unit->m_phase = ZIN0(2);
4924 ClearUnitOutputs(unit, 1);
4926 #endif
4928 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4931 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4933 #define GET_SCOPEBUF \
4934 float fbufnum = ZIN0(0); \
4935 if (fbufnum != unit->m_fbufnum) { \
4936 World *world = unit->mWorld; \
4937 if (!world->mNumSndBufs) { \
4938 ClearUnitOutputs(unit, inNumSamples); \
4939 return; \
4941 uint32 bufnum = (int)fbufnum; \
4942 if (bufnum >= world->mNumSndBufs) bufnum = 0; \
4943 unit->m_fbufnum = fbufnum; \
4944 unit->m_buf = world->mSndBufs + bufnum; \
4945 unit->m_bufupdates = world->mSndBufUpdates + bufnum; \
4947 SndBuf *buf = unit->m_buf; \
4948 LOCK_SNDBUF(buf); \
4949 SndBufUpdates *bufupdates = unit->m_bufupdates; \
4950 float *bufData __attribute__((__unused__)) = buf->data; \
4951 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
4952 uint32 bufFrames __attribute__((__unused__)) = buf->frames; \
4954 void ScopeOut_next(ScopeOut *unit, int inNumSamples)
4956 GET_SCOPEBUF
4958 if (!bufData) {
4959 unit->m_framepos = 0;
4960 return;
4963 SETUP_IN(1)
4965 uint32 framepos = unit->m_framepos;
4966 if (framepos >= bufFrames) {
4967 unit->m_framepos = 0;
4970 if (bufupdates->reads != bufupdates->writes) {
4971 unit->m_framepos += inNumSamples;
4972 return;
4975 bufData += framepos * bufChannels;
4977 int remain = (bufFrames - framepos), wrap = 0;
4979 if(inNumSamples <= remain) {
4980 remain = inNumSamples;
4981 wrap = 0;
4983 else
4984 wrap = inNumSamples - remain;
4986 if (bufChannels > 2) {
4987 for (int j=0; j<remain; ++j) {
4988 for (uint32 i=0; i<bufChannels; ++i) {
4989 *bufData++ = *++(in[i]);
4993 bufData = buf->data;
4995 for (int j=0; j<wrap; ++j) {
4996 for (uint32 i=0; i<bufChannels; ++i) {
4997 *bufData++ = *++(in[i]);
5000 } else if (bufChannels == 2) {
5001 float *in0 = in[0];
5002 float *in1 = in[1];
5003 for (int j=0; j<remain; ++j) {
5004 *bufData++ = *++in0;
5005 *bufData++ = *++in1;
5008 bufData = buf->data;
5010 for (int j=0; j<wrap; ++j) {
5011 *bufData++ = *++in0;
5012 *bufData++ = *++in1;
5014 } else {
5015 float *in0 = in[0];
5016 for (int j=0; j<remain; ++j) {
5017 *bufData++ = *++in0;
5020 bufData = buf->data;
5022 for (int j=0; j<wrap; ++j) {
5023 *bufData++ = *++in0;
5027 unit->m_framepos += inNumSamples;
5028 unit->m_framecount += inNumSamples;
5030 if (unit->m_framecount >= bufFrames) {
5031 bufupdates->writes++;
5032 unit->m_framecount = 0;
5038 void ScopeOut_Ctor(ScopeOut *unit)
5041 unit->m_fbufnum = -1e9;
5042 unit->m_framepos = 0;
5043 unit->m_framecount = 0;
5044 unit->mIn = 0;
5045 SETCALC(ScopeOut_next);
5048 void ScopeOut_Dtor(ScopeOut *unit)
5050 TAKEDOWN_IN
5053 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5055 struct ScopeOut2 : public Unit
5057 ScopeBufferHnd m_buffer;
5058 float **m_inBuffers;
5059 int m_maxPeriod;
5060 uint32 m_phase;
5064 void ScopeOut2_next(ScopeOut2 *unit, int inNumSamples)
5066 if( !unit->m_buffer ) return;
5068 const int inputOffset = 3;
5069 int numChannels = unit->mNumInputs - inputOffset;
5071 uint32 period = (uint32)ZIN0(2);
5072 uint32 framepos = unit->m_phase;
5074 period = std::max((uint32)inNumSamples, std::min(unit->m_buffer.maxFrames, period));
5076 if( framepos >= period ) framepos = 0;
5078 int remain = period - framepos, wrap = 0;
5080 if(inNumSamples <= remain)
5081 remain = inNumSamples;
5082 else
5083 wrap = inNumSamples - remain;
5085 for (int i = 0; i != numChannels; ++i) {
5086 float * inBuf = unit->m_buffer.channel_data(i);
5087 const float * in = IN(inputOffset + i);
5089 memcpy(inBuf + framepos, in, remain * sizeof(float));
5092 if(framepos + inNumSamples >= period)
5093 (*ft->fPushScopeBuffer)(unit->mWorld, unit->m_buffer, period);
5095 if (wrap) {
5096 for (int i = 0; i != numChannels; ++i) {
5097 float * inBuf = unit->m_buffer.channel_data(i);
5098 const float * in = IN(inputOffset + i);
5099 memcpy(inBuf, in + remain, wrap * sizeof(float));
5103 framepos += inNumSamples;
5104 if (framepos >= period)
5105 framepos = wrap;
5107 unit->m_phase = framepos;
5110 void ScopeOut2_Ctor(ScopeOut2 *unit)
5112 uint32 numChannels = unit->mNumInputs - 3;
5113 uint32 scopeNum = (uint32)ZIN0(0);
5114 uint32 maxFrames = (uint32)ZIN0(1);
5116 bool ok = (*ft->fGetScopeBuffer)(unit->mWorld, scopeNum, numChannels, maxFrames, unit->m_buffer);
5118 if( !ok ) {
5119 if( unit->mWorld->mVerbosity > -1 && !unit->mDone)
5120 Print("ScopeOut2: Requested scope buffer unavailable! (index: %d, channels: %d, size: %d)\n",
5121 scopeNum, numChannels, maxFrames);
5123 else {
5124 unit->m_phase = 0;
5127 SETCALC(ScopeOut2_next);
5130 void ScopeOut2_Dtor(ScopeOut2 *unit)
5132 if( unit->m_buffer )
5133 (*ft->fReleaseScopeBuffer)(unit->mWorld, unit->m_buffer);
5137 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5139 struct PitchShift : public Unit
5141 float *dlybuf;
5142 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5143 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5144 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5145 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5146 float fdelaylen, slope;
5147 long iwrphase, idelaylen, mask;
5148 long counter, stage, numoutput, framesize;
5151 void PitchShift_next(PitchShift *unit, int inNumSamples);
5152 void PitchShift_next(PitchShift *unit, int inNumSamples)
5154 float *out, *in, *dlybuf;
5155 float disppchratio, pchratio, pchratio1, value;
5156 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5157 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5158 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5159 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5160 float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, winsize, pchdisp, timedisp;
5161 long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp;
5162 long counter, stage, framesize;
5164 RGET
5166 out = ZOUT(0);
5167 in = ZIN(0);
5169 pchratio = ZIN0(2);
5170 winsize = ZIN0(1);
5171 pchdisp = ZIN0(3);
5172 timedisp = ZIN0(4);
5173 timedisp = sc_clip(timedisp, 0.f, winsize) * SAMPLERATE;
5175 dlybuf = unit->dlybuf;
5176 fdelaylen = unit->fdelaylen;
5177 idelaylen = unit->idelaylen;
5178 iwrphase = unit->iwrphase;
5180 counter = unit->counter;
5181 stage = unit->stage;
5182 mask = unit->mask;
5183 framesize = unit->framesize;
5185 dsamp1 = unit->dsamp1;
5186 dsamp2 = unit->dsamp2;
5187 dsamp3 = unit->dsamp3;
5188 dsamp4 = unit->dsamp4;
5190 dsamp1_slope = unit->dsamp1_slope;
5191 dsamp2_slope = unit->dsamp2_slope;
5192 dsamp3_slope = unit->dsamp3_slope;
5193 dsamp4_slope = unit->dsamp4_slope;
5195 ramp1 = unit->ramp1;
5196 ramp2 = unit->ramp2;
5197 ramp3 = unit->ramp3;
5198 ramp4 = unit->ramp4;
5200 ramp1_slope = unit->ramp1_slope;
5201 ramp2_slope = unit->ramp2_slope;
5202 ramp3_slope = unit->ramp3_slope;
5203 ramp4_slope = unit->ramp4_slope;
5205 slope = unit->slope;
5207 remain = inNumSamples;
5208 while (remain) {
5209 if (counter <= 0) {
5210 counter = framesize >> 2;
5211 unit->stage = stage = (stage + 1) & 3;
5212 disppchratio = pchratio;
5213 if (pchdisp != 0.f) {
5214 disppchratio += (pchdisp * frand2(s1,s2,s3));
5216 disppchratio = sc_clip(disppchratio, 0.f, 4.f);
5217 pchratio1 = disppchratio - 1.f;
5218 samp_slope = -pchratio1;
5219 startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
5220 startpos += (timedisp * frand(s1,s2,s3));
5221 switch(stage) {
5222 case 0 :
5223 unit->dsamp1_slope = dsamp1_slope = samp_slope;
5224 dsamp1 = startpos;
5225 ramp1 = 0.0;
5226 unit->ramp1_slope = ramp1_slope = slope;
5227 unit->ramp3_slope = ramp3_slope = -slope;
5228 break;
5229 case 1 :
5230 unit->dsamp2_slope = dsamp2_slope = samp_slope;
5231 dsamp2 = startpos;
5232 ramp2 = 0.0;
5233 unit->ramp2_slope = ramp2_slope = slope;
5234 unit->ramp4_slope = ramp4_slope = -slope;
5235 break;
5236 case 2 :
5237 unit->dsamp3_slope = dsamp3_slope = samp_slope;
5238 dsamp3 = startpos;
5239 ramp3 = 0.0;
5240 unit->ramp3_slope = ramp3_slope = slope;
5241 unit->ramp1_slope = ramp1_slope = -slope;
5242 break;
5243 case 3 :
5244 unit->dsamp4_slope = dsamp4_slope = samp_slope;
5245 dsamp4 = startpos;
5246 ramp4 = 0.0;
5247 unit->ramp2_slope = ramp2_slope = -slope;
5248 unit->ramp4_slope = ramp4_slope = slope;
5249 break;
5251 /*Print("%d %d %g %g %g %g %g %g %g %g %g %g %g %g\n",
5252 counter, stage, dsamp1_slope, dsamp2_slope, dsamp3_slope, dsamp4_slope,
5253 dsamp1, dsamp2, dsamp3, dsamp4,
5254 ramp1, ramp2, ramp3, ramp4);*/
5258 nsmps = sc_min(remain, counter);
5259 remain -= nsmps;
5260 counter -= nsmps;
5262 LOOP(nsmps,
5263 iwrphase = (iwrphase + 1) & mask;
5265 dsamp1 += dsamp1_slope;
5266 idsamp = (long)dsamp1;
5267 frac = dsamp1 - idsamp;
5268 irdphase = (iwrphase - idsamp) & mask;
5269 irdphaseb = (irdphase - 1) & mask;
5270 d1 = dlybuf[irdphase];
5271 d2 = dlybuf[irdphaseb];
5272 value = (d1 + frac * (d2 - d1)) * ramp1;
5273 ramp1 += ramp1_slope;
5275 dsamp2 += dsamp2_slope;
5276 idsamp = (long)dsamp2;
5277 frac = dsamp2 - idsamp;
5278 irdphase = (iwrphase - idsamp) & mask;
5279 irdphaseb = (irdphase - 1) & mask;
5280 d1 = dlybuf[irdphase];
5281 d2 = dlybuf[irdphaseb];
5282 value += (d1 + frac * (d2 - d1)) * ramp2;
5283 ramp2 += ramp2_slope;
5285 dsamp3 += dsamp3_slope;
5286 idsamp = (long)dsamp3;
5287 frac = dsamp3 - idsamp;
5288 irdphase = (iwrphase - idsamp) & mask;
5289 irdphaseb = (irdphase - 1) & mask;
5290 d1 = dlybuf[irdphase];
5291 d2 = dlybuf[irdphaseb];
5292 value += (d1 + frac * (d2 - d1)) * ramp3;
5293 ramp3 += ramp3_slope;
5295 dsamp4 += dsamp4_slope;
5296 idsamp = (long)dsamp4;
5297 frac = dsamp4 - idsamp;
5298 irdphase = (iwrphase - idsamp) & mask;
5299 irdphaseb = (irdphase - 1) & mask;
5300 d1 = dlybuf[irdphase];
5301 d2 = dlybuf[irdphaseb];
5302 value += (d1 + frac * (d2 - d1)) * ramp4;
5303 ramp4 += ramp4_slope;
5305 dlybuf[iwrphase] = ZXP(in);
5306 ZXP(out) = value *= 0.5;
5310 unit->counter = counter;
5312 unit->dsamp1 = dsamp1;
5313 unit->dsamp2 = dsamp2;
5314 unit->dsamp3 = dsamp3;
5315 unit->dsamp4 = dsamp4;
5317 unit->ramp1 = ramp1;
5318 unit->ramp2 = ramp2;
5319 unit->ramp3 = ramp3;
5320 unit->ramp4 = ramp4;
5322 unit->iwrphase = iwrphase;
5324 RPUT
5330 void PitchShift_next_z(PitchShift *unit, int inNumSamples);
5331 void PitchShift_next_z(PitchShift *unit, int inNumSamples)
5333 float *out, *in, *dlybuf;
5334 float disppchratio, pchratio, pchratio1, value;
5335 float dsamp1, dsamp1_slope, ramp1, ramp1_slope;
5336 float dsamp2, dsamp2_slope, ramp2, ramp2_slope;
5337 float dsamp3, dsamp3_slope, ramp3, ramp3_slope;
5338 float dsamp4, dsamp4_slope, ramp4, ramp4_slope;
5339 float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, winsize, pchdisp, timedisp;
5340 long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase;
5341 long mask, idsamp;
5342 long counter, stage, framesize, numoutput;
5344 RGET
5346 out = ZOUT(0);
5347 in = ZIN(0);
5348 pchratio = ZIN0(2);
5349 winsize = ZIN0(1);
5350 pchdisp = ZIN0(3);
5351 timedisp = ZIN0(4);
5352 timedisp = sc_clip(timedisp, 0.f, winsize) * SAMPLERATE;
5354 dlybuf = unit->dlybuf;
5355 fdelaylen = unit->fdelaylen;
5356 idelaylen = unit->idelaylen;
5357 iwrphase = unit->iwrphase;
5358 numoutput = unit->numoutput;
5360 counter = unit->counter;
5361 stage = unit->stage;
5362 mask = unit->mask;
5363 framesize = unit->framesize;
5365 dsamp1 = unit->dsamp1;
5366 dsamp2 = unit->dsamp2;
5367 dsamp3 = unit->dsamp3;
5368 dsamp4 = unit->dsamp4;
5370 dsamp1_slope = unit->dsamp1_slope;
5371 dsamp2_slope = unit->dsamp2_slope;
5372 dsamp3_slope = unit->dsamp3_slope;
5373 dsamp4_slope = unit->dsamp4_slope;
5375 ramp1 = unit->ramp1;
5376 ramp2 = unit->ramp2;
5377 ramp3 = unit->ramp3;
5378 ramp4 = unit->ramp4;
5380 ramp1_slope = unit->ramp1_slope;
5381 ramp2_slope = unit->ramp2_slope;
5382 ramp3_slope = unit->ramp3_slope;
5383 ramp4_slope = unit->ramp4_slope;
5385 slope = unit->slope;
5387 remain = inNumSamples;
5388 while (remain) {
5389 if (counter <= 0) {
5390 counter = framesize >> 2;
5391 unit->stage = stage = (stage + 1) & 3;
5392 disppchratio = pchratio;
5393 if (pchdisp != 0.f) {
5394 disppchratio += (pchdisp * frand2(s1,s2,s3));
5396 disppchratio = sc_clip(disppchratio, 0.f, 4.f);
5397 pchratio1 = disppchratio - 1.f;
5398 samp_slope = -pchratio1;
5399 startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f;
5400 startpos += (timedisp * frand(s1,s2,s3));
5401 switch(stage) {
5402 case 0 :
5403 unit->dsamp1_slope = dsamp1_slope = samp_slope;
5404 dsamp1 = startpos;
5405 ramp1 = 0.0;
5406 unit->ramp1_slope = ramp1_slope = slope;
5407 unit->ramp3_slope = ramp3_slope = -slope;
5408 break;
5409 case 1 :
5410 unit->dsamp2_slope = dsamp2_slope = samp_slope;
5411 dsamp2 = startpos;
5412 ramp2 = 0.0;
5413 unit->ramp2_slope = ramp2_slope = slope;
5414 unit->ramp4_slope = ramp4_slope = -slope;
5415 break;
5416 case 2 :
5417 unit->dsamp3_slope = dsamp3_slope = samp_slope;
5418 dsamp3 = startpos;
5419 ramp3 = 0.0;
5420 unit->ramp3_slope = ramp3_slope = slope;
5421 unit->ramp1_slope = ramp1_slope = -slope;
5422 break;
5423 case 3 :
5424 unit->dsamp4_slope = dsamp4_slope = samp_slope;
5425 dsamp4 = startpos;
5426 ramp4 = 0.0;
5427 unit->ramp2_slope = ramp2_slope = -slope;
5428 unit->ramp4_slope = ramp4_slope = slope;
5429 break;
5431 /*Print("z %d %d %g %g %g %g %g %g %g %g %g %g %g %g\n",
5432 counter, stage, dsamp1_slope, dsamp2_slope, dsamp3_slope, dsamp4_slope,
5433 dsamp1, dsamp2, dsamp3, dsamp4,
5434 ramp1, ramp2, ramp3, ramp4);*/
5436 nsmps = sc_min(remain, counter);
5437 remain -= nsmps;
5438 counter -= nsmps;
5440 while (nsmps--) {
5441 numoutput++;
5442 iwrphase = (iwrphase + 1) & mask;
5444 dsamp1 += dsamp1_slope;
5445 idsamp = (long)dsamp1;
5446 frac = dsamp1 - idsamp;
5447 irdphase = (iwrphase - idsamp) & mask;
5448 irdphaseb = (irdphase - 1) & mask;
5449 if (numoutput < idelaylen) {
5450 if (irdphase > iwrphase) {
5451 value = 0.f;
5452 } else if (irdphaseb > iwrphase) {
5453 d1 = dlybuf[irdphase];
5454 value = (d1 - frac * d1) * ramp1;
5455 } else {
5456 d1 = dlybuf[irdphase];
5457 d2 = dlybuf[irdphaseb];
5458 value = (d1 + frac * (d2 - d1)) * ramp1;
5460 } else {
5461 d1 = dlybuf[irdphase];
5462 d2 = dlybuf[irdphaseb];
5463 value = (d1 + frac * (d2 - d1)) * ramp1;
5465 ramp1 += ramp1_slope;
5467 dsamp2 += dsamp2_slope;
5468 idsamp = (long)dsamp2;
5469 frac = dsamp2 - idsamp;
5470 irdphase = (iwrphase - idsamp) & mask;
5471 irdphaseb = (irdphase - 1) & mask;
5472 if (numoutput < idelaylen) {
5473 if (irdphase > iwrphase) {
5474 //value += 0.f;
5475 } else if (irdphaseb > iwrphase) {
5476 d1 = dlybuf[irdphase];
5477 value += (d1 - frac * d1) * ramp2;
5478 } else {
5479 d1 = dlybuf[irdphase];
5480 d2 = dlybuf[irdphaseb];
5481 value += (d1 + frac * (d2 - d1)) * ramp2;
5483 } else {
5484 d1 = dlybuf[irdphase];
5485 d2 = dlybuf[irdphaseb];
5486 value += (d1 + frac * (d2 - d1)) * ramp2;
5488 ramp2 += ramp2_slope;
5490 dsamp3 += dsamp3_slope;
5491 idsamp = (long)dsamp3;
5492 frac = dsamp3 - idsamp;
5493 irdphase = (iwrphase - idsamp) & mask;
5494 irdphaseb = (irdphase - 1) & mask;
5495 if (numoutput < idelaylen) {
5496 if (irdphase > iwrphase) {
5497 //value += 0.f;
5498 } else if (irdphaseb > iwrphase) {
5499 d1 = dlybuf[irdphase];
5500 value += (d1 - frac * d1) * ramp3;
5501 } else {
5502 d1 = dlybuf[irdphase];
5503 d2 = dlybuf[irdphaseb];
5504 value += (d1 + frac * (d2 - d1)) * ramp3;
5506 } else {
5507 d1 = dlybuf[irdphase];
5508 d2 = dlybuf[irdphaseb];
5509 value += (d1 + frac * (d2 - d1)) * ramp3;
5511 ramp3 += ramp3_slope;
5513 dsamp4 += dsamp4_slope;
5514 idsamp = (long)dsamp4;
5515 frac = dsamp4 - idsamp;
5516 irdphase = (iwrphase - idsamp) & mask;
5517 irdphaseb = (irdphase - 1) & mask;
5519 if (numoutput < idelaylen) {
5520 if (irdphase > iwrphase) {
5521 //value += 0.f;
5522 } else if (irdphaseb > iwrphase) {
5523 d1 = dlybuf[irdphase];
5524 value += (d1 - frac * d1) * ramp4;
5525 } else {
5526 d1 = dlybuf[irdphase];
5527 d2 = dlybuf[irdphaseb];
5528 value += (d1 + frac * (d2 - d1)) * ramp4;
5530 } else {
5531 d1 = dlybuf[irdphase];
5532 d2 = dlybuf[irdphaseb];
5533 value += (d1 + frac * (d2 - d1)) * ramp4;
5535 ramp4 += ramp4_slope;
5537 dlybuf[iwrphase] = ZXP(in);
5538 ZXP(out) = value *= 0.5;
5542 unit->counter = counter;
5543 unit->stage = stage;
5544 unit->mask = mask;
5546 unit->dsamp1 = dsamp1;
5547 unit->dsamp2 = dsamp2;
5548 unit->dsamp3 = dsamp3;
5549 unit->dsamp4 = dsamp4;
5551 unit->ramp1 = ramp1;
5552 unit->ramp2 = ramp2;
5553 unit->ramp3 = ramp3;
5554 unit->ramp4 = ramp4;
5556 unit->numoutput = numoutput;
5557 unit->iwrphase = iwrphase;
5559 if (numoutput >= idelaylen) {
5560 SETCALC(PitchShift_next);
5563 RPUT
5567 void PitchShift_Ctor(PitchShift *unit);
5568 void PitchShift_Ctor(PitchShift *unit)
5570 long delaybufsize;
5571 float *out, *in, *dlybuf;
5572 float winsize, pchratio;
5573 float fdelaylen, slope;
5574 long framesize, last;
5576 out = ZOUT(0);
5577 in = ZIN(0);
5578 pchratio = ZIN0(2);
5579 winsize = ZIN0(1);
5581 delaybufsize = (long)ceil(winsize * SAMPLERATE * 3.f + 3.f);
5582 fdelaylen = delaybufsize - 3;
5584 delaybufsize = delaybufsize + BUFLENGTH;
5585 delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two
5586 dlybuf = (float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float));
5588 SETCALC(PitchShift_next_z);
5590 *dlybuf = ZIN0(0);
5591 ZOUT0(0) = 0.f;
5593 unit->dlybuf = dlybuf;
5594 unit->idelaylen = delaybufsize;
5595 unit->fdelaylen = fdelaylen;
5596 unit->iwrphase = 0;
5597 unit->numoutput = 0;
5598 unit->mask = last = (delaybufsize - 1);
5600 unit->framesize = framesize = ((long)(winsize * SAMPLERATE) + 2) & ~3;
5601 unit->slope = slope = 2.f / framesize;
5602 unit->stage = 3;
5603 unit->counter = framesize >> 2;
5604 unit->ramp1 = 0.5;
5605 unit->ramp2 = 1.0;
5606 unit->ramp3 = 0.5;
5607 unit->ramp4 = 0.0;
5609 unit->ramp1_slope = -slope;
5610 unit->ramp2_slope = -slope;
5611 unit->ramp3_slope = slope;
5612 unit->ramp4_slope = slope;
5614 dlybuf[last ] = 0.f; // put a few zeroes where we start the read heads
5615 dlybuf[last-1] = 0.f;
5616 dlybuf[last-2] = 0.f;
5618 unit->numoutput = 0;
5620 // start all read heads 2 samples behind the write head
5621 unit->dsamp1 = unit->dsamp2 = unit->dsamp3 = unit->dsamp4 = 2.f;
5622 // pch ratio is initially zero for the read heads
5623 unit->dsamp1_slope = unit->dsamp2_slope = unit->dsamp3_slope = unit->dsamp4_slope = 1.f;
5628 void PitchShift_Dtor(PitchShift *unit)
5630 RTFree(unit->mWorld, unit->dlybuf);
5636 typedef struct graintap1 {
5637 float pos, rate, level, slope, curve;
5638 long counter;
5639 struct graintap1 *next;
5640 } GrainTap1;
5642 #define MAXDGRAINS 32
5644 struct GrainTap : public Unit
5646 float m_fbufnum;
5647 SndBuf *m_buf;
5649 float fdelaylen;
5650 long bufsize, iwrphase;
5651 long nextTime;
5652 GrainTap1 grains[MAXDGRAINS];
5653 GrainTap1 *firstActive, *firstFree;
5657 // coefs: pos, rate, level, slope, curve, counter
5659 void GrainTap_next(GrainTap *unit, int inNumSamples);
5660 void GrainTap_next(GrainTap *unit, int inNumSamples)
5662 float *out, *out0;
5663 const float * dlybuf;
5664 float sdur, rdur, rdur2;
5665 float dsamp, dsamp_slope, fdelaylen, d1, d2, frac;
5666 float level, slope, curve;
5667 float maxpitch, pitch, maxtimedisp, timedisp, density;
5668 long remain, nsmps, irdphase, irdphaseb, iwrphase, iwrphase0;
5669 long idsamp, koffset;
5670 long counter;
5671 uint32 bufsize;
5672 GrainTap1 *grain, *prevGrain, *nextGrain;
5674 GET_BUF_SHARED
5676 RGET
5678 out0 = ZOUT(0);
5680 // bufnum, grainDur, pchRatio, pchDisp, timeDisp, overlap
5681 // 0 1 2 3 4 5
5683 density = ZIN0(5);
5684 density = sc_max(0.0001, density);
5686 bufsize = unit->bufsize;
5687 if (bufsize != bufSamples) {
5688 ClearUnitOutputs(unit, inNumSamples);
5689 return;
5692 dlybuf = bufData;
5693 fdelaylen = unit->fdelaylen;
5694 iwrphase0 = unit->iwrphase;
5696 // initialize buffer to zero
5697 out = out0;
5698 LOOP1(inNumSamples, ZXP(out) = 0.f;);
5700 // do all current grains
5701 prevGrain = NULL;
5702 grain = unit->firstActive;
5703 while (grain) {
5705 dsamp = grain->pos;
5706 dsamp_slope = grain->rate;
5707 level = grain->level;
5708 slope = grain->slope;
5709 curve = grain->curve;
5710 counter = grain->counter;
5712 nsmps = sc_min(counter, inNumSamples);
5713 iwrphase = iwrphase0;
5714 out = out0;
5715 LOOP(nsmps,
5716 dsamp += dsamp_slope;
5717 idsamp = (long)dsamp;
5718 frac = dsamp - idsamp;
5719 iwrphase = (iwrphase + 1) & mask;
5720 irdphase = (iwrphase - idsamp) & mask;
5721 irdphaseb = (irdphase - 1) & mask;
5722 d1 = dlybuf[irdphase];
5723 d2 = dlybuf[irdphaseb];
5724 ZXP(out) += (d1 + frac * (d2 - d1)) * level;
5725 level += slope;
5726 slope += curve;
5728 grain->pos = dsamp;
5729 grain->level = level;
5730 grain->slope = slope;
5731 grain->counter -= nsmps;
5733 nextGrain = grain->next;
5734 if (grain->counter <= 0) {
5735 // unlink from active list
5736 if (prevGrain) prevGrain->next = nextGrain;
5737 else unit->firstActive = nextGrain;
5739 // link onto free list
5740 grain->next = unit->firstFree;
5741 unit->firstFree = grain;
5742 } else {
5743 prevGrain = grain;
5745 grain = nextGrain;
5747 // start new grains
5748 remain = inNumSamples;
5749 while (unit->nextTime <= remain) {
5750 remain -= unit->nextTime;
5751 sdur = ZIN0(1) * SAMPLERATE;
5752 sdur = sc_max(sdur, 4.f);
5754 grain = unit->firstFree;
5755 if (grain) {
5756 unit->firstFree = grain->next;
5757 grain->next = unit->firstActive;
5758 unit->firstActive = grain;
5760 koffset = inNumSamples - remain;
5761 iwrphase = (iwrphase0 + koffset) & mask;
5763 grain->counter = (long)sdur;
5765 timedisp = ZIN0(4);
5766 timedisp = sc_max(timedisp, 0.f);
5767 timedisp = frand(s1,s2,s3) * timedisp * SAMPLERATE;
5769 pitch = ZIN0(2) + frand2(s1,s2,s3) * ZIN0(3);
5770 if (pitch >= 1.f) {
5771 maxpitch = 1.f + (fdelaylen/sdur);
5772 pitch = sc_min(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 - sdur * dsamp_slope;
5781 dsamp = sc_min(dsamp, fdelaylen);
5782 } else {
5783 maxpitch = -(1.f + (fdelaylen/sdur));
5784 pitch = sc_max(pitch, maxpitch);
5786 dsamp_slope = 1.f - pitch;
5787 grain->rate = dsamp_slope;
5789 maxtimedisp = fdelaylen - sdur * dsamp_slope;
5790 timedisp = sc_min(timedisp, maxtimedisp);
5792 dsamp = BUFLENGTH + koffset + 2.f + timedisp;
5793 dsamp = sc_min(dsamp, fdelaylen);
5796 grain->pos = dsamp;
5797 //postbuf("ds %g %g %g\n", dsamp_slope, dsamp, fdelaylen);
5799 rdur = 1.f / sdur;
5800 rdur2 = rdur * rdur;
5801 grain->level = level = 0.f;
5802 grain->slope = slope = 4.0 * (rdur - rdur2); // ampslope
5803 grain->curve = curve = -8.0 * rdur2; // ampcurve
5805 nsmps = remain;
5806 out = out0 + koffset;
5807 LOOP(nsmps,
5808 dsamp += dsamp_slope;
5809 idsamp = (long)dsamp;
5810 frac = dsamp - idsamp;
5811 iwrphase = (iwrphase + 1) & mask;
5812 irdphase = (iwrphase - idsamp) & mask;
5813 irdphaseb = (irdphase - 1) & mask;
5814 d1 = dlybuf[irdphase];
5815 d2 = dlybuf[irdphaseb];
5816 ZXP(out) += (d1 + frac * (d2 - d1)) * level;
5817 level += slope;
5818 slope += curve;
5820 grain->pos = dsamp;
5821 grain->level = level;
5822 grain->slope = slope;
5823 grain->counter -= nsmps;
5825 if (grain->counter <= 0) {
5826 // unlink from active list
5827 unit->firstActive = grain->next;
5829 // link onto free list
5830 grain->next = unit->firstFree;
5831 unit->firstFree = grain;
5834 unit->nextTime = (long)(sdur / density);
5835 if (unit->nextTime < 1) unit->nextTime = 1;
5837 /*if (grain == NULL) {
5838 postbuf("nextTime %d %g %g %p %p %p\n", unit->nextTime, sdur, density,
5839 grain, unit->firstActive, unit->firstFree);
5842 iwrphase = (iwrphase0 + BUFLENGTH) & mask;
5843 unit->nextTime -= remain;
5844 if (unit->nextTime < 0) unit->nextTime = 0;
5846 unit->iwrphase = iwrphase;
5848 RPUT
5852 void GrainTap_Ctor(GrainTap *unit);
5853 void GrainTap_Ctor(GrainTap *unit)
5855 float fdelaylen;
5856 float maxdelaytime;
5858 GET_BUF
5860 if (!ISPOWEROFTWO(bufSamples)) {
5861 Print("GrainTap buffer size not a power of two.\n");
5862 SETCALC(*ClearUnitOutputs);
5863 return;
5866 fdelaylen = bufSamples - 2 * BUFLENGTH - 3;
5867 maxdelaytime = fdelaylen * SAMPLEDUR;
5869 SETCALC(GrainTap_next);
5871 ZOUT0(0) = 0.f;
5873 unit->bufsize = bufSamples;
5874 unit->fdelaylen = fdelaylen;
5875 unit->iwrphase = 0;
5876 unit->nextTime = 0;
5877 for (int i=0; i<MAXDGRAINS-1; ++i) {
5878 unit->grains[i].next = unit->grains + (i + 1);
5880 unit->grains[MAXDGRAINS-1].next = NULL;
5881 unit->firstFree = unit->grains;
5882 unit->firstActive = NULL;
5888 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5891 #define GRAIN_BUF \
5892 const SndBuf *buf = bufs + bufnum; \
5893 LOCK_SNDBUF_SHARED(buf); \
5894 const float *bufData __attribute__((__unused__)) = buf->data; \
5895 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
5896 uint32 bufSamples __attribute__((__unused__)) = buf->samples; \
5897 uint32 bufFrames = buf->frames; \
5898 int guardFrame __attribute__((__unused__)) = bufFrames - 2; \
5901 inline float IN_AT(Unit* unit, int index, int offset)
5903 if (INRATE(index) == calc_FullRate) return IN(index)[offset];
5904 if (INRATE(index) == calc_DemandRate) return DEMANDINPUT_A(index, offset + 1);
5905 return ZIN0(index);
5908 inline double sc_gloop(double in, double hi)
5910 // avoid the divide if possible
5911 if (in >= hi) {
5912 in -= hi;
5913 if (in < hi) return in;
5914 } else if (in < 0.) {
5915 in += hi;
5916 if (in >= 0.) return in;
5917 } else return in;
5919 return in - hi * floor(in/hi);
5922 #define GRAIN_LOOP_BODY_4 \
5923 float amp = y1 * y1; \
5924 phase = sc_gloop(phase, loopMax); \
5925 int32 iphase = (int32)phase; \
5926 const float* table1 = bufData + iphase; \
5927 const float* table0 = table1 - 1; \
5928 const float* table2 = table1 + 1; \
5929 const float* table3 = table1 + 2; \
5930 if (iphase == 0) { \
5931 table0 += bufSamples; \
5932 } else if (iphase >= guardFrame) { \
5933 if (iphase == guardFrame) { \
5934 table3 -= bufSamples; \
5935 } else { \
5936 table2 -= bufSamples; \
5937 table3 -= bufSamples; \
5940 float fracphase = phase - (double)iphase; \
5941 float a = table0[0]; \
5942 float b = table1[0]; \
5943 float c = table2[0]; \
5944 float d = table3[0]; \
5945 float outval = amp * cubicinterp(fracphase, a, b, c, d); \
5946 ZXP(out1) += outval * pan1; \
5947 ZXP(out2) += outval * pan2; \
5948 double y0 = b1 * y1 - y2; \
5949 y2 = y1; \
5950 y1 = y0; \
5953 #define GRAIN_LOOP_BODY_2 \
5954 float amp = y1 * y1; \
5955 phase = sc_gloop(phase, loopMax); \
5956 int32 iphase = (int32)phase; \
5957 const float* table1 = bufData + iphase; \
5958 const float* table2 = table1 + 1; \
5959 if (iphase > guardFrame) { \
5960 table2 -= bufSamples; \
5962 float fracphase = phase - (double)iphase; \
5963 float b = table1[0]; \
5964 float c = table2[0]; \
5965 float outval = amp * (b + fracphase * (c - b)); \
5966 ZXP(out1) += outval * pan1; \
5967 ZXP(out2) += outval * pan2; \
5968 double y0 = b1 * y1 - y2; \
5969 y2 = y1; \
5970 y1 = y0; \
5973 #define GRAIN_LOOP_BODY_1 \
5974 float amp = y1 * y1; \
5975 phase = sc_gloop(phase, loopMax); \
5976 int32 iphase = (int32)phase; \
5977 float outval = amp * bufData[iphase]; \
5978 ZXP(out1) += outval * pan1; \
5979 ZXP(out2) += outval * pan2; \
5980 double y0 = b1 * y1 - y2; \
5981 y2 = y1; \
5982 y1 = y0; \
5985 void TGrains_next(TGrains *unit, int inNumSamples)
5987 float *trigin = IN(0);
5988 float prevtrig = unit->mPrevTrig;
5990 uint32 numOutputs = unit->mNumOutputs;
5991 ClearUnitOutputs(unit, inNumSamples);
5992 float *out[16];
5993 for (uint32 i=0; i<numOutputs; ++i) out[i] = ZOUT(i);
5995 World *world = unit->mWorld;
5996 SndBuf *bufs = world->mSndBufs;
5997 uint32 numBufs = world->mNumSndBufs;
5999 for (int i=0; i < unit->mNumActive; ) {
6000 Grain *grain = unit->mGrains + i;
6001 uint32 bufnum = grain->bufnum;
6003 GRAIN_BUF
6005 if (bufChannels != 1) {
6006 ++i;
6007 continue;
6010 double loopMax = (double)bufFrames;
6012 float pan1 = grain->pan1;
6013 float pan2 = grain->pan2;
6014 double rate = grain->rate;
6015 double phase = grain->phase;
6016 double b1 = grain->b1;
6017 double y1 = grain->y1;
6018 double y2 = grain->y2;
6020 uint32 chan1 = grain->chan;
6021 uint32 chan2 = chan1 + 1;
6022 if (chan2 >= numOutputs) chan2 = 0;
6024 float *out1 = out[chan1];
6025 float *out2 = out[chan2];
6026 //printf("B chan %d %d %p %p", chan1, chan2, out1, out2);
6028 int nsmps = sc_min(grain->counter, inNumSamples);
6029 if (grain->interp >= 4) {
6030 for (int j=0; j<nsmps; ++j) {
6031 GRAIN_LOOP_BODY_4;
6032 phase += rate;
6034 } else if (grain->interp >= 2) {
6035 for (int j=0; j<nsmps; ++j) {
6036 GRAIN_LOOP_BODY_2;
6037 phase += rate;
6039 } else {
6040 for (int j=0; j<nsmps; ++j) {
6041 GRAIN_LOOP_BODY_1;
6042 phase += rate;
6046 grain->phase = phase;
6047 grain->y1 = y1;
6048 grain->y2 = y2;
6050 grain->counter -= nsmps;
6051 if (grain->counter <= 0) {
6052 // remove grain
6053 *grain = unit->mGrains[--unit->mNumActive];
6054 } else ++i;
6057 int trigSamples = INRATE(0) == calc_FullRate ? inNumSamples : 1;
6059 for (int i=0; i<trigSamples; ++i) {
6060 float trig = trigin[i];
6062 if (trig > 0.f && prevtrig <= 0.f) {
6063 // start a grain
6064 if (unit->mNumActive+1 >= kMaxGrains) break;
6065 uint32 bufnum = (uint32)IN_AT(unit, 1, i);
6066 if (bufnum >= numBufs) continue;
6067 GRAIN_BUF
6069 if (bufChannels != 1) continue;
6071 float bufSampleRate = buf->samplerate;
6072 float bufRateScale = bufSampleRate * SAMPLEDUR;
6073 double loopMax = (double)bufFrames;
6075 Grain *grain = unit->mGrains + unit->mNumActive++;
6076 grain->bufnum = bufnum;
6078 double counter = floor(IN_AT(unit, 4, i) * SAMPLERATE);
6079 counter = sc_max(4., counter);
6080 grain->counter = (int)counter;
6082 double rate = grain->rate = IN_AT(unit, 2, i) * bufRateScale;
6083 double centerPhase = IN_AT(unit, 3, i) * bufSampleRate;
6084 double phase = centerPhase - 0.5 * counter * rate;
6086 float pan = IN_AT(unit, 5, i);
6087 float amp = IN_AT(unit, 6, i);
6088 grain->interp = (int)IN_AT(unit, 7, i);
6090 float panangle;
6091 if (numOutputs > 2) {
6092 pan = sc_wrap(pan * 0.5f, 0.f, 1.f);
6093 float cpan = numOutputs * pan + 0.5;
6094 float ipan = floor(cpan);
6095 float panfrac = cpan - ipan;
6096 panangle = panfrac * pi2_f;
6097 grain->chan = (int)ipan;
6098 if (grain->chan >= (int)numOutputs) grain->chan -= numOutputs;
6099 } else {
6100 grain->chan = 0;
6101 pan = sc_wrap(pan * 0.5f + 0.5f, 0.f, 1.f);
6102 panangle = pan * pi2_f;
6104 float pan1 = grain->pan1 = amp * cos(panangle);
6105 float pan2 = grain->pan2 = amp * sin(panangle);
6106 double w = pi / counter;
6107 double b1 = grain->b1 = 2. * cos(w);
6108 double y1 = sin(w);
6109 double y2 = 0.;
6111 uint32 chan1 = grain->chan;
6112 uint32 chan2 = chan1 + 1;
6113 if (chan2 >= numOutputs) chan2 = 0;
6115 float *out1 = out[chan1] + i;
6116 float *out2 = out[chan2] + i;
6118 int nsmps = sc_min(grain->counter, inNumSamples - i);
6119 if (grain->interp >= 4) {
6120 for (int j=0; j<nsmps; ++j) {
6121 GRAIN_LOOP_BODY_4;
6122 phase += rate;
6124 } else if (grain->interp >= 2) {
6125 for (int j=0; j<nsmps; ++j) {
6126 GRAIN_LOOP_BODY_2;
6127 phase += rate;
6129 } else {
6130 for (int j=0; j<nsmps; ++j) {
6131 GRAIN_LOOP_BODY_1;
6132 phase += rate;
6136 grain->phase = phase;
6137 grain->y1 = y1;
6138 grain->y2 = y2;
6140 grain->counter -= nsmps;
6141 if (grain->counter <= 0) {
6142 // remove grain
6143 *grain = unit->mGrains[--unit->mNumActive];
6146 prevtrig = trig;
6149 unit->mPrevTrig = prevtrig;
6152 void TGrains_Ctor(TGrains *unit)
6154 SETCALC(TGrains_next);
6156 unit->mNumActive = 0;
6157 unit->mPrevTrig = 0.;
6159 ClearUnitOutputs(unit, 1);
6163 ////////////////////////////////////////////////////////////////////////////////////////////////////////
6165 Pluck - Karplus-Strong
6167 void Pluck_Ctor(Pluck *unit)
6169 // FeedbackDelay_Reset(unit);
6170 float maxdelaytime = unit->m_maxdelaytime = IN0(2);
6171 float delaytime = unit->m_delaytime = IN0(3);
6172 unit->m_dlybuf = 0;
6173 bool allocationSucessful = DelayUnit_AllocDelayLine(unit, "Pluck");
6174 if (!allocationSucessful)
6175 return;
6177 unit->m_dsamp = CalcDelay(unit, unit->m_delaytime);
6179 unit->m_numoutput = 0;
6180 unit->m_iwrphase = 0;
6181 unit->m_feedbk = sc_CalcFeedback(unit->m_delaytime, unit->m_decaytime);
6183 if (INRATE(1) == calc_FullRate) {
6184 if(INRATE(5) == calc_FullRate){
6185 SETCALC(Pluck_next_aa_z);
6186 } else {
6187 SETCALC(Pluck_next_ak_z); //ak
6189 } else {
6190 if(INRATE(5) == calc_FullRate){
6191 SETCALC(Pluck_next_ka_z); //ka
6192 } else {
6193 SETCALC(Pluck_next_kk_z); //kk
6196 OUT0(0) = unit->m_lastsamp = 0.f;
6197 unit->m_prevtrig = 0.f;
6198 unit->m_inputsamps = 0;
6199 unit->m_coef = IN0(5);
6202 void Pluck_next_aa(Pluck *unit, int inNumSamples)
6204 float *out = OUT(0);
6205 float *in = IN(0);
6206 float *trig = IN(1);
6207 float delaytime = IN0(3);
6208 float decaytime = IN0(4);
6209 float *coef = IN(5);
6210 float lastsamp = unit->m_lastsamp;
6211 unsigned long inputsamps = unit->m_inputsamps;
6213 float *dlybuf = unit->m_dlybuf;
6214 long iwrphase = unit->m_iwrphase;
6215 float dsamp = unit->m_dsamp;
6216 float feedbk = unit->m_feedbk;
6217 long mask = unit->m_mask;
6218 float thisin, curtrig;
6219 float prevtrig = unit->m_prevtrig;
6221 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6222 long idsamp = (long)dsamp;
6223 float frac = dsamp - idsamp;
6224 for(int i = 0; i < inNumSamples; i++){
6225 curtrig = trig[i];
6226 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6227 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6229 prevtrig = curtrig;
6230 long irdphase1 = iwrphase - idsamp;
6231 long irdphase2 = irdphase1 - 1;
6232 long irdphase3 = irdphase1 - 2;
6233 long irdphase0 = irdphase1 + 1;
6234 if (inputsamps > 0) {
6235 thisin = in[i];
6236 --inputsamps;
6237 } else {
6238 thisin = 0.f;
6240 float d0 = dlybuf[irdphase0 & mask];
6241 float d1 = dlybuf[irdphase1 & mask];
6242 float d2 = dlybuf[irdphase2 & mask];
6243 float d3 = dlybuf[irdphase3 & mask];
6244 float value = cubicinterp(frac, d0, d1, d2, d3);
6245 float thiscoef = coef[i];
6246 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6247 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6248 out[i] = lastsamp = onepole;
6249 iwrphase++;
6251 } else {
6253 float next_dsamp = CalcDelay(unit, delaytime);
6254 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6256 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6257 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6259 for(int i = 0; i < inNumSamples; i++){
6260 curtrig = trig[i];
6261 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6262 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6264 prevtrig = curtrig;
6265 dsamp += dsamp_slope;
6266 long idsamp = (long)dsamp;
6267 float frac = dsamp - idsamp;
6268 long irdphase1 = iwrphase - idsamp;
6269 long irdphase2 = irdphase1 - 1;
6270 long irdphase3 = irdphase1 - 2;
6271 long irdphase0 = irdphase1 + 1;
6272 if (inputsamps > 0) {
6273 thisin = in[i];
6274 --inputsamps;
6275 } else {
6276 thisin = 0.f;
6278 float d0 = dlybuf[irdphase0 & mask];
6279 float d1 = dlybuf[irdphase1 & mask];
6280 float d2 = dlybuf[irdphase2 & mask];
6281 float d3 = dlybuf[irdphase3 & mask];
6282 float value = cubicinterp(frac, d0, d1, d2, d3);
6283 float thiscoef = coef[i];
6284 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6285 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6286 out[i] = lastsamp = onepole;
6287 feedbk += feedbk_slope;
6288 iwrphase++;
6290 unit->m_feedbk = feedbk;
6291 unit->m_dsamp = dsamp;
6292 unit->m_delaytime = delaytime;
6293 unit->m_decaytime = decaytime;
6296 unit->m_prevtrig = prevtrig;
6297 unit->m_inputsamps = inputsamps;
6298 unit->m_lastsamp = zapgremlins(lastsamp);
6299 unit->m_iwrphase = iwrphase;
6304 void Pluck_next_aa_z(Pluck *unit, int inNumSamples)
6306 float *out = OUT(0);
6307 float *in = IN(0);
6308 float *trig = IN(1);
6309 float delaytime = IN0(3);
6310 float decaytime = IN0(4);
6311 float *coef = IN(5);
6312 float lastsamp = unit->m_lastsamp;
6314 float *dlybuf = unit->m_dlybuf;
6315 long iwrphase = unit->m_iwrphase;
6316 float dsamp = unit->m_dsamp;
6317 float feedbk = unit->m_feedbk;
6318 long mask = unit->m_mask;
6319 float d0, d1, d2, d3;
6320 float thisin, curtrig;
6321 unsigned long inputsamps = unit->m_inputsamps;
6322 float prevtrig = unit->m_prevtrig;
6324 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6325 long idsamp = (long)dsamp;
6326 float frac = dsamp - idsamp;
6327 for(int i = 0; i < inNumSamples; i++){
6328 curtrig = trig[i];
6329 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6330 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6332 prevtrig = curtrig;
6333 long irdphase1 = iwrphase - idsamp;
6334 long irdphase2 = irdphase1 - 1;
6335 long irdphase3 = irdphase1 - 2;
6336 long irdphase0 = irdphase1 + 1;
6337 if (inputsamps > 0) {
6338 thisin = in[i];
6339 --inputsamps;
6340 } else {
6341 thisin = 0.f;
6343 if (irdphase0 < 0) {
6344 dlybuf[iwrphase & mask] = thisin;
6345 out[i] = 0.f;
6346 } else {
6347 if (irdphase1 < 0) {
6348 d1 = d2 = d3 = 0.f;
6349 d0 = dlybuf[irdphase0 & mask];
6350 } else if (irdphase2 < 0) {
6351 d1 = d2 = d3 = 0.f;
6352 d0 = dlybuf[irdphase0 & mask];
6353 d1 = dlybuf[irdphase1 & mask];
6354 } else if (irdphase3 < 0) {
6355 d3 = 0.f;
6356 d0 = dlybuf[irdphase0 & mask];
6357 d1 = dlybuf[irdphase1 & mask];
6358 d2 = dlybuf[irdphase2 & mask];
6359 } else {
6360 d0 = dlybuf[irdphase0 & mask];
6361 d1 = dlybuf[irdphase1 & mask];
6362 d2 = dlybuf[irdphase2 & mask];
6363 d3 = dlybuf[irdphase3 & mask];
6365 float value = cubicinterp(frac, d0, d1, d2, d3);
6366 float thiscoef = coef[i];
6367 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6368 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6369 out[i] = lastsamp = onepole;
6371 iwrphase++;
6373 } else {
6375 float next_dsamp = CalcDelay(unit, delaytime);
6376 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6378 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6379 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6381 for(int i = 0; i < inNumSamples; i++) {
6382 curtrig = trig[i];
6383 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6384 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6386 prevtrig = curtrig;
6387 dsamp += dsamp_slope;
6388 long idsamp = (long)dsamp;
6389 float frac = dsamp - idsamp;
6390 long irdphase1 = iwrphase - idsamp;
6391 long irdphase2 = irdphase1 - 1;
6392 long irdphase3 = irdphase1 - 2;
6393 long irdphase0 = irdphase1 + 1;
6394 if (inputsamps > 0) {
6395 thisin = in[i];
6396 --inputsamps;
6397 } else {
6398 thisin = 0.f;
6400 if (irdphase0 < 0) {
6401 dlybuf[iwrphase & mask] = thisin;
6402 out[i] = 0.f;
6403 } else {
6404 if (irdphase1 < 0) {
6405 d1 = d2 = d3 = 0.f;
6406 d0 = dlybuf[irdphase0 & mask];
6407 } else if (irdphase2 < 0) {
6408 d1 = d2 = d3 = 0.f;
6409 d0 = dlybuf[irdphase0 & mask];
6410 d1 = dlybuf[irdphase1 & mask];
6411 } else if (irdphase3 < 0) {
6412 d3 = 0.f;
6413 d0 = dlybuf[irdphase0 & mask];
6414 d1 = dlybuf[irdphase1 & mask];
6415 d2 = dlybuf[irdphase2 & mask];
6416 } else {
6417 d0 = dlybuf[irdphase0 & mask];
6418 d1 = dlybuf[irdphase1 & mask];
6419 d2 = dlybuf[irdphase2 & mask];
6420 d3 = dlybuf[irdphase3 & mask];
6422 float value = cubicinterp(frac, d0, d1, d2, d3);
6423 float thiscoef = coef[i];
6424 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6425 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6426 out[i] = lastsamp = onepole;
6428 feedbk += feedbk_slope;
6429 iwrphase++;
6431 unit->m_feedbk = feedbk;
6432 unit->m_dsamp = dsamp;
6433 unit->m_delaytime = delaytime;
6434 unit->m_decaytime = decaytime;
6437 unit->m_inputsamps = inputsamps;
6438 unit->m_prevtrig = prevtrig;
6439 unit->m_lastsamp = zapgremlins(lastsamp);
6440 unit->m_iwrphase = iwrphase;
6442 unit->m_numoutput += inNumSamples;
6443 if (unit->m_numoutput >= unit->m_idelaylen) {
6444 SETCALC(Pluck_next_aa);
6448 void Pluck_next_kk(Pluck *unit, int inNumSamples)
6450 float *out = OUT(0);
6451 float *in = IN(0);
6452 float trig = IN0(1);
6453 float delaytime = IN0(3);
6454 float decaytime = IN0(4);
6455 float coef = IN0(5);
6456 float lastsamp = unit->m_lastsamp;
6457 unsigned long inputsamps = unit->m_inputsamps;
6459 float *dlybuf = unit->m_dlybuf;
6460 long iwrphase = unit->m_iwrphase;
6461 float dsamp = unit->m_dsamp;
6462 float feedbk = unit->m_feedbk;
6463 long mask = unit->m_mask;
6464 float thisin;
6466 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6467 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6469 unit->m_prevtrig = trig;
6471 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6472 long idsamp = (long)dsamp;
6473 float frac = dsamp - idsamp;
6475 for(int i = 0; i < inNumSamples; i++){
6476 long irdphase1 = iwrphase - idsamp;
6477 long irdphase2 = irdphase1 - 1;
6478 long irdphase3 = irdphase1 - 2;
6479 long irdphase0 = irdphase1 + 1;
6480 if (inputsamps > 0) {
6481 thisin = in[i];
6482 --inputsamps;
6483 } else {
6484 thisin = 0.f;
6486 float d0 = dlybuf[irdphase0 & mask];
6487 float d1 = dlybuf[irdphase1 & mask];
6488 float d2 = dlybuf[irdphase2 & mask];
6489 float d3 = dlybuf[irdphase3 & mask];
6490 float value = cubicinterp(frac, d0, d1, d2, d3);
6491 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6492 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6493 out[i] = lastsamp = onepole; //value;
6494 iwrphase++;
6496 } else {
6498 float next_dsamp = CalcDelay(unit, delaytime);
6499 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6501 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6502 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6504 float curcoef = unit->m_coef;
6505 float coef_slope = CALCSLOPE(coef, curcoef);
6507 for(int i = 0; i < inNumSamples; i++){
6508 dsamp += dsamp_slope;
6509 long idsamp = (long)dsamp;
6510 float frac = dsamp - idsamp;
6511 long irdphase1 = iwrphase - idsamp;
6512 long irdphase2 = irdphase1 - 1;
6513 long irdphase3 = irdphase1 - 2;
6514 long irdphase0 = irdphase1 + 1;
6515 if (inputsamps > 0) {
6516 thisin = in[i];
6517 --inputsamps;
6518 } else {
6519 thisin = 0.f;
6521 float d0 = dlybuf[irdphase0 & mask];
6522 float d1 = dlybuf[irdphase1 & mask];
6523 float d2 = dlybuf[irdphase2 & mask];
6524 float d3 = dlybuf[irdphase3 & mask];
6525 float value = cubicinterp(frac, d0, d1, d2, d3);
6526 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6527 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6528 out[i] = lastsamp = onepole; //value;
6529 feedbk += feedbk_slope;
6530 curcoef += coef_slope;
6531 iwrphase++;
6533 unit->m_feedbk = feedbk;
6534 unit->m_coef = coef;
6535 unit->m_dsamp = dsamp;
6536 unit->m_delaytime = delaytime;
6537 unit->m_decaytime = decaytime;
6540 unit->m_inputsamps = inputsamps;
6541 unit->m_lastsamp = zapgremlins(lastsamp);
6542 unit->m_iwrphase = iwrphase;
6547 void Pluck_next_kk_z(Pluck *unit, int inNumSamples)
6549 float *out = OUT(0);
6550 float *in = IN(0);
6551 float trig = IN0(1);
6552 float delaytime = IN0(3);
6553 float decaytime = IN0(4);
6554 float coef = IN0(5);
6555 float lastsamp = unit->m_lastsamp;
6557 float *dlybuf = unit->m_dlybuf;
6558 long iwrphase = unit->m_iwrphase;
6559 float dsamp = unit->m_dsamp;
6560 float feedbk = unit->m_feedbk;
6561 long mask = unit->m_mask;
6562 float d0, d1, d2, d3;
6563 float thisin;
6564 unsigned long inputsamps = unit->m_inputsamps;
6566 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6567 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6569 unit->m_prevtrig = trig;
6571 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6572 long idsamp = (long)dsamp;
6573 float frac = dsamp - idsamp;
6574 for(int i = 0; i < inNumSamples; i++){
6576 long irdphase1 = iwrphase - idsamp;
6577 long irdphase2 = irdphase1 - 1;
6578 long irdphase3 = irdphase1 - 2;
6579 long irdphase0 = irdphase1 + 1;
6580 if (inputsamps > 0) {
6581 thisin = in[i];
6582 --inputsamps;
6583 } else {
6584 thisin = 0.f;
6586 if (irdphase0 < 0) {
6587 dlybuf[iwrphase & mask] = thisin;
6588 out[i] = 0.f;
6589 } else {
6590 if (irdphase1 < 0) {
6591 d1 = d2 = d3 = 0.f;
6592 d0 = dlybuf[irdphase0 & mask];
6593 } else if (irdphase2 < 0) {
6594 d1 = d2 = d3 = 0.f;
6595 d0 = dlybuf[irdphase0 & mask];
6596 d1 = dlybuf[irdphase1 & mask];
6597 } else if (irdphase3 < 0) {
6598 d3 = 0.f;
6599 d0 = dlybuf[irdphase0 & mask];
6600 d1 = dlybuf[irdphase1 & mask];
6601 d2 = dlybuf[irdphase2 & mask];
6602 } else {
6603 d0 = dlybuf[irdphase0 & mask];
6604 d1 = dlybuf[irdphase1 & mask];
6605 d2 = dlybuf[irdphase2 & mask];
6606 d3 = dlybuf[irdphase3 & mask];
6608 float value = cubicinterp(frac, d0, d1, d2, d3);
6609 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6610 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6611 out[i] = lastsamp = onepole; //value;
6613 iwrphase++;
6615 } else {
6617 float next_dsamp = CalcDelay(unit, delaytime);
6618 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6620 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6621 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6623 float curcoef = unit->m_coef;
6624 float coef_slope = CALCSLOPE(coef, curcoef);
6626 for(int i = 0; i < inNumSamples; i++) {
6627 dsamp += dsamp_slope;
6628 long idsamp = (long)dsamp;
6629 float frac = dsamp - idsamp;
6630 long irdphase1 = iwrphase - idsamp;
6631 long irdphase2 = irdphase1 - 1;
6632 long irdphase3 = irdphase1 - 2;
6633 long irdphase0 = irdphase1 + 1;
6634 if (inputsamps > 0) {
6635 thisin = in[i];
6636 --inputsamps;
6637 } else {
6638 thisin = 0.f;
6640 if (irdphase0 < 0) {
6641 dlybuf[iwrphase & mask] = thisin;
6642 out[i] = 0.f;
6643 } else {
6644 if (irdphase1 < 0) {
6645 d1 = d2 = d3 = 0.f;
6646 d0 = dlybuf[irdphase0 & mask];
6647 } else if (irdphase2 < 0) {
6648 d1 = d2 = d3 = 0.f;
6649 d0 = dlybuf[irdphase0 & mask];
6650 d1 = dlybuf[irdphase1 & mask];
6651 } else if (irdphase3 < 0) {
6652 d3 = 0.f;
6653 d0 = dlybuf[irdphase0 & mask];
6654 d1 = dlybuf[irdphase1 & mask];
6655 d2 = dlybuf[irdphase2 & mask];
6656 } else {
6657 d0 = dlybuf[irdphase0 & mask];
6658 d1 = dlybuf[irdphase1 & mask];
6659 d2 = dlybuf[irdphase2 & mask];
6660 d3 = dlybuf[irdphase3 & mask];
6662 float value = cubicinterp(frac, d0, d1, d2, d3);
6663 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6664 dlybuf[iwrphase & mask] = thisin + (feedbk * onepole);
6665 out[i] = lastsamp = onepole; //value;
6667 feedbk += feedbk_slope;
6668 curcoef += coef_slope;
6669 iwrphase++;
6671 unit->m_feedbk = feedbk;
6672 unit->m_dsamp = dsamp;
6673 unit->m_delaytime = delaytime;
6674 unit->m_decaytime = decaytime;
6675 unit->m_coef = coef;
6678 unit->m_inputsamps = inputsamps;
6679 unit->m_lastsamp = zapgremlins(lastsamp);
6680 unit->m_iwrphase = iwrphase;
6682 unit->m_numoutput += inNumSamples;
6683 if (unit->m_numoutput >= unit->m_idelaylen) {
6684 SETCALC(Pluck_next_kk);
6688 void Pluck_next_ak(Pluck *unit, int inNumSamples)
6690 float *out = OUT(0);
6691 float *in = IN(0);
6692 float *trig = IN(1);
6693 float delaytime = IN0(3);
6694 float decaytime = IN0(4);
6695 float coef = IN0(5);
6696 float lastsamp = unit->m_lastsamp;
6697 unsigned long inputsamps = unit->m_inputsamps;
6699 float *dlybuf = unit->m_dlybuf;
6700 long iwrphase = unit->m_iwrphase;
6701 float dsamp = unit->m_dsamp;
6702 float feedbk = unit->m_feedbk;
6703 long mask = unit->m_mask;
6704 float thisin, curtrig;
6705 float prevtrig = unit->m_prevtrig;
6707 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6708 long idsamp = (long)dsamp;
6709 float frac = dsamp - idsamp;
6710 for(int i = 0; i < inNumSamples; i++){
6711 curtrig = trig[i];
6712 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6713 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6715 prevtrig = curtrig;
6716 long irdphase1 = iwrphase - idsamp;
6717 long irdphase2 = irdphase1 - 1;
6718 long irdphase3 = irdphase1 - 2;
6719 long irdphase0 = irdphase1 + 1;
6720 if (inputsamps > 0) {
6721 thisin = in[i];
6722 --inputsamps;
6723 } else {
6724 thisin = 0.f;
6726 float d0 = dlybuf[irdphase0 & mask];
6727 float d1 = dlybuf[irdphase1 & mask];
6728 float d2 = dlybuf[irdphase2 & mask];
6729 float d3 = dlybuf[irdphase3 & mask];
6730 float value = cubicinterp(frac, d0, d1, d2, d3);
6731 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6732 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6733 out[i] = lastsamp = onepole;
6734 iwrphase++;
6736 } else {
6738 float next_dsamp = CalcDelay(unit, delaytime);
6739 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6741 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6742 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6744 float curcoef = unit->m_coef;
6745 float coef_slope = CALCSLOPE(coef, curcoef);
6747 for(int i = 0; i < inNumSamples; i++){
6748 curtrig = trig[i];
6749 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6750 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6752 prevtrig = curtrig;
6753 dsamp += dsamp_slope;
6754 long idsamp = (long)dsamp;
6755 float frac = dsamp - idsamp;
6756 long irdphase1 = iwrphase - idsamp;
6757 long irdphase2 = irdphase1 - 1;
6758 long irdphase3 = irdphase1 - 2;
6759 long irdphase0 = irdphase1 + 1;
6760 if (inputsamps > 0) {
6761 thisin = in[i];
6762 --inputsamps;
6763 } else {
6764 thisin = 0.f;
6766 float d0 = dlybuf[irdphase0 & mask];
6767 float d1 = dlybuf[irdphase1 & mask];
6768 float d2 = dlybuf[irdphase2 & mask];
6769 float d3 = dlybuf[irdphase3 & mask];
6770 float value = cubicinterp(frac, d0, d1, d2, d3);
6771 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6772 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6773 out[i] = lastsamp = onepole;
6774 feedbk += feedbk_slope;
6775 curcoef += coef_slope;
6776 iwrphase++;
6778 unit->m_feedbk = feedbk;
6779 unit->m_dsamp = dsamp;
6780 unit->m_delaytime = delaytime;
6781 unit->m_decaytime = decaytime;
6782 unit->m_coef = coef;
6785 unit->m_prevtrig = prevtrig;
6786 unit->m_inputsamps = inputsamps;
6787 unit->m_lastsamp = zapgremlins(lastsamp);
6788 unit->m_iwrphase = iwrphase;
6793 void Pluck_next_ak_z(Pluck *unit, int inNumSamples)
6795 float *out = OUT(0);
6796 float *in = IN(0);
6797 float *trig = IN(1);
6798 float delaytime = IN0(3);
6799 float decaytime = IN0(4);
6800 float coef = IN0(5);
6801 float lastsamp = unit->m_lastsamp;
6803 float *dlybuf = unit->m_dlybuf;
6804 long iwrphase = unit->m_iwrphase;
6805 float dsamp = unit->m_dsamp;
6806 float feedbk = unit->m_feedbk;
6807 long mask = unit->m_mask;
6808 float d0, d1, d2, d3;
6809 float thisin, curtrig;
6810 unsigned long inputsamps = unit->m_inputsamps;
6811 float prevtrig = unit->m_prevtrig;
6813 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime && coef == unit->m_coef) {
6814 long idsamp = (long)dsamp;
6815 float frac = dsamp - idsamp;
6816 for(int i = 0; i < inNumSamples; i++){
6817 curtrig = trig[i];
6818 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6819 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6821 prevtrig = curtrig;
6822 long irdphase1 = iwrphase - idsamp;
6823 long irdphase2 = irdphase1 - 1;
6824 long irdphase3 = irdphase1 - 2;
6825 long irdphase0 = irdphase1 + 1;
6826 if (inputsamps > 0) {
6827 thisin = in[i];
6828 --inputsamps;
6829 } else {
6830 thisin = 0.f;
6832 if (irdphase0 < 0) {
6833 dlybuf[iwrphase & mask] = thisin;
6834 out[i] = 0.f;
6835 } else {
6836 if (irdphase1 < 0) {
6837 d1 = d2 = d3 = 0.f;
6838 d0 = dlybuf[irdphase0 & mask];
6839 } else if (irdphase2 < 0) {
6840 d1 = d2 = d3 = 0.f;
6841 d0 = dlybuf[irdphase0 & mask];
6842 d1 = dlybuf[irdphase1 & mask];
6843 } else if (irdphase3 < 0) {
6844 d3 = 0.f;
6845 d0 = dlybuf[irdphase0 & mask];
6846 d1 = dlybuf[irdphase1 & mask];
6847 d2 = dlybuf[irdphase2 & mask];
6848 } else {
6849 d0 = dlybuf[irdphase0 & mask];
6850 d1 = dlybuf[irdphase1 & mask];
6851 d2 = dlybuf[irdphase2 & mask];
6852 d3 = dlybuf[irdphase3 & mask];
6854 float value = cubicinterp(frac, d0, d1, d2, d3);
6855 float onepole = ((1. - fabs(coef)) * value) + (coef * lastsamp);
6856 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6857 out[i] = lastsamp = onepole;
6859 iwrphase++;
6861 } else {
6863 float next_dsamp = CalcDelay(unit, delaytime);
6864 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6866 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6867 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6869 float curcoef = unit->m_coef;
6870 float coef_slope = CALCSLOPE(coef, curcoef);
6872 for(int i = 0; i < inNumSamples; i++) {
6873 curtrig = trig[i];
6874 if ((prevtrig <= 0.f) && (curtrig > 0.f)) {
6875 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6877 prevtrig = curtrig;
6878 dsamp += dsamp_slope;
6879 long idsamp = (long)dsamp;
6880 float frac = dsamp - idsamp;
6881 long irdphase1 = iwrphase - idsamp;
6882 long irdphase2 = irdphase1 - 1;
6883 long irdphase3 = irdphase1 - 2;
6884 long irdphase0 = irdphase1 + 1;
6885 if (inputsamps > 0) {
6886 thisin = in[i];
6887 --inputsamps;
6888 } else {
6889 thisin = 0.f;
6891 if (irdphase0 < 0) {
6892 dlybuf[iwrphase & mask] = thisin;
6893 out[i] = 0.f;
6894 } else {
6895 if (irdphase1 < 0) {
6896 d1 = d2 = d3 = 0.f;
6897 d0 = dlybuf[irdphase0 & mask];
6898 } else if (irdphase2 < 0) {
6899 d1 = d2 = d3 = 0.f;
6900 d0 = dlybuf[irdphase0 & mask];
6901 d1 = dlybuf[irdphase1 & mask];
6902 } else if (irdphase3 < 0) {
6903 d3 = 0.f;
6904 d0 = dlybuf[irdphase0 & mask];
6905 d1 = dlybuf[irdphase1 & mask];
6906 d2 = dlybuf[irdphase2 & mask];
6907 } else {
6908 d0 = dlybuf[irdphase0 & mask];
6909 d1 = dlybuf[irdphase1 & mask];
6910 d2 = dlybuf[irdphase2 & mask];
6911 d3 = dlybuf[irdphase3 & mask];
6913 float value = cubicinterp(frac, d0, d1, d2, d3);
6914 float onepole = ((1. - fabs(curcoef)) * value) + (curcoef * lastsamp);
6915 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6916 out[i] = lastsamp = onepole;
6918 feedbk += feedbk_slope;
6919 curcoef +=coef_slope;
6920 iwrphase++;
6922 unit->m_feedbk = feedbk;
6923 unit->m_dsamp = dsamp;
6924 unit->m_delaytime = delaytime;
6925 unit->m_decaytime = decaytime;
6926 unit->m_coef = coef;
6929 unit->m_inputsamps = inputsamps;
6930 unit->m_prevtrig = prevtrig;
6931 unit->m_lastsamp = zapgremlins(lastsamp);
6932 unit->m_iwrphase = iwrphase;
6934 unit->m_numoutput += inNumSamples;
6935 if (unit->m_numoutput >= unit->m_idelaylen) {
6936 SETCALC(Pluck_next_ak);
6941 void Pluck_next_ka(Pluck *unit, int inNumSamples)
6943 float *out = OUT(0);
6944 float *in = IN(0);
6945 float trig = IN0(1);
6946 float delaytime = IN0(3);
6947 float decaytime = IN0(4);
6948 float *coef = IN(5);
6949 float lastsamp = unit->m_lastsamp;
6950 unsigned long inputsamps = unit->m_inputsamps;
6952 float *dlybuf = unit->m_dlybuf;
6953 long iwrphase = unit->m_iwrphase;
6954 float dsamp = unit->m_dsamp;
6955 float feedbk = unit->m_feedbk;
6956 long mask = unit->m_mask;
6957 float thisin;
6959 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
6960 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
6962 unit->m_prevtrig = trig;
6964 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
6965 long idsamp = (long)dsamp;
6966 float frac = dsamp - idsamp;
6967 for(int i = 0; i < inNumSamples; i++){
6968 long irdphase1 = iwrphase - idsamp;
6969 long irdphase2 = irdphase1 - 1;
6970 long irdphase3 = irdphase1 - 2;
6971 long irdphase0 = irdphase1 + 1;
6972 if (inputsamps > 0) {
6973 thisin = in[i];
6974 --inputsamps;
6975 } else {
6976 thisin = 0.f;
6978 float d0 = dlybuf[irdphase0 & mask];
6979 float d1 = dlybuf[irdphase1 & mask];
6980 float d2 = dlybuf[irdphase2 & mask];
6981 float d3 = dlybuf[irdphase3 & mask];
6982 float value = cubicinterp(frac, d0, d1, d2, d3);
6983 float thiscoef = coef[i];
6984 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
6985 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
6986 out[i] = lastsamp = onepole;
6987 iwrphase++;
6989 } else {
6991 float next_dsamp = CalcDelay(unit, delaytime);
6992 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
6994 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
6995 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
6997 for(int i = 0; i < inNumSamples; i++){
6998 dsamp += dsamp_slope;
6999 long idsamp = (long)dsamp;
7000 float frac = dsamp - idsamp;
7001 long irdphase1 = iwrphase - idsamp;
7002 long irdphase2 = irdphase1 - 1;
7003 long irdphase3 = irdphase1 - 2;
7004 long irdphase0 = irdphase1 + 1;
7005 if (inputsamps > 0) {
7006 thisin = in[i];
7007 --inputsamps;
7008 } else {
7009 thisin = 0.f;
7011 float d0 = dlybuf[irdphase0 & mask];
7012 float d1 = dlybuf[irdphase1 & mask];
7013 float d2 = dlybuf[irdphase2 & mask];
7014 float d3 = dlybuf[irdphase3 & mask];
7015 float value = cubicinterp(frac, d0, d1, d2, d3);
7016 float thiscoef = coef[i];
7017 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7018 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7019 out[i] = lastsamp = onepole;
7020 feedbk += feedbk_slope;
7021 iwrphase++;
7023 unit->m_feedbk = feedbk;
7024 unit->m_dsamp = dsamp;
7025 unit->m_delaytime = delaytime;
7026 unit->m_decaytime = decaytime;
7029 unit->m_inputsamps = inputsamps;
7030 unit->m_lastsamp = zapgremlins(lastsamp);
7031 unit->m_iwrphase = iwrphase;
7036 void Pluck_next_ka_z(Pluck *unit, int inNumSamples)
7038 float *out = OUT(0);
7039 float *in = IN(0);
7040 float trig = IN0(1);
7041 float delaytime = IN0(3);
7042 float decaytime = IN0(4);
7043 float *coef = IN(5);
7044 float lastsamp = unit->m_lastsamp;
7046 float *dlybuf = unit->m_dlybuf;
7047 long iwrphase = unit->m_iwrphase;
7048 float dsamp = unit->m_dsamp;
7049 float feedbk = unit->m_feedbk;
7050 long mask = unit->m_mask;
7051 float d0, d1, d2, d3;
7052 float thisin;
7053 unsigned long inputsamps = unit->m_inputsamps;
7055 if ((unit->m_prevtrig <= 0.f) && (trig > 0.f)) {
7056 inputsamps = (long)(delaytime * unit->mRate->mSampleRate + .5f);
7059 unit->m_prevtrig = trig;
7061 if (delaytime == unit->m_delaytime && decaytime == unit->m_decaytime) {
7062 long idsamp = (long)dsamp;
7063 float frac = dsamp - idsamp;
7064 for(int i = 0; i < inNumSamples; i++){
7065 long irdphase1 = iwrphase - idsamp;
7066 long irdphase2 = irdphase1 - 1;
7067 long irdphase3 = irdphase1 - 2;
7068 long irdphase0 = irdphase1 + 1;
7069 if (inputsamps > 0) {
7070 thisin = in[i];
7071 --inputsamps;
7072 } else {
7073 thisin = 0.f;
7075 if (irdphase0 < 0) {
7076 dlybuf[iwrphase & mask] = thisin;
7077 out[i] = 0.f;
7078 } else {
7079 if (irdphase1 < 0) {
7080 d1 = d2 = d3 = 0.f;
7081 d0 = dlybuf[irdphase0 & mask];
7082 } else if (irdphase2 < 0) {
7083 d1 = d2 = d3 = 0.f;
7084 d0 = dlybuf[irdphase0 & mask];
7085 d1 = dlybuf[irdphase1 & mask];
7086 } else if (irdphase3 < 0) {
7087 d3 = 0.f;
7088 d0 = dlybuf[irdphase0 & mask];
7089 d1 = dlybuf[irdphase1 & mask];
7090 d2 = dlybuf[irdphase2 & mask];
7091 } else {
7092 d0 = dlybuf[irdphase0 & mask];
7093 d1 = dlybuf[irdphase1 & mask];
7094 d2 = dlybuf[irdphase2 & mask];
7095 d3 = dlybuf[irdphase3 & mask];
7097 float value = cubicinterp(frac, d0, d1, d2, d3);
7098 float thiscoef = coef[i];
7099 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7100 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7101 out[i] = lastsamp = onepole;
7103 iwrphase++;
7105 } else {
7107 float next_dsamp = CalcDelay(unit, delaytime);
7108 float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
7110 float next_feedbk = sc_CalcFeedback(delaytime, decaytime);
7111 float feedbk_slope = CALCSLOPE(next_feedbk, feedbk);
7113 for(int i = 0; i < inNumSamples; i++) {
7114 dsamp += dsamp_slope;
7115 long idsamp = (long)dsamp;
7116 float frac = dsamp - idsamp;
7117 long irdphase1 = iwrphase - idsamp;
7118 long irdphase2 = irdphase1 - 1;
7119 long irdphase3 = irdphase1 - 2;
7120 long irdphase0 = irdphase1 + 1;
7121 if (inputsamps > 0) {
7122 thisin = in[i];
7123 --inputsamps;
7124 } else {
7125 thisin = 0.f;
7127 if (irdphase0 < 0) {
7128 dlybuf[iwrphase & mask] = thisin;
7129 out[i] = 0.f;
7130 } else {
7131 if (irdphase1 < 0) {
7132 d1 = d2 = d3 = 0.f;
7133 d0 = dlybuf[irdphase0 & mask];
7134 } else if (irdphase2 < 0) {
7135 d1 = d2 = d3 = 0.f;
7136 d0 = dlybuf[irdphase0 & mask];
7137 d1 = dlybuf[irdphase1 & mask];
7138 } else if (irdphase3 < 0) {
7139 d3 = 0.f;
7140 d0 = dlybuf[irdphase0 & mask];
7141 d1 = dlybuf[irdphase1 & mask];
7142 d2 = dlybuf[irdphase2 & mask];
7143 } else {
7144 d0 = dlybuf[irdphase0 & mask];
7145 d1 = dlybuf[irdphase1 & mask];
7146 d2 = dlybuf[irdphase2 & mask];
7147 d3 = dlybuf[irdphase3 & mask];
7149 float value = cubicinterp(frac, d0, d1, d2, d3);
7150 float thiscoef = coef[i];
7151 float onepole = ((1. - fabs(thiscoef)) * value) + (thiscoef * lastsamp);
7152 dlybuf[iwrphase & mask] = thisin + feedbk * onepole;
7153 out[i] = lastsamp = onepole;
7155 feedbk += feedbk_slope;
7156 iwrphase++;
7158 unit->m_feedbk = feedbk;
7159 unit->m_dsamp = dsamp;
7160 unit->m_delaytime = delaytime;
7161 unit->m_decaytime = decaytime;
7164 unit->m_inputsamps = inputsamps;
7165 unit->m_lastsamp = zapgremlins(lastsamp);
7166 unit->m_iwrphase = iwrphase;
7168 unit->m_numoutput += inNumSamples;
7169 if (unit->m_numoutput >= unit->m_idelaylen) {
7170 SETCALC(Pluck_next_ka);
7175 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7178 #define DELTAP_BUF \
7179 World *world = unit->mWorld;\
7180 if (bufnum >= world->mNumSndBufs) { \
7181 int localBufNum = bufnum - world->mNumSndBufs; \
7182 Graph *parent = unit->mParent; \
7183 if(localBufNum <= parent->localBufNum) { \
7184 unit->m_buf = parent->mLocalSndBufs + localBufNum; \
7185 } else { \
7186 bufnum = 0; \
7187 unit->m_buf = world->mSndBufs + bufnum; \
7189 } else { \
7190 unit->m_buf = world->mSndBufs + bufnum; \
7192 SndBuf *buf = unit->m_buf; \
7193 float *bufData __attribute__((__unused__)) = buf->data; \
7194 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
7195 uint32 bufSamples = buf->samples; \
7196 uint32 bufFrames = buf->frames; \
7197 int guardFrame __attribute__((__unused__)) = bufFrames - 2; \
7198 double loopMax = (double)bufSamples;
7200 #define CHECK_DELTAP_BUF \
7201 if ((!bufData) || (bufChannels != 1)) { \
7202 unit->mDone = true; \
7203 ClearUnitOutputs(unit, inNumSamples); \
7204 return; \
7208 static void DelTapWr_first(DelTapWr *unit, int inNumSamples)
7210 float fbufnum = IN0(0);
7211 uint32 bufnum = (uint32)fbufnum;
7212 float* in = IN(1);
7213 float* out = OUT(0);
7215 uint32 phase = unit->m_phase;
7217 DELTAP_BUF
7218 CHECK_DELTAP_BUF
7220 // zero out the buffer!
7221 #ifdef NOVA_SIMD
7222 if (nova::vec<float>::is_aligned(bufData)) {
7223 uint32 unroll = bufSamples & (~(nova::vec<float>::size - 1));
7224 nova::zerovec_simd(bufData, unroll);
7226 uint32 remain = bufSamples - unroll;
7227 Clear(remain, bufData + unroll);
7229 #else
7230 Clear(bufSamples, bufData);
7231 #endif
7233 out[0] = (float)phase;
7234 bufData[phase] = in[0];
7235 phase++;
7236 if(phase == bufSamples)
7237 phase -= bufSamples;
7239 unit->m_phase = phase;
7242 void DelTapWr_Ctor(DelTapWr *unit)
7244 if (BUFLENGTH & 15)
7245 SETCALC(DelTapWr_next);
7246 else
7247 SETCALC(DelTapWr_next_simd);
7248 unit->m_phase = 0;
7249 unit->m_fbufnum = -1e9f;
7250 DelTapWr_first(unit, 1);
7253 template <bool simd>
7254 static inline void DelTapWr_perform(DelTapWr *unit, int inNumSamples)
7256 float fbufnum = IN0(0);
7257 uint32 bufnum = (uint32)fbufnum;
7258 const float* in = ZIN(1);
7259 float* out = ZOUT(0);
7260 uint32 * phase_out = (uint32*)out;
7262 uint32 phase = unit->m_phase;
7264 DELTAP_BUF
7265 CHECK_DELTAP_BUF
7267 LOCK_SNDBUF(buf);
7268 int buf_remain = (int)(bufSamples - phase);
7269 if (inNumSamples < buf_remain)
7271 /* fast-path */
7272 #ifdef NOVA_SIMD
7273 if (simd)
7274 nova::copyvec_an_simd(bufData+phase, IN(1), inNumSamples);
7275 else
7276 #endif
7277 Copy(inNumSamples, bufData + phase, IN(1));
7278 LOOP1 (inNumSamples,
7279 ZXP(phase_out) = phase++;
7281 } else {
7282 LOOP1 (inNumSamples,
7283 bufData[phase] = ZXP(in);
7284 ZXP(phase_out) = phase++;
7285 if(phase == bufSamples)
7286 phase -= bufSamples;
7290 unit->m_phase = phase;
7293 void DelTapWr_next(DelTapWr *unit, int inNumSamples)
7295 DelTapWr_perform<false>(unit, inNumSamples);
7298 void DelTapWr_next_simd(DelTapWr *unit, int inNumSamples)
7300 DelTapWr_perform<true>(unit, inNumSamples);
7304 #define SETUP_TAPDELK \
7305 float delTime = unit->m_delTime; \
7306 float newDelTime = IN0(2) * (float)SAMPLERATE; \
7307 float delTimeInc = CALCSLOPE(newDelTime, delTime); \
7308 float * fPhaseIn = IN(1); \
7309 uint32 * iPhaseIn = (uint32*)fPhaseIn; \
7310 uint32 phaseIn = *iPhaseIn; \
7311 float fbufnum = IN0(0); \
7312 uint32 bufnum = (uint32)fbufnum; \
7313 float* out = ZOUT(0); \
7315 #define SETUP_TAPDELA \
7316 float* delTime = ZIN(2); \
7317 float * fPhaseIn = IN(1); \
7318 uint32 * iPhaseIn = (uint32*)fPhaseIn; \
7319 uint32 phaseIn = *iPhaseIn; \
7320 float fbufnum = IN0(0); \
7321 uint32 bufnum = (uint32)fbufnum; \
7322 float* out = ZOUT(0); \
7324 void DelTapRd_Ctor(DelTapRd *unit)
7326 unit->m_fbufnum = -1e9f;
7327 unit->m_delTime = IN0(2) * SAMPLERATE;
7328 int interp = (int)IN0(3);
7329 if (INRATE(2) == calc_FullRate) {
7330 if (interp == 2)
7331 SETCALC(DelTapRd_next2_a);
7332 else if (interp == 4)
7333 SETCALC(DelTapRd_next4_a);
7334 else
7335 SETCALC(DelTapRd_next1_a);
7336 } else {
7337 if (interp == 2)
7338 SETCALC(DelTapRd_next2_k);
7339 else if (interp == 4)
7340 SETCALC(DelTapRd_next4_k);
7341 else
7342 if (BUFLENGTH & 15)
7343 SETCALC(DelTapRd_next1_k);
7344 else {
7345 SETCALC(DelTapRd_next1_k_simd);
7346 DelTapRd_next1_k(unit, 1);
7347 return;
7350 (unit->mCalcFunc)(unit, 1);
7354 void DelTapRd_next1_a(DelTapRd *unit, int inNumSamples)
7356 SETUP_TAPDELA
7357 DELTAP_BUF
7358 CHECK_DELTAP_BUF
7360 LOCK_SNDBUF_SHARED(buf);
7361 LOOP1(inNumSamples,
7362 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7363 double phase = phaseIn - curDelTimeSamps;
7364 if(phase < 0.) phase += loopMax;
7365 if(phase >=loopMax) phase -= loopMax;
7366 int32 iphase = (int32)phase;
7367 ZXP(out) = bufData[iphase];
7368 phaseIn += 1.;
7372 template <bool simd>
7373 inline void DelTapRd_perform1_k(DelTapRd *unit, int inNumSamples)
7375 SETUP_TAPDELK
7376 DELTAP_BUF
7377 CHECK_DELTAP_BUF
7378 float * zout = ZOUT(0);
7380 LOCK_SNDBUF_SHARED(buf);
7381 if (delTime == newDelTime)
7383 double phase = (double)phaseIn - delTime;
7384 int32 iphase = (int32)phase;
7385 if ( (iphase >= 0) // lower bound
7386 && iphase + inNumSamples < (bufSamples - 1)) //upper bound
7388 #ifdef NOVA_SIMD
7389 if (simd)
7390 nova::copyvec_na_simd(OUT(0), bufData + iphase, inNumSamples);
7391 else
7392 #endif
7393 Copy(inNumSamples, OUT(0), bufData + iphase);
7395 else
7396 LOOP1(inNumSamples,
7397 if(iphase < 0) iphase += bufSamples;
7398 if(iphase >= bufSamples) iphase -= bufSamples;
7399 ZXP(zout) = bufData[iphase];
7400 ++iphase;
7402 } else {
7403 LOOP1(inNumSamples,
7404 double phase = (double)phaseIn - delTime;
7405 if(phase < 0.) phase += loopMax;
7406 if(phase >=loopMax) phase -= loopMax;
7407 int32 iphase = (int32)phase;
7408 ZXP(zout) = bufData[iphase];
7409 delTime += delTimeInc;
7410 ++phaseIn;
7412 unit->m_delTime = delTime;
7416 void DelTapRd_next1_k(DelTapRd *unit, int inNumSamples)
7418 DelTapRd_perform1_k<false>(unit, inNumSamples);
7421 void DelTapRd_next1_k_simd(DelTapRd *unit, int inNumSamples)
7423 DelTapRd_perform1_k<true>(unit, inNumSamples);
7426 void DelTapRd_next2_k(DelTapRd *unit, int inNumSamples)
7428 SETUP_TAPDELK
7429 DELTAP_BUF
7430 CHECK_DELTAP_BUF
7432 int32 iloopMax = (int32)bufSamples;
7434 LOCK_SNDBUF_SHARED(buf);
7436 if (delTime == newDelTime)
7438 double phase = (double)phaseIn - delTime;
7439 double dphase;
7440 float fracphase = std::modf(phase, &dphase);
7441 int32 iphase = (int32)dphase;
7443 if ( (phase >= 0) // lower bound
7444 && phase + inNumSamples < (loopMax - 2)) //upper bound
7446 LOOP1(inNumSamples,
7447 int32 iphase1 = iphase + 1;
7448 float b = bufData[iphase];
7449 float c = bufData[iphase1];
7450 ZXP(out) = (b + fracphase * (c - b));
7451 iphase += 1;
7453 } else {
7454 LOOP1(inNumSamples,
7455 if(iphase < 0) iphase += iloopMax;
7456 else if(iphase >= bufSamples) phase -= iloopMax;
7457 int32 iphase1 = iphase + 1;
7458 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7459 float b = bufData[iphase];
7460 float c = bufData[iphase1];
7461 ZXP(out) = (b + fracphase * (c - b));
7462 ++iphase;
7465 } else {
7466 LOOP1(inNumSamples,
7467 double phase = (double)phaseIn - delTime;
7468 if(phase < 0.) phase += loopMax;
7469 if(phase >= loopMax) phase -= loopMax;
7470 int32 iphase = (int32)phase;
7471 int32 iphase1 = iphase + 1;
7472 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7473 float fracphase = phase - (double)iphase;
7474 float b = bufData[iphase];
7475 float c = bufData[iphase1];
7476 ZXP(out) = (b + fracphase * (c - b));
7477 delTime += delTimeInc;
7478 ++phaseIn;
7480 unit->m_delTime = delTime;
7484 void DelTapRd_next2_a(DelTapRd *unit, int inNumSamples)
7486 SETUP_TAPDELA
7487 DELTAP_BUF
7488 CHECK_DELTAP_BUF
7490 int32 iloopMax = (int32)bufSamples;
7492 LOCK_SNDBUF_SHARED(buf);
7493 LOOP1(inNumSamples,
7494 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7495 double phase = (double)phaseIn - curDelTimeSamps;
7496 if(phase < 0.) phase += loopMax;
7497 if(phase >= loopMax) phase -= loopMax;
7498 int32 iphase = (int32)phase;
7499 int32 iphase1 = iphase + 1;
7500 if(iphase1 >= iloopMax) iphase1 -= iloopMax;
7501 float fracphase = phase - (double)iphase;
7502 float b = bufData[iphase];
7503 float c = bufData[iphase1];
7504 ZXP(out) = (b + fracphase * (c - b));
7505 ++phaseIn;
7509 void DelTapRd_next4_k(DelTapRd *unit, int inNumSamples)
7511 SETUP_TAPDELK
7512 DELTAP_BUF
7513 CHECK_DELTAP_BUF
7515 int32 iloopMax = (int32)loopMax;
7517 LOCK_SNDBUF_SHARED(buf);
7520 if (delTime == newDelTime)
7522 double phase = (double)phaseIn - delTime;
7523 double dphase;
7524 float fracphase = std::modf(phase, &dphase);
7525 int32 iphase = (int32)dphase;
7527 if ( (iphase >= 1) // lower bound
7528 && iphase + inNumSamples < (iloopMax - 4)) //upper bound
7530 LOOP1(inNumSamples,
7531 int32 iphase0 = iphase - 1;
7532 int32 iphase1 = iphase + 1;
7533 int32 iphase2 = iphase + 2;
7535 float a = bufData[iphase0];
7536 float b = bufData[iphase];
7537 float c = bufData[iphase1];
7538 float d = bufData[iphase2];
7539 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7540 ++iphase;
7542 } else {
7543 LOOP1(inNumSamples,
7544 if(iphase < 0) iphase += iloopMax;
7545 else if(iphase >= iloopMax) iphase -= iloopMax;
7546 int32 iphase0 = iphase - 1;
7547 int32 iphase1 = iphase + 1;
7548 int32 iphase2 = iphase + 2;
7550 if(iphase0 < 0) iphase0 += iloopMax;
7551 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7552 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7554 float a = bufData[iphase0];
7555 float b = bufData[iphase];
7556 float c = bufData[iphase1];
7557 float d = bufData[iphase2];
7558 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7559 ++iphase;
7562 } else {
7563 LOOP1(inNumSamples,
7564 double phase = (double)phaseIn - delTime;
7565 double dphase;
7566 float fracphase = std::modf(phase, &dphase);
7567 int32 iphase = (int32)dphase;
7569 if(iphase < 0.) iphase += iloopMax;
7570 if(iphase >= iloopMax) iphase -= iloopMax;
7571 int32 iphase0 = iphase - 1;
7572 int32 iphase1 = iphase + 1;
7573 int32 iphase2 = iphase + 2;
7575 if(iphase0 < 0) iphase0 += iloopMax;
7576 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7577 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7579 float a = bufData[iphase0];
7580 float b = bufData[iphase];
7581 float c = bufData[iphase1];
7582 float d = bufData[iphase2];
7583 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7584 delTime += delTimeInc;
7585 ++phaseIn;
7587 unit->m_delTime = delTime;
7591 void DelTapRd_next4_a(DelTapRd *unit, int inNumSamples)
7593 SETUP_TAPDELA
7594 DELTAP_BUF
7595 CHECK_DELTAP_BUF
7597 int32 iloopMax = (int32)loopMax;
7599 LOCK_SNDBUF_SHARED(buf);
7600 LOOP1(inNumSamples,
7601 double curDelTimeSamps = ZXP(delTime) * SAMPLERATE;
7602 double phase = (double)phaseIn - curDelTimeSamps;
7603 if(phase < 0.) phase += loopMax;
7604 if(phase >= loopMax) phase -= loopMax;
7605 int32 iphase = (int32)phase;
7606 int32 iphase0 = iphase - 1;
7607 int32 iphase1 = iphase + 1;
7608 int32 iphase2 = iphase + 2;
7610 if(iphase0 < 0) iphase0 += iloopMax;
7611 if(iphase1 > iloopMax) iphase1 -=iloopMax;
7612 if(iphase2 > iloopMax) iphase2 -=iloopMax;
7614 float fracphase = phase - (double)iphase;
7615 float a = bufData[iphase0];
7616 float b = bufData[iphase];
7617 float c = bufData[iphase1];
7618 float d = bufData[iphase2];
7619 ZXP(out) = cubicinterp(fracphase, a, b, c, d);
7620 ++phaseIn;
7625 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7628 ////////////////////////////////////////////////////////////////////////////////////////////////////////
7630 PluginLoad(Delay)
7632 ft = inTable;
7634 #define DefineInfoUnit(name) \
7635 (*ft->fDefineUnit)(#name, sizeof(Unit), (UnitCtorFunc)&name##_Ctor, 0, 0);
7637 DefineInfoUnit(ControlRate);
7638 DefineInfoUnit(SampleRate);
7639 DefineInfoUnit(SampleDur);
7640 DefineInfoUnit(ControlDur);
7641 DefineInfoUnit(SubsampleOffset);
7642 DefineInfoUnit(RadiansPerSample);
7643 DefineInfoUnit(NumInputBuses);
7644 DefineInfoUnit(NumOutputBuses);
7645 DefineInfoUnit(NumAudioBuses);
7646 DefineInfoUnit(NumControlBuses);
7647 DefineInfoUnit(NumBuffers);
7648 DefineInfoUnit(NumRunningSynths);
7650 #define DefineBufInfoUnit(name) \
7651 (*ft->fDefineUnit)(#name, sizeof(BufInfoUnit), (UnitCtorFunc)&name##_Ctor, 0, 0);
7653 DefineBufInfoUnit(BufSampleRate);
7654 DefineBufInfoUnit(BufRateScale);
7655 DefineBufInfoUnit(BufSamples);
7656 DefineBufInfoUnit(BufFrames);
7657 DefineBufInfoUnit(BufChannels);
7658 DefineBufInfoUnit(BufDur);
7660 DefineSimpleCantAliasUnit(PlayBuf);
7661 #if NOTYET
7662 DefineSimpleUnit(SimpleLoopBuf);
7663 #endif
7664 DefineDtorUnit(RecordBuf);
7665 DefineSimpleUnit(BufRd);
7666 DefineSimpleUnit(BufWr);
7667 DefineDtorUnit(Pitch);
7669 DefineSimpleUnit(BufDelayN);
7670 DefineSimpleUnit(BufDelayL);
7671 DefineSimpleUnit(BufDelayC);
7672 DefineSimpleUnit(BufCombN);
7673 DefineSimpleUnit(BufCombL);
7674 DefineSimpleUnit(BufCombC);
7675 DefineSimpleUnit(BufAllpassN);
7676 DefineSimpleUnit(BufAllpassL);
7677 DefineSimpleUnit(BufAllpassC);
7679 #define DefineDelayUnit(name) \
7680 (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
7681 (UnitDtorFunc)&DelayUnit_Dtor, 0);
7683 DefineDelayUnit(DelayN);
7684 DefineDelayUnit(DelayL);
7685 DefineDelayUnit(DelayC);
7686 DefineDelayUnit(CombN);
7687 DefineDelayUnit(CombL);
7688 DefineDelayUnit(CombC);
7689 DefineDelayUnit(AllpassN);
7690 DefineDelayUnit(AllpassL);
7691 DefineDelayUnit(AllpassC);
7693 DefineDtorUnit(PitchShift);
7694 DefineSimpleUnit(GrainTap);
7695 DefineSimpleCantAliasUnit(TGrains);
7696 DefineDtorUnit(ScopeOut);
7697 DefineDtorUnit(ScopeOut2);
7698 DefineDelayUnit(Pluck);
7700 DefineSimpleUnit(DelTapWr);
7701 DefineSimpleUnit(DelTapRd);
7703 DefineDtorUnit(LocalBuf);
7704 DefineSimpleUnit(MaxLocalBufs);
7705 DefineSimpleUnit(SetBuf);
7706 DefineSimpleUnit(ClearBuf);
7709 //////////////////////////////////////////////////////////////////////////////////////////////////