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 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 #ifndef CSL_CORE_H          // This is in case you try to include this twice
00040 #define CSL_CORE_H
00041 
00042 #include "CSL_Types.h"      // CSL type definitions and central macros, Observer classes
00043 #include "CSL_Exceptions.h" // CSL exception hierarchy
00044 #include "CGestalt.h"       // System constants class
00045 
00046 namespace csl {             // All this happens in the CSL namespace
00047 
00052 
00053 #ifdef CSL_ENUMS
00054 typedef enum {
00055     kSamples,               
00056     kSpectra,               
00057     kLPCCoeff,              
00058     kIRData,                
00059     kWavelet,               
00060     kGeometry,              
00061     kUnknown                
00062 } BufferContentType;
00063 #else
00064     #define kSamples 0
00065     #define kSpectra 1
00066     #define kLPCCoeff 2
00067     #define kIRData 3
00068     #define kWavelet 4
00069     #define kGeometry 5
00070     #define kUnknown 6
00071     typedef int BufferContentType;
00072 #endif
00073 
00085 
00086 class Buffer {
00087 public:                                 
00088     Buffer(unsigned numChannels = 1, unsigned numFrames = CGestalt::blockSize()); 
00089     ~Buffer();                          
00090     
00091                                     // public data members  
00092     SampleBufferVector mBuffers;        
00093     unsigned mNumChannels;              
00094     unsigned mNumFrames;                
00095     unsigned mMonoBufferByteSize;       
00096     unsigned mSequence;                 
00097     Timestamp mTimestamp;               
00098 
00099     bool mAreBuffersAllocated;          
00100     bool mDidIAllocateBuffers;          
00101     bool mIsPopulated;                  
00102     bool mAreBuffersZero;               
00103     BufferContentType mType;            
00104 
00105     void setSize(unsigned numChannels, unsigned numFrames);
00107     void setSizeOnly(unsigned numChannels, unsigned numFrames);
00108 
00109     void checkBuffers() throw (MemoryError);    
00110     void allocateBuffers() throw (MemoryError); 
00111     void freeBuffers();                         
00112 
00113     void zeroBuffers();                     
00114     void fillWith(sample value);            
00115     void copyFrom(Buffer & src) throw (RunTimeError);           
00116     void copySamplesFrom(Buffer & src) throw (RunTimeError);    
00117 
00119     SampleBuffer monoBuffer(unsigned bufNum) { return mBuffers[bufNum]; }
00120 
00123 
00124 #ifdef CSL_DSP_BUFFER                       
00125     float rms(unsigned chan);               
00126     float avg(unsigned chan);               
00127     float max(unsigned chan);               
00128     float min(unsigned chan);               
00129     unsigned int zeroX(unsigned chan);      
00130     unsigned int indexOfPeak(unsigned chan);                            
00131     unsigned int indexOfPeak(unsigned chan, unsigned low, unsigned hi); 
00132     unsigned int indexOfMin(unsigned chan);                             
00133     unsigned int indexOfMin(unsigned chan, unsigned low, unsigned hi);  
00134     void autocorrelation(unsigned chan, SampleBuffer result);           
00135 #endif
00136 };
00137 
00142 
00143 class BufferCMap : public Buffer {
00144 public:
00145     BufferCMap();                           
00146     BufferCMap(unsigned numChannels, unsigned numFrames); 
00147     BufferCMap(unsigned numChannels, unsigned realNumChannels, unsigned numFrames);
00148     ~BufferCMap();                          
00149 
00150     unsigned mRealNumChannels;              
00151     std::vector<int> mChannelMap;           
00152 
00154     SampleBuffer monoBuffer(unsigned bufNum) { return mBuffers[mChannelMap[bufNum]]; }
00155 };
00156 
00160 
00161 #ifdef CSL_ENUMS
00162 typedef enum {
00163     kCopy,              
00164     kExpand,            
00165     kIgnore             
00166 } BufferCopyPolicy;
00167 #else
00168     #define kCopy 0
00169     #define kExpand 1
00170     #define kIgnore 2
00171     typedef int BufferCopyPolicy;
00172 #endif
00173 
00174 class RingBuffer;   
00175 
00192 
00193 class UnitGenerator : public Model {
00194 public:
00197     UnitGenerator(unsigned rate = CGestalt::frameRate(), unsigned chans = 1);   
00198     virtual ~UnitGenerator() { }        
00199 
00200                                         // accessing methods
00201     unsigned frameRate() { return mFrameRate; };                
00202     void setFrameRate(unsigned rate) { mFrameRate = rate; }
00203 
00204     virtual unsigned numChannels() { return mNumChannels; };    
00205     void setNumChannels(unsigned ch) { mNumChannels = ch; }
00206 
00207     BufferCopyPolicy copyPolicy() { return mCopyPolicy; };      
00208     void setCopyPolicy(BufferCopyPolicy ch) { mCopyPolicy = ch; }
00209 
00210     string * name() { return mName; };                          
00211     void setName(string ch) { mName = &ch; }
00212 
00215     virtual void nextBuffer(Buffer & outputBuffer) throw (CException);
00216     
00219     virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
00220 
00222     virtual bool isFixed() { return false; };
00224     virtual bool isActive() { return true; };
00226     void addOutput(UnitGenerator * ugen);
00227     void removeOutput(UnitGenerator * ugen);
00228     UGenVector outputs() { return mOutputs; };
00229 
00231     virtual void setValue(sample theValue) { throw LogicError("can't set value of a generator"); };
00232     virtual sample value() { throw LogicError("can't get value of a generator"); };
00233 
00234     virtual void dump();            
00235 
00236 protected:              // My data members
00237     unsigned mFrameRate;            
00238     unsigned mNumChannels;          
00239     BufferCopyPolicy mCopyPolicy;   
00240     UGenVector mOutputs;            
00241     unsigned mNumOutputs;           
00242     RingBuffer * mOutputCache;      
00243     unsigned mSequence;             
00244     string * mName;                 
00245 
00246     void zeroBuffer(Buffer & outputBuffer, unsigned outBufNum);
00247 };
00248 
00256 
00257 class Port {
00258 public:
00259     Port();                             
00260     Port(UnitGenerator * ug);           
00261     Port(float value);                  
00262     virtual ~Port();                    
00263 
00264                                         // public data members
00265     UnitGenerator * mUGen;              
00266     Buffer * mBuffer;                   
00267     float mValue;                       
00268     float *mValuePtr;                   
00269     unsigned mPtrIncrement;             
00270     unsigned mValueIndex;               
00271 
00272     void checkBuffer() throw (LogicError);  
00273     inline float nextValue();               
00274     inline void nextFrame(SampleBuffer where);
00275     inline bool isReady();
00276     void resetPtr();                    
00277     virtual bool isActive();            
00278     void dump();                        
00279     bool isFixed() { return (mPtrIncrement == 0); };    
00280 };
00281 
00282 // Answer the next value (dynamic or constant) as a fast inline function
00283 
00284 inline sample Port::nextValue() {
00285     mValuePtr += mPtrIncrement;         // increment the pointer (mPtrIncrement may be 0)
00286     return *mValuePtr;                  // return the value
00287 }
00288 
00289 // Write the next n-dimensional sample frame
00290 
00291 inline void Port::nextFrame(SampleBuffer where) {
00292     for (unsigned i = 0; i < mBuffer->mNumChannels; i++)
00293         *where++ = mBuffer->mBuffers[i][mValueIndex];
00294     mValueIndex++;                      // increment the counter (an unsigned, initially 0)
00295 }
00296 
00297 // Answer whether the give port is ready (i.e., has its UGen or scalar value set up and primed)
00298 
00299 inline bool Port::isReady() {
00300     return (mValuePtr != 0);
00301 }
00302 
00313 
00314 class Controllable {
00315 public:
00316     Controllable() : mInputs() { };         
00317     virtual ~Controllable() { };            
00318 
00319     Port * getPort(CSL_MAP_KEY name);
00320 protected:
00321     PortMap mInputs;                        
00322 
00324     void addInput(CSL_MAP_KEY name, UnitGenerator & ugen);
00326     void addInput(CSL_MAP_KEY name, float value);
00329     void pullInput(Port * thePort, unsigned numFrames) throw (CException);
00330     void pullInput(Port * thePort, Buffer & theBuffer) throw (CException);
00331 
00332     virtual void dump();                    
00333 };
00334 
00342 
00343 class Scalable : public virtual Controllable {
00344 public:
00345     Scalable();                                     
00346     Scalable(float scale);                          
00347     Scalable(float scale, float offset);            
00348     Scalable(UnitGenerator & scale, float offset);  
00349     Scalable(UnitGenerator & scale, UnitGenerator & offset);    
00350     ~Scalable();                                    
00351 
00352                                                     // accessors
00353     void setScale(UnitGenerator & scale);           
00354     void setScale(float scale);
00355 
00356     void setOffset(UnitGenerator & offset);         
00357     void setOffset(float offset);
00358 };
00359 
00362 
00364 
00365 #define DECLARE_SCALABLE_CONTROLS                           \
00366     Port * scalePort = mInputs[CSL_SCALE];                  \
00367     Port * offsetPort = mInputs[CSL_OFFSET];                \
00368     float scaleValue, offsetValue
00369 
00371 
00372 #define LOAD_SCALABLE_CONTROLS                              \
00373     Controllable::pullInput(scalePort, numFrames);          \
00374     scaleValue = scalePort->nextValue();                    \
00375     Controllable::pullInput(offsetPort, numFrames);         \
00376     offsetValue = offsetPort->nextValue()
00377 
00378 // Update the scale/offset-related values in the loop
00379 
00380 #define UPDATE_SCALABLE_CONTROLS                            \
00381     scaleValue = scalePort->nextValue();                    \
00382     offsetValue = offsetPort->nextValue()
00383 
00384 #define CHECK_UPDATE_SCALABLE_CONTROLS                      \
00385     if (scalePort)                                          \
00386         scaleValue = scalePort->nextValue();                \
00387     if (offsetPort)                                         \
00388         offsetValue = offsetPort->nextValue()
00389 
00395 
00396 class Effect : public UnitGenerator, public virtual Controllable {
00397 public:
00398     Effect();                                   
00399     Effect(UnitGenerator & input);              
00400 
00401     bool isActive();
00402 
00403     void setInput(UnitGenerator & inp);         
00404 //  UnitGenerator *input() { return mInputs[CSL_INPUT]->mUGen; }    // no getter for now
00405     bool isInline;                              
00406     void setInline() { isInline = true; }       
00407     
00408 protected:
00409     SampleBuffer mInputPtr;                     
00410 
00411     void pullInput(Buffer & outputBuffer) throw (CException);
00412     void pullInput(unsigned numFrames) throw (CException);
00414     inline Port * inPort() { return mInputs[CSL_INPUT]; };
00415 };
00416 
00423 
00424 class Phased : public virtual Controllable {
00425 public:
00426     Phased();                                       
00427     Phased(float frequency, float phase = 0);       
00428     Phased(UnitGenerator & freq, float phase = 0);  
00429     ~Phased();                                      
00430 
00432     void setFrequency(UnitGenerator & frequency);
00433     void setFrequency(float frequency);
00434     void setPhase(float phase) { mPhase = phase; };
00435 
00436 protected:
00437     float mPhase;                                   
00438 };
00439 
00444 
00446 
00447 #define DECLARE_PHASED_CONTROLS                             \
00448     Port * freqPort = mInputs[CSL_FREQUENCY];               \
00449     float freqValue
00450 
00454 
00455 #define LOAD_PHASED_CONTROLS                                \
00456     Controllable::pullInput(freqPort, numFrames);           \
00457     freqValue = freqPort->nextValue()
00458 
00460 
00461 #define UPDATE_PHASED_CONTROLS                              \
00462     freqValue = freqPort->nextValue()
00463 
00464 #define CHECK_UPDATE_PHASED_CONTROLS                        \
00465     if (freqPort)                                           \
00466         freqValue = freqPort->nextValue()
00467 
00472 class Writeable {
00473 public:                             
00474     virtual void writeBuffer(Buffer& inputBuffer) throw(CException);
00475     virtual ~Writeable() { /* ?? */ };
00476 
00477 protected:                          
00478     virtual void writeBuffer(Buffer & inputBuffer, unsigned bufNum) throw(CException);
00479 };
00480 
00484 
00485 #ifdef CSL_ENUMS
00486 typedef enum {
00487     kPositionStart,
00488     kPositionCurrent,
00489     kPositionEnd
00490 } SeekPosition;
00491 #else
00492     #define kPositionStart 0
00493     #define kPositionCurrent 1
00494     #define kPositionEnd 2
00495     typedef int SeekPosition;
00496 #endif
00497 
00502 
00503 class Seekable {
00504 public:
00505     Seekable() : mCurrentFrame(0), mActualFrame(0.0)  { }   
00506     virtual ~Seekable() { /* ?? */ };
00507 
00508     unsigned mCurrentFrame;                 
00509     double mActualFrame;                    
00510 
00512     virtual unsigned seekTo(int position, SeekPosition whence) throw(CException) = 0;
00513     virtual void reset() throw(CException); 
00514     virtual unsigned duration() const = 0;  
00515 };
00516 
00520 
00521 class Cacheable {
00522 public:
00523     Cacheable() : mUseCache(false) { }  ;   
00524     Cacheable(bool uC) : mUseCache(uC) { };
00525 
00526     bool mUseCache;                         
00527 };
00528 
00530 
00538 
00539 class FanOut : public Effect {
00540 public:
00541     FanOut(UnitGenerator & in, unsigned taps);  
00542     ~FanOut() { };
00543 
00544     virtual void nextBuffer(Buffer & outputBuffer) throw(CException);
00545 
00546 protected:
00547     Buffer mBuffer;         
00548     unsigned mOutputs;      
00549     unsigned mCurrent;      
00550 };
00551 
00555 
00556 class Splitter : public FanOut {
00557 public:
00558     Splitter(UnitGenerator & in, unsigned taps);    
00559     ~Splitter() { };
00560 
00561     void nextBuffer(Buffer & outputBuffer) throw(CException);
00562 };
00563 
00567 
00568 class Joiner : public Effect {
00569 public:                                     
00570     Joiner() { };                           
00571     Joiner(UnitGenerator & in1, UnitGenerator & in2);
00572     ~Joiner() { };
00573 
00574     void nextBuffer(Buffer & outputBuffer) throw(CException);
00575     void addInput(UnitGenerator & in);      
00576 
00577 protected:
00578     std::vector<UnitGenerator *>mInputs;    
00579 };
00580 
00585 
00586 class Interleaver {
00587 
00588 public:
00590     void interleave(Buffer & output, SampleBuffer samples, unsigned numFrames, 
00591                     unsigned numChannels) throw (CException);
00592     void interleave(Buffer & output, short * samples, unsigned numFrames, 
00593                     unsigned numChannels) throw (CException);
00594 
00597     void interleaveAndRemap(Buffer & output, SampleBuffer samples, unsigned numFrames, unsigned numChannels,
00598                         unsigned *channelMap) throw (CException);
00599 
00601     void deinterleave(Buffer & output, SampleBuffer samples, unsigned numFrames, 
00602                     unsigned numChannels) throw (CException);
00603     void deinterleave(Buffer & output, short * samples, unsigned numFrames, 
00604                     unsigned numChannels) throw (CException);
00605 };
00606 
00607 
00609 
00610 #ifndef CSL_WINDOWS                 // on "normal" platforms
00611 
00612 #ifdef DO_TIMING                    // Here are the macros and globals for the timing code
00613 #include <sys/time.h>
00614 #define GET_TIME(val) if (gettimeofday(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00615 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00616 #endif
00617 
00618 #else                               // If on Windows
00619 
00620 #ifdef DO_TIMING                    // Here are the macros and globals for the timing code
00621 #include <Winsock2.h>
00622 #include <winsock.h>
00623 #include <time.h>
00624 int getSysTime(timeval *val, void * e);
00625 #define GET_TIME(val) if (getSysTime(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00626 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00627 #endif
00628 
00629 #endif                              // Windows
00630 
00631 // IO Status flag
00632 
00633 #ifdef CSL_ENUMS
00634 typedef enum {
00635     kIONew,
00636     kIOInit,
00637     kIOOpen,
00638     kIORunning,
00639     kIOClosed,
00640     kIOExit
00641 } IO_Status;
00642 #else
00643     #define kIONew 0
00644     #define kIOInit 1
00645     #define kIOOpen 2
00646     #define kIORunning 3
00647     #define kIOClosed 4
00648     #define kIOExit 5
00649     typedef int IO_Status;
00650 #endif
00651 
00663 
00664 class IO : public Model  {                                  // superclass = Model
00665 public:
00666     IO(unsigned s_rate = 44100, unsigned b_size = CGestalt::blockSize(),
00667         int in_device = -1, int out_device = -1,
00668         unsigned in_chans = 0, unsigned out_chans = 2);             
00669     virtual ~IO() { };
00670                             // Control methods
00671     virtual void open() throw(CException) { mStatus = kIOOpen; };   
00672     virtual void close() throw(CException) { mStatus = kIOClosed; };
00673     virtual void start() throw(CException) { mStatus = kIORunning; };
00674     virtual void stop() throw(CException) { mStatus = kIOOpen; };
00675     virtual void test() throw(CException) { };  
00676     
00677     void setRoot(UnitGenerator & root);     
00678     void clearRoot();
00680     void pullInput(Buffer & outBuffer, SampleBuffer out = 0)  throw(CException);
00681 
00682     virtual Buffer & getInput() throw(CException);  
00683     virtual Buffer & getInput(unsigned numFrames, unsigned numChannels) throw(CException);
00684     unsigned getAndIncrementSequence();     
00685 
00686                             // Data members
00687     UnitGenerator * mGraph;                 
00688     Buffer mInputBuffer;                    
00689     Buffer mOutputBuffer;                   
00690     SampleBuffer mInputPointer;             
00691     unsigned * mChannelMap;                 
00692 
00693     unsigned mNumFramesPlayed;              
00694     unsigned mSequence;                     
00695     unsigned mLoggingPeriod;                
00696     unsigned mNumInChannels;                
00697     unsigned mNumOutChannels;               
00698     unsigned mNumRealInChannels;            
00699     unsigned mNumRealOutChannels;           
00700     IO_Status mStatus;                      
00701     bool mInterleaved;                      
00702 
00703 #ifdef DO_TIMING                            // This is for the performance timing code
00704     struct timeval mThen, mNow;             
00705     long mTimeVals, mThisSec, mTimeSum;     
00706     float mUsage;                           
00707 
00708     void printTimeStatistics(struct timeval * tthen, struct timeval * tnow, long * tsecond, 
00709                             long * ttimeSum, long * ttimeVals);
00710 #endif
00711 
00712 protected:                                  
00713     virtual void initialize(unsigned sr, unsigned bs, int is, int os, unsigned ic, unsigned oc) { };
00714 };
00715 
00720 
00721 class IODevice {
00722 public:
00723     IODevice() { } ;                        
00724     IODevice(char * name, unsigned index, unsigned maxIn, unsigned maxOut, bool isIn, bool isOut);
00725     IODevice(string name, unsigned index, unsigned maxIn, unsigned maxOut, bool isIn, bool isOut);
00727     char mName[CSL_NAME_LEN];       
00728     unsigned mIndex;                
00729     unsigned mMaxInputChannels;     
00730     unsigned mMaxOutputChannels;    
00731     float mFrameRate;               
00732     vector<float> mFrameRates;      
00733     bool mIsDefaultIn;              
00734     bool mIsDefaultOut;             
00735     void dump();                    
00736 };
00737 
00738 }   // end of namespace
00739 
00740 #endif // CSL_CORE_H

Generated on Sat Oct 17 14:12:30 2009 for CSL by  doxygen 1.4.5-20051010