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"
00043 #include "CSL_Exceptions.h"
00044 #include "CGestalt.h"
00045
00046 namespace csl {
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
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
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:
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
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
00283
00284 inline sample Port::nextValue() {
00285 mValuePtr += mPtrIncrement;
00286 return *mValuePtr;
00287 }
00288
00289
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++;
00295 }
00296
00297
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
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
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
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
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 {
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
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
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
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 }
00739
00740 #endif // CSL_CORE_H