/[svn]/linuxsampler/trunk/src/engines/common/SignalUnit.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/common/SignalUnit.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2232 by iliev, Mon Aug 8 13:40:04 2011 UTC revision 2264 by iliev, Mon Aug 22 10:00:01 2011 UTC
# Line 24  Line 24 
24  #define __LS_SIGNALUNIT_H__  #define __LS_SIGNALUNIT_H__
25    
26  #include "../../common/ArrayList.h"  #include "../../common/ArrayList.h"
27    #include "../../common/Pool.h"
28    
29    
30  namespace LinuxSampler {  namespace LinuxSampler {
# Line 38  namespace LinuxSampler { Line 39  namespace LinuxSampler {
39              }              }
40                            
41              ~FixedArray() {              ~FixedArray() {
42                  delete pData;                  delete[] pData;
43                  pData = NULL;                  pData = NULL;
44              }              }
45                            
# Line 51  namespace LinuxSampler { Line 52  namespace LinuxSampler {
52              }              }
53                            
54                            
55              T increment() {              T& increment() {
56                  if (iSize >= iCapacity) throw Exception("Array out of bounds");                  if (iSize >= iCapacity) throw Exception("Array out of bounds");
57                  return pData[iSize++];                  return pData[iSize++];
58              }              }
# Line 163  namespace LinuxSampler { Line 164  namespace LinuxSampler {
164          public:          public:
165              ArrayList<SignalUnit::Parameter> Params; // The list of parameters which are modulating the signal unit              ArrayList<SignalUnit::Parameter> Params; // The list of parameters which are modulating the signal unit
166                            
167              SignalUnit(SignalUnitRack* rack): pRack(rack), bActive(false), Level(0.0f), bCalculating(false), uiDelayTrigger(0) { }              SignalUnit(SignalUnitRack* rack): pRack(rack), bActive(false), Level(0.0f), bRecalculate(true), bCalculating(false), uiDelayTrigger(0) { }
168              SignalUnit(const SignalUnit& Unit): pRack(Unit.pRack) { Copy(Unit); }              SignalUnit(const SignalUnit& Unit): pRack(Unit.pRack) { Copy(Unit); }
169              void operator=(const SignalUnit& Unit) { Copy(Unit); }              void operator=(const SignalUnit& Unit) { Copy(Unit); }
170                virtual ~SignalUnit() { }
171                            
172              void Copy(const SignalUnit& Unit) {              void Copy(const SignalUnit& Unit) {
173                  if (this == &Unit) return;                  if (this == &Unit) return;
# Line 202  namespace LinuxSampler { Line 204  namespace LinuxSampler {
204               * the parameters, their levels are calculated too.               * the parameters, their levels are calculated too.
205               */               */
206              virtual float GetLevel() {              virtual float GetLevel() {
207                  if (!bRecalculate) return Level;                  if (Params.empty() || !bRecalculate) return Level;
208    
209                  if (bCalculating) {                  if (bCalculating) {
210                      std::cerr << "SignalUnit: Loop detected. Aborted!";                      std::cerr << "SignalUnit: Loop detected. Aborted!";
# Line 327  namespace LinuxSampler { Line 329  namespace LinuxSampler {
329       */       */
330      class Smoother {      class Smoother {
331          protected:          protected:
332              uint    timeSteps; // The number of time steps to reach the goal              uint  timeSteps; // The number of time steps to reach the goal
333              uint    currentTimeStep;              uint  currentTimeStep;
334              uint8_t goal; // 0 - 127              float goal;
335              uint8_t prev; // 0 - 127              float prev;
336                            
337          public:          public:
338              /**              /**
# Line 339  namespace LinuxSampler { Line 341  namespace LinuxSampler {
341               * @param sampleRate               * @param sampleRate
342               * @param val The initial value               * @param val The initial value
343               */               */
344              void trigger(float time, float sampleRate, uint8_t val = 0) {              void trigger(float time, float sampleRate, float val = 0) {
345                  currentTimeStep = timeSteps = time * sampleRate;                  currentTimeStep = timeSteps = time * sampleRate;
346                  prev = goal = val;                  prev = goal = val;
347              }              }
# Line 348  namespace LinuxSampler { Line 350  namespace LinuxSampler {
350               * Set the current value, which the smoother will not smooth out.               * Set the current value, which the smoother will not smooth out.
351               * If you want the value to be smoothen out, use update() instead.               * If you want the value to be smoothen out, use update() instead.
352               */               */
353              void setValue( uint8_t val) {              void setValue( float val) {
354                  currentTimeStep = timeSteps;                  currentTimeStep = timeSteps;
355                  prev = goal = val;                  prev = goal = val;
356              }              }
# Line 357  namespace LinuxSampler { Line 359  namespace LinuxSampler {
359               * Sets a new value. The render function will return               * Sets a new value. The render function will return
360               * values gradually approaching this value.               * values gradually approaching this value.
361               */               */
362              void update(uint8_t val) {              void update(float val) {
363                  if (val == goal) return;                  if (val == goal) return;
364                                    
365                  prev = prev + (goal - prev) * (currentTimeStep / (float)timeSteps);                  prev = prev + (goal - prev) * (currentTimeStep / (float)timeSteps);
# Line 365  namespace LinuxSampler { Line 367  namespace LinuxSampler {
367                  currentTimeStep = 0;                  currentTimeStep = 0;
368              }              }
369                            
370              uint8_t render() {              float render() {
371                  if (currentTimeStep >= timeSteps) return goal;                  if (currentTimeStep >= timeSteps) return goal;
372                  return prev + (goal - prev) * (currentTimeStep++ / (float)timeSteps);                  return prev + (goal - prev) * (currentTimeStep++ / (float)timeSteps);
373              }              }
374                            
375              bool isSmoothingOut() { return currentTimeStep < timeSteps; }              bool isSmoothingOut() { return currentTimeStep < timeSteps; }
376                
377                float getGoal() { return goal; }
378      };      };
379            
380      /**      /**
# Line 386  namespace LinuxSampler { Line 390  namespace LinuxSampler {
390                      virtual void ValueChanged(CCSignalUnit* pUnit) = 0;                      virtual void ValueChanged(CCSignalUnit* pUnit) = 0;
391              };              };
392                            
         protected:  
393              class CC {              class CC {
394                  public:                  public:
395                      uint8_t   Controller;  ///< MIDI controller number.                      uint8_t   Controller;  ///< MIDI controller number.
396                      uint8_t   Value;       ///< Controller Value.                      uint8_t   Value;       ///< Controller Value.
397                      short int Curve;       ///< specifies the curve type                      short int Curve;       ///< specifies the curve type
398                      float     Influence;                      float     Influence;
399                        float     Step;
400                                            
401                      Smoother* pSmoother;                      Smoother* pSmoother;
402                                            
403                      CC(uint8_t Controller = 0, float Influence = 0.0f, short int Curve = -1, Smoother* pSmoother = NULL) {                      CC (
404                            uint8_t   Controller = 0,
405                            float     Influence  = 0.0f,
406                            short int Curve      = -1,
407                            Smoother* pSmoother  = NULL,
408                            float     Step       = 0
409                        ) {
410                          this->Controller = Controller;                          this->Controller = Controller;
411                          this->Value = 0;                          this->Value = 0;
412                          this->Curve = Curve;                          this->Curve = Curve;
413                          this->Influence = Influence;                          this->Influence = Influence;
414                          this->pSmoother = pSmoother;                          this->pSmoother = pSmoother;
415                            this->Step  = Step;
416                      }                      }
417                                            
418                      CC(const CC& cc) { Copy(cc); }                      CC(const CC& cc) { Copy(cc); }
# Line 409  namespace LinuxSampler { Line 420  namespace LinuxSampler {
420                                            
421                      void Copy(const CC& cc) {                      void Copy(const CC& cc) {
422                          Controller = cc.Controller;                          Controller = cc.Controller;
423                          Value = cc.Value;                          Value      = cc.Value;
424                          Influence = cc.Influence;                          Influence  = cc.Influence;
425                          Curve = cc.Curve;                          Curve      = cc.Curve;
426                          pSmoother = cc.pSmoother;                          pSmoother  = cc.pSmoother;
427                            Step       = cc.Step;
428                      }                      }
429              };              };
430                            
431              FixedArray<CC> Ctrls; // The MIDI controllers which modulates this signal unit.          protected:
432                RTList<CC>* pCtrls; // The MIDI controllers which modulates this signal unit.
433              Listener* pListener;              Listener* pListener;
434              bool hasSmoothCtrls; // determines whether there are smooth controllers (used for optimization)              bool hasSmoothCtrls; // determines whether there are smooth controllers (used for optimization)
435              bool isSmoothingOut; // determines whether there is a CC which is in process of smoothing out (used for optimization)              bool isSmoothingOut; // determines whether there is a CC which is in process of smoothing out (used for optimization)
436    
437          public:          public:
438                            
439              CCSignalUnit(SignalUnitRack* rack, Listener* l = NULL): SignalUnit(rack), Ctrls(128) {              CCSignalUnit(SignalUnitRack* rack, Listener* l = NULL): SignalUnit(rack), pCtrls(NULL) {
440                  pListener = l;                  pListener = l;
441                  hasSmoothCtrls = isSmoothingOut = false;                  hasSmoothCtrls = isSmoothingOut = false;
442              }              }
443                            
444              CCSignalUnit(const CCSignalUnit& Unit): SignalUnit(Unit.pRack), Ctrls(128) { Copy(Unit); }              CCSignalUnit(const CCSignalUnit& Unit): SignalUnit(Unit.pRack), pCtrls(NULL) { Copy(Unit); }
445              void operator=(const CCSignalUnit& Unit) { Copy(Unit); }              void operator=(const CCSignalUnit& Unit) { Copy(Unit); }
446                            
447                virtual ~CCSignalUnit() {
448                    if (pCtrls != NULL) delete pCtrls;
449                }
450                
451              void Copy(const CCSignalUnit& Unit) {              void Copy(const CCSignalUnit& Unit) {
452                  Ctrls.copy(Unit.Ctrls);                  if (pCtrls != NULL) delete pCtrls;
453                    pCtrls = new RTList<CC>(*(Unit.pCtrls));
454                    if (pCtrls->poolIsEmpty() && pCtrls->count() < Unit.pCtrls->count()) {
455                        std::cerr << "Maximum number of CC reached!" << std::endl;
456                    }
457                    
458                  pListener = Unit.pListener;                  pListener = Unit.pListener;
459                  hasSmoothCtrls = Unit.hasSmoothCtrls;                  hasSmoothCtrls = Unit.hasSmoothCtrls;
460                  isSmoothingOut = Unit.isSmoothingOut;                  isSmoothingOut = Unit.isSmoothingOut;
461                  SignalUnit::Copy(Unit);                  SignalUnit::Copy(Unit);
462              }              }
463                            
464              void AddCC(uint8_t Controller, float Influence, short int Curve = -1, Smoother* pSmoother = NULL) {              virtual void InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
465                  Ctrls.add(CC(Controller, Influence, Curve, pSmoother));                  if (pCtrls != NULL) delete pCtrls;
466                  if (pSmoother != NULL) hasSmoothCtrls = true;                  pCtrls = new RTList<CC>(pCCPool);
467              }              }
468                            
469              void RemoveAllCCs() {              void AddCC(uint8_t Controller, float Influence, short int Curve = -1, Smoother* pSmoother = NULL, float Step = 0) {
470                  Ctrls.clear();                  if(pCtrls->poolIsEmpty()) {
471                        std::cerr << "Maximum number of CC reached!" << std::endl;
472                        return;
473                    }
474                    *(pCtrls->allocAppend()) = CC(Controller, Influence, Curve, pSmoother, Step);
475                    if (pSmoother != NULL) hasSmoothCtrls = true;
476              }              }
477                            
478                virtual void RemoveAllCCs() { pCtrls->clear(); }
479                
480                int GetCCCount() { return pCtrls->count(); }
481                
482              virtual void Increment() {              virtual void Increment() {
483                  if (hasSmoothCtrls && isSmoothingOut) Calculate();                  if (hasSmoothCtrls && isSmoothingOut) Calculate();
484              }              }
# Line 460  namespace LinuxSampler { Line 491  namespace LinuxSampler {
491              virtual void ProcessCCEvent(uint8_t Controller, uint8_t Value) {              virtual void ProcessCCEvent(uint8_t Controller, uint8_t Value) {
492                  bool recalculate = false;                  bool recalculate = false;
493                                    
494                  for (int i = 0; i < Ctrls.size(); i++) {                  RTList<CC>::Iterator ctrl = pCtrls->first();
495                      if (Controller != Ctrls[i].Controller) continue;                  RTList<CC>::Iterator end  = pCtrls->end();
496                      if (Ctrls[i].Value == Value) continue;                  for(; ctrl != end; ++ctrl) {
497                      Ctrls[i].Value = Value;                      if (Controller != (*ctrl).Controller) continue;
498                      if (Ctrls[i].pSmoother != NULL) Ctrls[i].pSmoother->update(Value);                      if ((*ctrl).Value == Value) continue;
499                        
500                        (*ctrl).Value = Value;
501                        
502                        if ((*ctrl).Step > 0 && (*ctrl).pSmoother != NULL) {
503                            float oldGoal = (*ctrl).pSmoother->getGoal();
504                            float newGoal = Normalize(Value, (*ctrl).Curve) * (*ctrl).Influence;
505                            newGoal = ((int) (newGoal / (*ctrl).Step)) * (*ctrl).Step;
506                            if (oldGoal != newGoal) (*ctrl).pSmoother->update(newGoal);
507                        }
508                        
509                        if ((*ctrl).pSmoother != NULL && (*ctrl).Step <= 0) (*ctrl).pSmoother->update(Value);
510                      if (!bActive) bActive = true;                      if (!bActive) bActive = true;
511                      recalculate = true;                      recalculate = true;
512                  }                  }
# Line 475  namespace LinuxSampler { Line 517  namespace LinuxSampler {
517              virtual void Calculate() {              virtual void Calculate() {
518                  float l = 0;                  float l = 0;
519                  isSmoothingOut = false;                  isSmoothingOut = false;
520                  for (int i = 0; i < Ctrls.size(); i++) {                  RTList<CC>::Iterator ctrl = pCtrls->first();
521                      if (Ctrls[i].pSmoother == NULL) {                  RTList<CC>::Iterator end  = pCtrls->end();
522                          l += Normalize(Ctrls[i].Value, Ctrls[i].Curve) * Ctrls[i].Influence;                  for(; ctrl != end; ++ctrl) {
523                        if ((*ctrl).pSmoother == NULL) {
524                            float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
525                            if ((*ctrl).Step > 0) val = ( (int)(val / (*ctrl).Step) ) * (*ctrl).Step;
526                            l += val;
527                      } else {                      } else {
528                          if (Ctrls[i].pSmoother->isSmoothingOut()) isSmoothingOut = true;                          if ((*ctrl).pSmoother->isSmoothingOut()) isSmoothingOut = true;
529                          l += Normalize(Ctrls[i].pSmoother->render(), Ctrls[i].Curve) * Ctrls[i].Influence;                          
530                            if ((*ctrl).Step > 0) {
531                                l += (*ctrl).pSmoother->render();
532                            } else {
533                                l += Normalize((*ctrl).pSmoother->render(), (*ctrl).Curve) * (*ctrl).Influence;
534                            }
535                      }                      }
536                  }                  }
537                  if (Level != l) {                  if (Level != l) {

Legend:
Removed from v.2232  
changed lines
  Added in v.2264

  ViewVC Help
Powered by ViewVC