/[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 2207 by iliev, Fri Jul 15 15:43:49 2011 UTC revision 2230 by iliev, Fri Aug 5 17:59:10 2011 UTC
# Line 28  Line 28 
28    
29  namespace LinuxSampler {  namespace LinuxSampler {
30    
31        template<typename T>
32        class FixedArray {
33            public:
34                FixedArray(int capacity) {
35                    iSize = 0;
36                    iCapacity = capacity;
37                    pData = new T[iCapacity];
38                }
39                
40                ~FixedArray() {
41                    delete pData;
42                    pData = NULL;
43                }
44                
45                inline int size() const { return iSize; }
46                inline int capacity() { return iCapacity; }
47                
48                void add(T element) {
49                    if (iSize >= iCapacity) throw Exception("Array out of bounds");
50                    pData[iSize++] = element;
51                }
52                
53                
54                T increment() {
55                    if (iSize >= iCapacity) throw Exception("Array out of bounds");
56                    return pData[iSize++];
57                }
58                
59                void clear() { iSize = 0; }
60                
61                void copy(const FixedArray<T>& array) {
62                    if(array.size() >= capacity()) throw Exception("Not enough space to copy array");
63                    for (int i = 0; i < array.size(); i++) pData[i] = array[i];
64                    iSize = array.size();
65                }
66                
67                inline T& operator[](int idx) const {
68                    return pData[idx];
69                }
70                
71            private:
72                T*   pData;
73                int  iSize;
74                int  iCapacity;
75        };
76        
77        class SignalUnitRack;
78    
79      /**      /**
80       * A signal unit consist of internal signal generator (like envelope generator,       * A signal unit consist of internal signal generator (like envelope generator,
81       * low frequency oscillator, etc) with a number of generator parameters which       * low frequency oscillator, etc) with a number of generator parameters which
# Line 81  namespace LinuxSampler { Line 129  namespace LinuxSampler {
129                  Parameter(const Parameter& Prm) { Copy(Prm); }                  Parameter(const Parameter& Prm) { Copy(Prm); }
130                  void operator=(const Parameter& Prm) { Copy(Prm); }                  void operator=(const Parameter& Prm) { Copy(Prm); }
131                            
132                  virtual void Copy(const Parameter& Prm) {                  void Copy(const Parameter& Prm) {
133                      if (this == &Prm) return;                      if (this == &Prm) return;
134    
135                      pUnit = Prm.pUnit;                      pUnit = Prm.pUnit;
# Line 115  namespace LinuxSampler { Line 163  namespace LinuxSampler {
163          public:          public:
164              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
165                            
166              SignalUnit() : bActive(false), Level(0.0f), bCalculating(false), uiDelayTrigger(0) { }              SignalUnit(SignalUnitRack* rack): pRack(rack), bActive(false), Level(0.0f), bCalculating(false), uiDelayTrigger(0) { }
167              SignalUnit(const SignalUnit& Unit) { Copy(Unit); }              SignalUnit(const SignalUnit& Unit): pRack(Unit.pRack) { Copy(Unit); }
168              void operator=(const SignalUnit& Unit) { Copy(Unit); }              void operator=(const SignalUnit& Unit) { Copy(Unit); }
169                            
170              virtual void Copy(const SignalUnit& Unit) {              void Copy(const SignalUnit& Unit) {
171                  if (this == &Unit) return;                  if (this == &Unit) return;
172    
173                  bActive = Unit.bActive;                  bActive = Unit.bActive;
# Line 200  namespace LinuxSampler { Line 248  namespace LinuxSampler {
248               */               */
249              virtual uint DelayTrigger() { return uiDelayTrigger; }              virtual uint DelayTrigger() { return uiDelayTrigger; }
250                            
251                /**
252                 * A helper method which checks whether the delay
253                 * stage is finished.
254                 */
255                bool DelayStage();
256                
257          protected:          protected:
258                SignalUnitRack* const pRack;
259    
260              bool   bActive; /* Don't use it to check the active state of the unit!!!              bool   bActive; /* Don't use it to check the active state of the unit!!!
261                               * Use Active() instead! */                               * Use Active() instead! */
262              float  Level;              float  Level;
# Line 213  namespace LinuxSampler { Line 269  namespace LinuxSampler {
269                    
270      };      };
271            
272      class EndpointSignalUnit: virtual public SignalUnit {      class EndpointSignalUnit: public SignalUnit {
273          public:          public:
274                EndpointSignalUnit(SignalUnitRack* rack): SignalUnit(rack) { }
275    
276              /**              /**
277               * Gets the volume modulation value               * Gets the volume modulation value
278               * for the current time step (sample point).               * for the current time step (sample point).
# Line 239  namespace LinuxSampler { Line 297  namespace LinuxSampler {
297               */               */
298              virtual float GetResonance() = 0;              virtual float GetResonance() = 0;
299                            
300              virtual float CalculateFilterCutoff(float cutoff) = 0;              /** Should return value in the range [-100, 100] (L <-> R) */
301                            virtual float GetPan() = 0;
             virtual float CalculatePitch(float pitch) = 0;  
302                            
303              virtual float CalculateResonance(float res) = 0;              virtual float CalculateFilterCutoff(float cutoff) {
304      };                  cutoff *= GetFilterCutoff();
305                        return cutoff > 13500 ? 13500 : cutoff;
   
     class SignalUnitRack;  
   
     template <class O /* The signal unit's owner */>  
     class SignalUnitBase: virtual public SignalUnit {  
         public:  
             SignalUnitBase() : pOwner(NULL) { }  
             SignalUnitBase(const SignalUnitBase& Unit) { Copy(Unit); }  
             void operator=(const SignalUnitBase& Unit) { Copy(Unit); }  
               
             virtual void Copy(const SignalUnitBase& Unit) {  
                 if (this == &Unit) return;  
   
                 pOwner = Unit.pOwner;  
                 SignalUnit::Copy(Unit);  
306              }              }
   
         protected:  
             O* pOwner; // The owner to which this rack belongs.  
               
             SignalUnitRack* GetSignalUnitRack() { return pOwner->GetSignalUnitRack(); }  
           
         public:  
307                            
308                virtual float CalculatePitch(float pitch) {
309                    return GetPitch() * pitch;
310                }
311                            
312              /**              virtual float CalculateResonance(float res) {
313               * The owner of the unit is set by the rack                  return GetResonance() * res;
314               * just before the call to the unit's trigger method.              }
              */  
             void SetOwner(O* Owner) { pOwner = Owner; }  
315                            
316              /**              /** Should return value in the range [0, 127] (L <-> R) */
317               * A helper method which checks whether the delay              virtual uint8_t CaluclatePan(uint8_t pan) {
318               * stage is finished.                  int p = pan + GetPan() * 0.63;
319               */                  if (p < 0) return 0;
320              bool DelayStage() {                  if (p > 127) return 127;
321                  return (DelayTrigger() >= GetSignalUnitRack()->GetCurrentStep());                  return p;
322              }              }
323      };      };
324            
325      /**      /**
326       * Continuous controller signal unit.       * Continuous controller signal unit.
327       * The level of this unit corresponds to the controller changes       * The level of this unit corresponds to the controllers changes
328       * and is normalized to be in the range from -1 to +1.       * and their influences.
329       */       */
330      template<class O>      class CCSignalUnit: public SignalUnit {
331      class CCSignalUnit: public SignalUnitBase<O> {          public:
332          private:              /** Listener which will be notified when the level of the unit is changed. */
333              uint8_t Ctrl; // The number of the MIDI controller which modulates this signal unit.              class Listener {
334                    public:
335                        virtual void ValueChanged(CCSignalUnit* pUnit) = 0;
336                };
337                
338            protected:
339                class CC {
340                    public:
341                        uint8_t   Controller;  ///< MIDI controller number.
342                        uint8_t   Value;       ///< Controller Value.
343                        short int Curve;       ///< specifies the curve type
344                        float     Influence;
345                        
346                        CC(uint8_t Controller = 0, float Influence = 0.0f, short int Curve = -1) {
347                            this->Controller = Controller;
348                            this->Value = 0;
349                            this->Curve = Curve;
350                            this->Influence = Influence;
351                        }
352                        
353                        CC(const CC& cc) { Copy(cc); }
354                        void operator=(const CC& cc) { Copy(cc); }
355                        
356                        void Copy(const CC& cc) {
357                            Controller = cc.Controller;
358                            Value = cc.Value;
359                            Influence = cc.Influence;
360                            Curve = cc.Curve;
361                        }
362                };
363                
364                FixedArray<CC> Ctrls; // The MIDI controllers which modulates this signal unit.
365                Listener* pListener;
366    
367          public:          public:
368              CCSignalUnit(uint8_t Controller) {              
369                  Ctrl = Controller;              CCSignalUnit(SignalUnitRack* rack, Listener* l = NULL): SignalUnit(rack), Ctrls(128) {
370                    pListener = l;
371              }              }
372                            
373              CCSignalUnit(const CCSignalUnit& Unit) { Copy(Unit); }              CCSignalUnit(const CCSignalUnit& Unit): SignalUnit(Unit.pRack), Ctrls(128) { Copy(Unit); }
374              void operator=(const CCSignalUnit& Unit) { Copy(Unit); }              void operator=(const CCSignalUnit& Unit) { Copy(Unit); }
375                            
376              virtual void Copy(const CCSignalUnit& Unit) {              void Copy(const CCSignalUnit& Unit) {
377                  SignalUnitBase<O>::Copy(Unit);                  Ctrls.copy(Unit.Ctrls);
378                  Ctrl = Unit.Ctrl;                  pListener = Unit.pListener;
379                    SignalUnit::Copy(Unit);
380                }
381                
382                void AddCC(uint8_t Controller, float Influence, short int Curve = -1) {
383                    Ctrls.add(CC(Controller, Influence, Curve));
384                }
385                
386                void RemoveAllCCs() {
387                    Ctrls.clear();
388              }              }
389                            
390              virtual void Increment() { }              virtual void Increment() { }
391                            
392                virtual void Trigger() {
393                    Calculate();
394                    bActive = Level != 0;
395                }
396                
397              virtual void ProcessCCEvent(uint8_t Controller, uint8_t Value) {              virtual void ProcessCCEvent(uint8_t Controller, uint8_t Value) {
398                  if (Controller != Ctrl) return;                  bool recalculate = false;
399                                    
400                  // Normalize the value so it belongs to the interval [-1, +1]                  for (int i = 0; i < Ctrls.size(); i++) {
401                  SignalUnitBase<O>::Level = 2 * Value;                      if (Controller != Ctrls[i].Controller) continue;
402                  SignalUnitBase<O>::Level = SignalUnitBase<O>::Level/127.0f - 1.0f;                      if (Ctrls[i].Value == Value) continue;
403                        Ctrls[i].Value = Value;
404                        if (!bActive) bActive = true;
405                        recalculate = true;
406                    }
407                                    
408                  if (!SignalUnitBase<O>::bActive) SignalUnitBase<O>::bActive = true;                  if (recalculate) {
409              }                      Calculate();
410      };                      if (pListener!= NULL) pListener->ValueChanged(this);
411                    }
     /**  
      * Endpoint signal unit.  
      */  
     template<class O>  
     class EndpointSignalUnitBase : public SignalUnitBase<O>, public EndpointSignalUnit {  
         public:  
   
             virtual float CalculateFilterCutoff(float cutoff) {  
                 cutoff *= GetFilterCutoff();  
                 return cutoff > 13500 ? 13500 : cutoff;  
             }  
               
             virtual float CalculatePitch(float pitch) {  
                 return GetPitch() * pitch;  
412              }              }
413                            
414              virtual float CalculateResonance(float res) {              virtual void Calculate() {
415                  return GetResonance() * res;                  Level = 0;
416                    for (int i = 0; i < Ctrls.size(); i++) {
417                        if (Ctrls[i].Value == 0) continue;
418                        Level += (Ctrls[i].Value / 127.0f) * Ctrls[i].Influence;
419                    }
420              }              }
421      };      };
422            

Legend:
Removed from v.2207  
changed lines
  Added in v.2230

  ViewVC Help
Powered by ViewVC