CSL_Core1.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 //#include "ThreadUtilities.h"  // Thread util classes (used only by NullIO)
00038 //#include "ThreadedFrameStream.h"
00039 
00040 //#define CSL_DEBUG         // define this for verbose debugging of call-backs
00041 
00042 namespace csl {             // All this happens in the CSL namespace
00043 
00048 typedef enum {          
00049     kSamples,               
00050     kSpectra,               
00051     kLPCCoeff,              
00052     kIRData,                    
00053     kWavelet,               
00054     kGeometry,              
00055     kUnknown                
00056 } BufferContentType;
00057 
00064 class Buffer {
00065 public:
00066     Buffer(unsigned numChannels = 1, unsigned numFrames = CGestalt::blockSize()); 
00067     ~Buffer();                          
00068                             // public data members  
00069     SampleBufferVector mMonoBuffers;    
00070     unsigned mNumChannels;              
00071     unsigned mNumFrames;                
00072     unsigned mMonoBufferByteSize;       
00073     unsigned mSequence;             
00074     Timestamp mTimestamp;               
00075     BufferContentType mType;                
00076     
00077     bool mAreBuffersAllocated;          
00078     bool mDidIAllocateBuffers;          
00079     bool mIsPopulated;                  
00080     bool mAreBuffersZero;               
00081 
00083     void setSize(unsigned numChannels, unsigned numFrames);
00085     void setSizeOnly(unsigned numChannels, unsigned numFrames);
00086 
00087     void allocateMonoBuffers() throw (MemoryError); 
00088     void freeMonoBuffers();                         
00089     
00090     void zeroBuffers();                 
00091     void fillWith(sample value);            
00092     void copySamplesFrom(Buffer & src) throw (RunTimeError);    
00093     
00095     sample * monoBuffer(unsigned bufNum) { return mMonoBuffers[bufNum]; }
00096     
00098     float rms(unsigned chan);               
00099     float avg(unsigned chan);               
00100     float max(unsigned chan);               
00101     float min(unsigned chan);               
00102     unsigned int zeroX(unsigned chan);  
00103     unsigned int indexOfPeak(unsigned chan);    
00104     unsigned int indexOfPeak(unsigned chan, unsigned low, unsigned hi); 
00105     unsigned int indexOfMin(unsigned chan); 
00106     unsigned int indexOfMin(unsigned chan, unsigned low, unsigned hi);  
00107     void autocorrelation(unsigned chan, sample * result);   
00108 };
00109 
00114 class BufferCMap : public Buffer {
00115 public:
00116     BufferCMap();                           
00117     BufferCMap(unsigned numChannels, unsigned numFrames); 
00118     BufferCMap(unsigned numChannels, unsigned realNumChannels, unsigned numFrames);
00119     ~BufferCMap();                          
00120     
00121     unsigned mRealNumChannels;              
00122     std::vector<unsigned> mChannelMap;      
00123 
00125     sample * monoBuffer(unsigned bufNum) { return mMonoBuffers[mChannelMap[bufNum]]; }
00126 };
00127 
00131 typedef enum {          
00132     kCopy,              
00133     kExpand,            
00134     kIgnore             
00135 } BufferCopyPolicy;
00136 
00137 class RingBuffer;   
00138 
00139 
00154 class UnitGenerator : public Model {
00155 public: 
00157     UnitGenerator(unsigned rate = CGestalt::frameRate(), unsigned chans = 1);   
00158     virtual ~UnitGenerator() { }        
00159 
00160                                     // accessing methods
00161     unsigned frameRate() { return mFrameRate; };            
00162     void setFrameRate(unsigned rate) { mFrameRate = rate; }
00163 
00164     unsigned numChannels() { return mNumChannels; };        
00165     void setNumChannels(unsigned ch) { mNumChannels = ch; }
00166 
00167     BufferCopyPolicy copyPolicy() { return mCopyPolicy; };  
00168     void setCopyPolicy(BufferCopyPolicy ch) { mCopyPolicy = ch; }
00169     
00170 //  string name() { return mName; };                        ///< get/set the receiver's name string
00171 //  void setName(string ch) { mName = ch; }
00172     
00175     virtual void nextBuffer(Buffer & outputBuffer) throw (Exception);
00178     virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (Exception);
00179     
00181     virtual bool isFixed() { return false; };
00183     virtual bool isActive() { return true; };
00185     void addOutput(UnitGenerator * ugen);
00186     void removeOutput(UnitGenerator * ugen);
00187     UGenVector outputs() { return mOutputs; };
00188     
00190     virtual void setValue(sample theValue) { throw LogicError("can't set value of a generator"); };
00191     virtual sample value() { throw LogicError("can't get value of a generator"); };
00192     
00193     virtual void dump();                
00194     
00195 protected:          
00196     unsigned mFrameRate;            
00197     unsigned mNumChannels;          
00198     BufferCopyPolicy mCopyPolicy;   
00199     
00200     UGenVector mOutputs;            
00201     unsigned mNumOutputs;           
00202     unsigned mSequence;         
00203 
00204     RingBuffer * mOutputCache;      
00205 //  string mName;                   ///< my name (used for editors)
00206     
00208     void zeroBuffer(Buffer & outputBuffer, unsigned outBufNum);
00209 };
00210 
00211 
00218 class Port {
00219 public:
00220     Port();                         
00221     Port(UnitGenerator * ug);           
00222     Port(float value);                  
00223     virtual ~Port();                    
00224                             // public data members
00225     UnitGenerator * mUGen;          
00226     Buffer * mBuffer;                   
00227     float mValue;                   
00228     float *mValuePtr;                   
00229     unsigned mPtrIncrement;         
00230 
00231     void checkBuffer() throw (LogicError);  
00232     inline float nextValue();           
00233     void resetPtr();                    
00234     void dump();                        
00235     bool isFixed() { return (mPtrIncrement == 0); };            
00236 };
00237 
00241 inline float Port :: nextValue() {
00242     mValuePtr += mPtrIncrement;     // increment the pointer (mPtrIncrement may be 0)
00243     return *mValuePtr;              // return the value
00244 }
00245 
00246 
00256 class Controllable {
00257 public:     
00258     Controllable() : mInputs() { };     
00259     virtual ~Controllable() { };            
00260     
00261 protected:  
00262     PortMap mInputs;                //< the map of my inputs or controls (used by the mix-in classes)
00263 
00265     void addInput(CSL_MAP_KEY name, UnitGenerator & ugen);
00267     void addInput(CSL_MAP_KEY name, float value);
00270     void pullInput(Port * thePort, unsigned numFrames) throw (Exception);
00271     
00272     virtual void dump();                
00273 };
00274 
00280 class Phased : public virtual Controllable {
00281 public:
00282     Phased();                           
00283     Phased(UnitGenerator & frequency);  
00284     Phased(float frequency);
00285     Phased(float frequency, float phase);   
00286     ~Phased();                      
00287     
00289     void setFrequency(UnitGenerator & frequency);
00290     void setFrequency(float frequency);
00291     void setPhase(float phase) { mPhase = phase; };
00292 
00293 protected:
00294     float mPhase;                   
00295 };
00296 
00301 
00303 
00304 #define DECLARE_PHASED_CONTROLS                     \
00305     Port * freqPort = mInputs[CSL_FREQUENCY];               \
00306     float freqValue
00307 
00310 
00311 #define LOAD_PHASED_CONTROLS                            \
00312     Controllable :: pullInput(freqPort, numFrames);         \
00313     freqValue = freqPort->nextValue()
00314 
00316 
00317 #define UPDATE_PHASED_CONTROLS                      \
00318     freqValue = freqPort->nextValue()
00319     
00320 #define CHECK_UPDATE_PHASED_CONTROLS                    \
00321     if (freqPort)                                           \
00322         freqValue = freqPort->nextValue()
00323 
00330 class Scalable : public virtual Controllable {
00331 public:     
00332     Scalable();                     
00333     Scalable(float scale);                          
00334     Scalable(float scale, float offset);                
00335     Scalable(UnitGenerator & scale, float offset);  
00336     Scalable(UnitGenerator & scale, UnitGenerator & offset);    
00337     ~Scalable();                        
00338     
00339                                     // accessors
00340     void setScale(UnitGenerator & scale);       
00341     void setScale(float scale);
00342 
00343     void setOffset(UnitGenerator & offset); 
00344     void setOffset(float offset);
00345 };
00346 
00349 
00351 
00352 #define DECLARE_SCALABLE_CONTROLS                       \
00353     Port * scalePort = mInputs[CSL_SCALE];                  \
00354     Port * offsetPort = mInputs[CSL_OFFSET];                \
00355     float scaleValue, offsetValue
00356 
00358 
00359 #define LOAD_SCALABLE_CONTROLS                      \
00360     Controllable :: pullInput(scalePort, numFrames);        \
00361     scaleValue = scalePort->nextValue();                    \
00362     Controllable :: pullInput(offsetPort, numFrames);       \
00363     offsetValue = offsetPort->nextValue()
00364 
00365 // Update the scale/offset-related values in the loop
00366 
00367 #define UPDATE_SCALABLE_CONTROLS                        \
00368     scaleValue = scalePort->nextValue();                    \
00369     offsetValue = offsetPort->nextValue()
00370 
00371 #define CHECK_UPDATE_SCALABLE_CONTROLS              \
00372     if (scalePort)                                          \
00373         scaleValue = scalePort->nextValue();                \
00374     if (offsetPort)                                     \
00375         offsetValue = offsetPort->nextValue()
00376 
00381 class Effect : public UnitGenerator, public virtual Controllable {
00382 public:
00383     Effect();                               
00384     Effect(UnitGenerator & input);      
00385 
00386     bool isActive() { return (mInputs[CSL_INPUT]->mUGen->isActive()); };
00387     virtual unsigned numChannels() { return (mInputs[CSL_INPUT]->mUGen->numChannels()); };
00388 
00389     void setInput(UnitGenerator & inp); 
00390 
00391     Port * inPort() { return mInputs[CSL_INPUT]; };
00392 
00393     virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (Exception);
00394 protected:
00395     sample *mInputPtr;                  
00396 
00397     void pullInput(Buffer & outputBuffer) throw (Exception);
00398     void pullInput(unsigned numFrames) throw (Exception);
00399 };
00400 
00401 
00405 class Writeable {
00406 public:                             
00407     virtual void writeBuffer(Buffer& inputBuffer) throw(Exception);
00408     virtual ~Writeable() {};
00409 
00410 protected:                          
00411     virtual void writeBuffer(Buffer & inputBuffer, unsigned bufNum) throw(Exception);
00412 };
00413 
00417 typedef enum {
00418     kPositionStart,
00419     kPositionCurrent,
00420     kPositionEnd
00421 } SeekPosition;
00422 
00426 class Seekable {
00427 public:
00428     Seekable() : mCurrentFrame(0) { }   
00429     virtual ~Seekable() {};
00430     
00431     unsigned mCurrentFrame;             
00432     
00434     virtual unsigned seekTo(int position, SeekPosition whence) throw(Exception) = 0;
00435     virtual void reset() throw(Exception);  
00436     virtual unsigned duration() const = 0;  
00437 };
00438 
00442 class Cacheable {
00443 public:
00444     Cacheable() : mUseCache(false) { }  ;   
00445     Cacheable(bool uC) : mUseCache(uC) { };
00446 
00447     bool mUseCache;                     
00448 };
00449 
00450 
00452 
00460 class FanOut : public Effect {
00461 public:
00462     FanOut(UnitGenerator & in, unsigned taps);  
00463     ~FanOut() { };
00464 
00465     virtual void nextBuffer(Buffer & outputBuffer) throw(Exception);
00466 
00467 protected:
00468     Buffer mBuffer;         
00469     unsigned mOutputs;      
00470     unsigned mCurrent;      
00471 };
00472 
00476 class Splitter : public FanOut {
00477 public:
00478     Splitter(UnitGenerator & in, unsigned taps);    
00479     ~Splitter() { };
00480 
00481     void nextBuffer(Buffer & outputBuffer) throw(Exception);
00482 };
00483 
00487 class Joiner : public Effect {  
00488 public:                                 
00489     Joiner() { };                           
00490     Joiner(UnitGenerator & in1, UnitGenerator & in2);
00491     ~Joiner() { };
00492 
00493     void nextBuffer(Buffer & outputBuffer) throw(Exception);
00494     void addInput(UnitGenerator & in);  
00495 
00496 protected:
00497     std::vector<UnitGenerator *>mInputs;    
00498 };
00499 
00500 
00501 // Support for the IO classes
00502 
00503 #define DO_TIMING               // Do the timing statistics
00504 
00505 #ifdef DO_TIMING                    // Here are the macros and globals for the timing code
00506 
00507 #ifndef CSL_WINDOWS         // for UNIX-like platforms
00508 
00509 #include <sys/time.h>
00510 #define GET_TIME(val) if (gettimeofday(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00511 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00512 
00513 #else                           // else for MS-Windows
00514 
00515 #include <Winsock2.h>
00516 #include <winsock.h>
00517 #include <time.h>
00518 int getSysTime(timeval *val, void * e);
00519 #define GET_TIME(val) if (getSysTime(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00520 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00521 
00522 #endif                          // platform switch
00523 
00524 #endif                          // DO_TIMING
00525 
00526 #define DEFAULT_LOGGINGPERIOD 4         // print statistics every 5 seconds
00527 
00532 class IO {                                  // no superclass
00533 public:                                     
00535     IO() : mGraph(NULL), mNumFramesPlayed(0), mSequence(0), mLoggingPeriod(CGestalt::loggingPeriod()) { };
00536     virtual ~IO() { };
00537     
00538     virtual void open() throw(Exception) { };   
00539     virtual void close() throw(Exception) { };
00540     virtual void start() throw(Exception) { };
00541     virtual void stop() throw(Exception) { };
00543     void setRoot(UnitGenerator & root);
00544     void clearRoot();
00545                                 
00546     virtual Buffer & getInput() throw(Exception) = 0;   
00547     virtual Buffer & getInput(unsigned numFrames, unsigned numChannels) throw(Exception) = 0;   
00548     unsigned getAndIncrementSequence();     
00549     
00550     UnitGenerator * mGraph;                 
00551     Buffer mInputBuffer;                        
00552     Buffer mOutputBuffer;                   
00553 
00554     unsigned mNumFramesPlayed;              
00555     unsigned mSequence;                 
00556     unsigned mLoggingPeriod;                    
00557     unsigned mNumInChannels;                
00558     unsigned mNumOutChannels;               
00559     unsigned mNumRealInChannels;            
00560     unsigned mNumRealOutChannels;           
00561     
00562 #ifdef DO_TIMING                                // This is for the performance timing code
00563     struct timeval mThen, mNow;             
00564     long mTimeVals, mThisSec, mTimeSum; 
00565 
00566     void printTimeStatistics(struct timeval * tthen, struct timeval * tnow, long * tsecond, long * ttimeSum, long * ttimeVals);
00567 #endif
00568 };
00569 
00570 }   // end of namespace
00571 
00572 #endif CSL_CORE_H
00573 

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