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 namespace csl {
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
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
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
00189
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
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
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
00260
00261 inline sample Port :: nextValue() {
00262 mValuePtr += mPtrIncrement;
00263 return *mValuePtr;
00264 }
00265
00266
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++;
00272 }
00273
00274
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;
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
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
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
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
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 {
00574 public:
00576 IO() : mGraph(NULL), mNumFramesPlayed(0), mSequence(0), mLoggingPeriod(CGestalt::loggingPeriod()) { };
00577 virtual ~IO() { };
00578
00579
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;
00601 unsigned mNumOutChannels;
00602 unsigned mNumRealInChannels;
00603 unsigned mNumRealOutChannels;
00604
00605 #ifdef DO_TIMING
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 }
00615
00616 #endif CSL_CORE_H