[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] [commit] PeakFollower




 there is still a problem with triggers: an audio rate trigger in a
 control rate ugen does not work properly. This is not solved by A2K
 now, because it exactly acts like an ausdio rate ugen input.


Hi Julian,

There is a stub for PeakFollower, but no plug-in.  Seems like this
would be a good place for that functionality.

that's a good idea.


I've written the missing PeakFollower and added a helpfile.
I used the leak algorithm from Integrator.





Index: TriggerUGens.cpp
===================================================================
RCS file: /cvsroot/supercollider/SuperCollider3/source/plugins/TriggerUGens.cpp,v
retrieving revision 1.21
diff -p -b -B -r1.21 TriggerUGens.cpp
*** TriggerUGens.cpp    3 Aug 2004 21:55:13 -0000       1.21
--- TriggerUGens.cpp    6 Nov 2004 15:56:57 -0000
*************** struct Peak : public Unit
*** 125,130 ****
--- 125,136 ----
        float m_prevtrig;
  };

+ struct PeakFollower : public Unit
+ {
+       float mLevel;
+       float mDecay;
+ };
+
  struct MostChange : public Unit
  {
        float mPrevA, mPrevB;
*************** void Peak_next_ak(Peak *unit, int inNumS
*** 254,259 ****
--- 260,270 ----
  void Peak_next_ai(Peak *unit, int inNumSamples);
  void Peak_next_aa(Peak *unit, int inNumSamples);

+
+ void PeakFollower_Ctor(PeakFollower *unit);
+ void PeakFollower_next(PeakFollower *unit, int inNumSamples);
+ void PeakFollower_next_ai(PeakFollower *unit, int inNumSamples);
+
  void MostChange_Ctor(MostChange *unit);
  void MostChange_next_ak(MostChange *unit, int inNumSamples);
  void MostChange_next_ka(MostChange *unit, int inNumSamples);
*************** void Peak_next_aa(Peak *unit, int inNumS
*** 1431,1438 ****
--- 1442,1551 ----
        unit->mLevel = level;
  }

+

////////////////////////////////////////////////////////////////////////////////////////////////////////

+ void PeakFollower_Ctor(PeakFollower *unit)
+ {
+
+       if (INRATE(1) == calc_ScalarRate) {
+               SETCALC(PeakFollower_next_ai);
+       } else {
+               SETCALC(PeakFollower_next);
+       }
+
+       unit->mDecay = ZIN0(1);
+       ZOUT0(0) = unit->mLevel = ZIN0(0);
+ }
+
+ void PeakFollower_next(PeakFollower *unit, int inNumSamples)
+ {
+       float *out = ZOUT(0);
+       float *in = ZIN(0);
+       float decay = ZIN0(1);
+       float level = unit->mLevel;
+
+
+       if(decay == unit->mDecay) {
+               LOOP(inNumSamples,
+                       float inlevel = ZXP(in);
+                       if (inlevel >= level) {
+                               level = inlevel;
+                       } else {
+                               level = inlevel + decay * (level - inlevel);
+                       }
+                       ZXP(out) = level;
+               );
+
+       } else {
+
+               float decay_slope = CALCSLOPE(decay, unit->mDecay);
+               if (decay >= 0.f && unit->mDecay >= 0.f) {
+                       LOOP(inNumSamples,
+                               float inlevel = ZXP(in);
+                               if (inlevel >= level) {
+                                       level = inlevel;
+                               } else {
+ level = inlevel + decay * (level - inlevel);
+                                       decay += decay_slope;
+                               };
+                               ZXP(out) = level;
+                       );
+               } else if (decay <= 0.f && unit->mDecay <= 0.f) {
+                       LOOP(inNumSamples,
+                               float inlevel = ZXP(in);
+                               if (inlevel >= level) {
+                                       level = inlevel;
+                               } else {
+ level = inlevel + decay * (level + inlevel);
+                                       decay += decay_slope;
+                               };
+                               ZXP(out) = level;
+                       );
+               } else {
+                       LOOP(inNumSamples,
+                               float inlevel = ZXP(in);
+                               if (inlevel >= level) {
+                                       level = inlevel;
+                               } else {
+ level = (1.f - fabs(decay)) * inlevel + decay * level;
+                                       decay += decay_slope;
+                               };
+                               ZXP(out) = level;
+                       );
+               };
+       }
+
+       unit->mLevel = level;
+       unit->mDecay = decay;
+ }
+
+
+ void PeakFollower_next_ai(PeakFollower *unit, int inNumSamples)
+ {
+       float *out = ZOUT(0);
+       float *in = ZIN(0);
+       float decay = ZIN0(1);
+       float level = unit->mLevel;
+
+               LOOP(inNumSamples,
+                       float inlevel = ZXP(in);
+                       if (inlevel >= level) {
+                               level = inlevel;
+                       } else {
+                               level = inlevel + decay * (level - inlevel);
+                       }
+                       ZXP(out) = level;
+               );
+
+       unit->mLevel = level;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
  void MostChange_Ctor(MostChange *unit)
  {
        if (INRATE(0) == calc_FullRate) {
*************** void load(InterfaceTable *inTable)
*** 1899,1904 ****
--- 2012,2018 ----
        DefineSimpleUnit(Sweep);
        DefineSimpleUnit(Phasor);
        DefineSimpleUnit(Peak);
+       DefineSimpleUnit(PeakFollower);
        DefineSimpleUnit(MostChange);
        DefineSimpleUnit(LeastChange);
        DefineSimpleUnit(LastValue);
--








.