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"
00035 #include "CSL_Exceptions.h"
00036 #include "CGestalt.h"
00037
00038
00039
00040
00041
00042 namespace csl {
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
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
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
00171
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
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
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;
00243 return *mValuePtr;
00244 }
00245
00246
00256 class Controllable {
00257 public:
00258 Controllable() : mInputs() { };
00259 virtual ~Controllable() { };
00260
00261 protected:
00262 PortMap mInputs;
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
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
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
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 {
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
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 }
00571
00572 #endif CSL_CORE_H
00573