CSL_Core.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #ifndef CSL_CORE_H          // This is in case you include this twice
00032 #define CSL_CORE_H
00033 
00034 #include "CSL_Types.h"      // CSL type definitions and central macros, Observer classes
00035 #include "CSL_Exceptions.h" // CSL exception hierarchy
00036 #include "CGestalt.h"           // System constants class
00037 
00038 // #define CSL_DEBUG        // define this for verbose debugging of constructors and call-backs
00039 
00040 namespace csl {             // All this happens in the CSL namespace
00041 
00042 
00047 #ifdef CSL_ENUMS
00048 typedef enum {          
00049     kSamples,               
00050     kSpectra,               
00051     kLPCCoeff,              
00052     kIRData,                    
00053     kWavelet,               
00054     kGeometry,              
00055     kUnknown                
00056 } BufferContentType;
00057 #else
00058     #define kSamples 0
00059     #define kSpectra 1
00060     #define kLPCCoeff 2
00061     #define kIRData 3
00062     #define kWavelet 4
00063     #define kGeometry 5
00064     #define kUnknown 6
00065     typedef int BufferContentType;
00066 #endif
00067 
00075 class Buffer {
00076 public:
00077     Buffer(unsigned numChannels = 1, unsigned numFrames = CGestalt::blockSize()); 
00078     ~Buffer();                          
00079                             // public data members  
00080     SampleBufferVector mMonoBuffers;    
00081     unsigned mNumChannels;              
00082     unsigned mNumFrames;                
00083     unsigned mMonoBufferByteSize;       
00084     unsigned mSequence;             
00085     Timestamp mTimestamp;               
00086     
00087     bool mAreBuffersAllocated;          
00088     bool mDidIAllocateBuffers;          
00089     bool mIsPopulated;                  
00090     bool mAreBuffersZero;               
00091     BufferContentType mType;                
00092 
00093     void setSize(unsigned numChannels, unsigned numFrames);
00095     void setSizeOnly(unsigned numChannels, unsigned numFrames);
00096 
00097     void allocateMonoBuffers() throw (MemoryError); 
00098     void freeMonoBuffers();                         
00099     
00100     void zeroBuffers();                 
00101     void fillWith(sample value);            
00102     void copySamplesFrom(Buffer & src) throw (RunTimeError);    
00103     
00105     sample * monoBuffer(unsigned bufNum) { return mMonoBuffers[bufNum]; }
00106     
00108     float rms(unsigned chan);               
00109     float avg(unsigned chan);               
00110     float max(unsigned chan);               
00111     float min(unsigned chan);               
00112     unsigned int zeroX(unsigned chan);  
00113     unsigned int indexOfPeak(unsigned chan);    
00114     unsigned int indexOfPeak(unsigned chan, unsigned low, unsigned hi); 
00115     unsigned int indexOfMin(unsigned chan); 
00116     unsigned int indexOfMin(unsigned chan, unsigned low, unsigned hi);  
00117     void autocorrelation(unsigned chan, sample * result);   
00118 };
00119 
00124 class BufferCMap : public Buffer {
00125 public:
00126     BufferCMap();                           
00127     BufferCMap(unsigned numChannels, unsigned numFrames); 
00128     BufferCMap(unsigned numChannels, unsigned realNumChannels, unsigned numFrames);
00129     ~BufferCMap();                          
00130     
00131     unsigned mRealNumChannels;              
00132     std::vector<unsigned> mChannelMap;      
00133 
00135     sample * monoBuffer(unsigned bufNum) { return mMonoBuffers[mChannelMap[bufNum]]; }
00136 };
00137 
00141 #ifdef CSL_ENUMS
00142 typedef enum {          
00143     kCopy,              
00144     kExpand,            
00145     kIgnore             
00146 } BufferCopyPolicy;
00147 #else
00148     #define kCopy 0
00149     #define kExpand 1
00150     #define kIgnore 2
00151     typedef int BufferCopyPolicy;
00152 #endif
00153 
00154 class RingBuffer;   
00155 
00156 
00172 class UnitGenerator : public Model {
00173 public: 
00175     UnitGenerator(unsigned rate = CGestalt::frameRate(), unsigned chans = 1);   
00176     virtual ~UnitGenerator() { }        
00177 
00178                                     // accessing methods
00179     unsigned frameRate() { return mFrameRate; };            
00180     void setFrameRate(unsigned rate) { mFrameRate = rate; }
00181 
00182     unsigned numChannels() { return mNumChannels; };        
00183     void setNumChannels(unsigned ch) { mNumChannels = ch; }
00184 
00185     BufferCopyPolicy copyPolicy() { return mCopyPolicy; };  
00186     void setCopyPolicy(BufferCopyPolicy ch) { mCopyPolicy = ch; }
00187     
00188 //  string name() { return mName; };                        ///< get/set the receiver's name string
00189 //  void setName(string ch) { mName = ch; }
00190     
00193     virtual void nextBuffer(Buffer & outputBuffer) throw (CException);
00196     virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
00197     
00199     virtual bool isFixed() { return false; };
00201     virtual bool isActive() { return true; };
00203     void addOutput(UnitGenerator * ugen);
00204     void removeOutput(UnitGenerator * ugen);
00205     UGenVector outputs() { return mOutputs; };
00206     
00208     virtual void setValue(sample theValue) { throw LogicError("can't set value of a generator"); };
00209     virtual sample value() { throw LogicError("can't get value of a generator"); };
00210     
00211     virtual void dump();                
00212 
00213 protected:          
00214     unsigned mFrameRate;            
00215     unsigned mNumChannels;          
00216     BufferCopyPolicy mCopyPolicy;   
00217     UGenVector mOutputs;            
00218     unsigned mNumOutputs;           
00219     unsigned mSequence;         
00220 
00221     RingBuffer * mOutputCache;      
00222 //  string mName;                   ///< my name (used for editors)
00223     
00225     void zeroBuffer(Buffer & outputBuffer, unsigned outBufNum);
00226 };
00227 
00234 
00235 class Port {
00236 public:
00237     Port();                         
00238     Port(UnitGenerator * ug);           
00239     Port(float value);                  
00240     virtual ~Port();                    
00241                             // public data members
00242     UnitGenerator * mUGen;          
00243     Buffer * mBuffer;                   
00244     float mValue;                   
00245     float *mValuePtr;                   
00246     unsigned mPtrIncrement;         
00247     unsigned mValueIndex;           
00248 
00249     void checkBuffer() throw (LogicError);  
00250     inline float nextValue();           
00251     inline void nextFrame(sample * where);
00252     inline bool Port :: isReady();
00253     void resetPtr();                    
00254     virtual bool isActive();            
00255     void dump();                        
00256     bool isFixed() { return (mPtrIncrement == 0); };            
00257 };
00258 
00259 // Answer the next value (dynamic or constant) as a fast inline function
00260 
00261 inline sample Port :: nextValue() {
00262     mValuePtr += mPtrIncrement;     // increment the pointer (mPtrIncrement may be 0)
00263     return *mValuePtr;              // return the value
00264 }
00265 
00266 // Write the next n-dimensional sample frame
00267 
00268 inline void Port :: nextFrame(sample * where) {
00269     for (unsigned i = 0; i < mBuffer->mNumChannels; i++)
00270         *where++ = mBuffer->mMonoBuffers[i][mValueIndex];
00271     mValueIndex++;      // increment the counter (an unsigned, initially 0)
00272 }
00273 
00274 // Answer whether the give port is ready (i.e., has its UGen or scalar value set up and primed)
00275 
00276 inline bool Port :: isReady() {
00277     return (mValuePtr != 0);
00278 }
00279 
00289 class Controllable {
00290 public:     
00291     Controllable() : mInputs() { };     
00292     virtual ~Controllable() { };            
00293     
00294 protected:  
00295     PortMap mInputs;                //< the map of my inputs or controls (used by the mix-in classes)
00296 
00298     void addInput(CSL_MAP_KEY name, UnitGenerator & ugen);
00300     void addInput(CSL_MAP_KEY name, float value);
00303     void pullInput(Port * thePort, unsigned numFrames) throw (CException);
00304     
00305     virtual void dump();                
00306 };
00307 
00313 class Phased : public virtual Controllable {
00314 public:
00315     Phased();                           
00316     Phased(UnitGenerator & frequency);  
00317     Phased(float frequency);
00318     Phased(float frequency, float phase);   
00319     ~Phased();                          
00320     
00322     void setFrequency(UnitGenerator & frequency);
00323     void setFrequency(float frequency);
00324     void setPhase(float phase) { mPhase = phase; };
00325 
00326 protected:
00327     float mPhase;                       
00328 };
00329 
00334 
00336 
00337 #define DECLARE_PHASED_CONTROLS                     \
00338     Port * freqPort = mInputs[CSL_FREQUENCY];               \
00339     float freqValue
00340 
00343 
00344 #define LOAD_PHASED_CONTROLS                            \
00345     Controllable :: pullInput(freqPort, numFrames);         \
00346     freqValue = freqPort->nextValue()
00347 
00349 
00350 #define UPDATE_PHASED_CONTROLS                      \
00351     freqValue = freqPort->nextValue()
00352     
00353 #define CHECK_UPDATE_PHASED_CONTROLS                    \
00354     if (freqPort)                                           \
00355         freqValue = freqPort->nextValue()
00356 
00363 class Scalable : public virtual Controllable {
00364 public:     
00365     Scalable();                     
00366     Scalable(float scale);                          
00367     Scalable(float scale, float offset);                
00368     Scalable(UnitGenerator & scale, float offset);  
00369     Scalable(UnitGenerator & scale, UnitGenerator & offset);    
00370     ~Scalable();                        
00371     
00372                                     // accessors
00373     void setScale(UnitGenerator & scale);       
00374     void setScale(float scale);
00375 
00376     void setOffset(UnitGenerator & offset); 
00377     void setOffset(float offset);
00378 };
00379 
00382 
00384 
00385 #define DECLARE_SCALABLE_CONTROLS                       \
00386     Port * scalePort = mInputs[CSL_SCALE];                  \
00387     Port * offsetPort = mInputs[CSL_OFFSET];                \
00388     float scaleValue, offsetValue
00389 
00391 
00392 #define LOAD_SCALABLE_CONTROLS                      \
00393     Controllable :: pullInput(scalePort, numFrames);        \
00394     scaleValue = scalePort->nextValue();                    \
00395     Controllable :: pullInput(offsetPort, numFrames);       \
00396     offsetValue = offsetPort->nextValue()
00397 
00398 // Update the scale/offset-related values in the loop
00399 
00400 #define UPDATE_SCALABLE_CONTROLS                        \
00401     scaleValue = scalePort->nextValue();                    \
00402     offsetValue = offsetPort->nextValue()
00403 
00404 #define CHECK_UPDATE_SCALABLE_CONTROLS              \
00405     if (scalePort)                                          \
00406         scaleValue = scalePort->nextValue();                \
00407     if (offsetPort)                                     \
00408         offsetValue = offsetPort->nextValue()
00409 
00414 class Effect : public UnitGenerator, public virtual Controllable {
00415 public:
00416     Effect();                               
00417     Effect(UnitGenerator & input);      
00418 
00419     bool isActive() { return (mInputs[CSL_INPUT]->isActive()); };
00420 
00421     void setInput(UnitGenerator & inp); 
00422 //  UnitGenerator *input() { return mInputs[CSL_INPUT]->mUGen; }
00423 
00424 protected:
00425     sample *mInputPtr;                  
00426 
00427     void pullInput(Buffer & outputBuffer) throw (CException);
00428     void pullInput(unsigned numFrames) throw (CException);
00430     Port * inPort() { return mInputs[CSL_INPUT]; };
00431 };
00432 
00433 
00437 class Writeable {
00438 public:                             
00439     virtual void writeBuffer(Buffer& inputBuffer) throw(CException);
00440 
00441 protected:                          
00442     virtual void writeBuffer(Buffer & inputBuffer, unsigned bufNum) throw(CException);
00443 };
00444 
00445 
00449 #ifdef CSL_ENUMS
00450 typedef enum {
00451     kPositionStart,
00452     kPositionCurrent,
00453     kPositionEnd
00454 } SeekPosition;
00455 #else
00456     #define kPositionStart 0
00457     #define kPositionCurrent 1
00458     #define kPositionEnd 2
00459     typedef int SeekPosition;
00460 #endif
00461 
00465 class Seekable {
00466 public:
00467     Seekable() : mCurrentFrame(0) { }   
00468 
00469     unsigned mCurrentFrame;             
00470     
00472     virtual unsigned seekTo(int position, SeekPosition whence) throw(CException) = 0;
00473     virtual void reset() throw(CException); 
00474     virtual unsigned duration() const = 0;  
00475 };
00476 
00480 class Cacheable {
00481 public:
00482     Cacheable() : mUseCache(false) { }  ;   
00483     Cacheable(bool uC) : mUseCache(uC) { };
00484 
00485     bool mUseCache;                     
00486 };
00487 
00488 
00490 
00498 class FanOut : public Effect {
00499 public:
00500     FanOut(UnitGenerator & in, unsigned taps);  
00501     ~FanOut() { };
00502 
00503     virtual void nextBuffer(Buffer & outputBuffer) throw(CException);
00504 
00505 protected:
00506     Buffer mBuffer;         
00507     unsigned mOutputs;      
00508     unsigned mCurrent;      
00509 };
00510 
00514 class Splitter : public FanOut {
00515 public:
00516     Splitter(UnitGenerator & in, unsigned taps);    
00517     ~Splitter() { };
00518 
00519     void nextBuffer(Buffer & outputBuffer) throw(CException);
00520 };
00521 
00525 class Joiner : public Effect {  
00526 public:                                 
00527     Joiner() { };                           
00528     Joiner(UnitGenerator & in1, UnitGenerator & in2);
00529     ~Joiner() { };
00530 
00531     void nextBuffer(Buffer & outputBuffer) throw(CException);
00532     void addInput(UnitGenerator & in);  
00533 
00534 protected:
00535     std::vector<UnitGenerator *>mInputs;    
00536 };
00537 
00538 
00539 // Support for the IO classes
00540 
00541 #ifndef CSL_WINDOWS
00542 #define DO_TIMING               // Do the timing statistics
00543 #endif CSL_WINDOWS
00544 
00545 #ifdef CSL_WINDOWS
00546 
00547 #ifdef DO_TIMING                    // Here are the macros and globals for the timing code
00548 #include <Winsock2.h>
00549 #include <winsock.h>
00550 #include <time.h>
00551 
00552 int getSysTime(timeval *val, void * e);
00553 
00554 #define GET_TIME(val) if (getSysTime(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00555 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00556 #endif
00557 
00558 #else                           // other platforms
00559 
00560 #ifdef DO_TIMING                    // Here are the macros and globals for the timing code
00561 #include <sys/time.h>
00562 #define GET_TIME(val) if (gettimeofday(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00563 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00564 
00565 #endif                          // other platforms
00566 
00567 #endif                          // DO_TIMING
00568 
00573 class IO {                                  // no superclass
00574 public:                                     
00576     IO() : mGraph(NULL), mNumFramesPlayed(0), mSequence(0), mLoggingPeriod(CGestalt::loggingPeriod()) { };
00577     virtual ~IO() { };
00578 
00579 //  static IO * theInstance() { return mInstance; };    ///< Access the singleton instance
00580 
00581     virtual void open() throw(CException) { };  
00582     virtual void close() throw(CException) { };
00583     virtual void start() throw(CException) { };
00584     virtual void stop() throw(CException) { };
00586     void setRoot(UnitGenerator & root);
00587     void clearRoot();
00588 
00589     virtual Buffer & getInput() throw(CException) = 0;  
00590     virtual Buffer & getInput(unsigned numFrames, unsigned numChannels) throw(CException) = 0;  
00591     unsigned getAndIncrementSequence();     
00592     
00593     UnitGenerator * mGraph;                 
00594     Buffer mInputBuffer;                        
00595     Buffer mOutputBuffer;                   
00596 
00597     unsigned mNumFramesPlayed;              
00598     unsigned mSequence;                 
00599     unsigned mLoggingPeriod;                    
00600     unsigned mNumInChannels;                // # inputs
00601     unsigned mNumOutChannels;               // # outputs
00602     unsigned mNumRealInChannels;            // # physical inputs
00603     unsigned mNumRealOutChannels;           // # physical outputs
00604 
00605 #ifdef DO_TIMING                                // This is for the performance timing code
00606     struct timeval mThen, mNow;             
00607     long mTimeVals, mThisSec, mTimeSum; 
00608 
00609     void printTimeStatistics(struct timeval * tthen, struct timeval * tnow, long * tsecond, long * ttimeSum, long * ttimeVals);
00610 #endif
00611 
00612 };
00613 
00614 }   // end of namespace
00615 
00616 #endif CSL_CORE_H

Generated on Fri Apr 6 20:18:12 2007 for CSL by  doxygen 1.4.5-20051010