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 allocateBuffers() throw (MemoryError);
00110 void freeBuffers();
00111
00112 void zeroBuffers();
00113 void fillWith(sample value);
00114 void copyFrom(Buffer & src) throw (RunTimeError);
00115 void copySamplesFrom(Buffer & src) throw (RunTimeError);
00116
00118 SampleBuffer monoBuffer(unsigned bufNum) { return mBuffers[bufNum]; }
00119
00122
00123 #ifdef CSL_DSP_BUFFER
00124 float rms(unsigned chan);
00125 float avg(unsigned chan);
00126 float max(unsigned chan);
00127 float min(unsigned chan);
00128 unsigned int zeroX(unsigned chan);
00129 unsigned int indexOfPeak(unsigned chan);
00130 unsigned int indexOfPeak(unsigned chan, unsigned low, unsigned hi);
00131 unsigned int indexOfMin(unsigned chan);
00132 unsigned int indexOfMin(unsigned chan, unsigned low, unsigned hi);
00133 void autocorrelation(unsigned chan, SampleBuffer result);
00134 #endif
00135 };
00136
00141
00142 class BufferCMap : public Buffer {
00143 public:
00144 BufferCMap();
00145 BufferCMap(unsigned numChannels, unsigned numFrames);
00146 BufferCMap(unsigned numChannels, unsigned realNumChannels, unsigned numFrames);
00147 ~BufferCMap();
00148
00149 unsigned mRealNumChannels;
00150 std::vector<int> mChannelMap;
00151
00153 SampleBuffer monoBuffer(unsigned bufNum) { return mBuffers[mChannelMap[bufNum]]; }
00154 };
00155
00159
00160 #ifdef CSL_ENUMS
00161 typedef enum {
00162 kCopy,
00163 kExpand,
00164 kIgnore
00165 } BufferCopyPolicy;
00166 #else
00167 #define kCopy 0
00168 #define kExpand 1
00169 #define kIgnore 2
00170 typedef int BufferCopyPolicy;
00171 #endif
00172
00173 class RingBuffer;
00174
00191
00192 class UnitGenerator : public Model {
00193 public:
00196 UnitGenerator(unsigned rate = CGestalt::frameRate(), unsigned chans = 1);
00197 virtual ~UnitGenerator() { }
00198
00199
00200 unsigned frameRate() { return mFrameRate; };
00201 void setFrameRate(unsigned rate) { mFrameRate = rate; }
00202
00203 virtual unsigned numChannels() { return mNumChannels; };
00204 void setNumChannels(unsigned ch) { mNumChannels = ch; }
00205
00206 BufferCopyPolicy copyPolicy() { return mCopyPolicy; };
00207 void setCopyPolicy(BufferCopyPolicy ch) { mCopyPolicy = ch; }
00208
00209
00210
00211
00214 virtual void nextBuffer(Buffer & outputBuffer) throw (CException);
00215
00218 virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
00219
00221 virtual bool isFixed() { return false; };
00223 virtual bool isActive() { return true; };
00225 void addOutput(UnitGenerator * ugen);
00226 void removeOutput(UnitGenerator * ugen);
00227 UGenVector outputs() { return mOutputs; };
00228
00230 virtual void setValue(sample theValue) { throw LogicError("can't set value of a generator"); };
00231 virtual sample value() { throw LogicError("can't get value of a generator"); };
00232
00233 virtual void dump();
00234
00235 protected:
00236 unsigned mFrameRate;
00237 unsigned mNumChannels;
00238 BufferCopyPolicy mCopyPolicy;
00239 UGenVector mOutputs;
00240 unsigned mNumOutputs;
00241 RingBuffer * mOutputCache;
00242 unsigned mSequence;
00243
00245 void zeroBuffer(Buffer & outputBuffer, unsigned outBufNum);
00246 };
00247
00255
00256 class Port {
00257 public:
00258 Port();
00259 Port(UnitGenerator * ug);
00260 Port(float value);
00261 virtual ~Port();
00262
00263
00264 UnitGenerator * mUGen;
00265 Buffer * mBuffer;
00266 float mValue;
00267 float *mValuePtr;
00268 unsigned mPtrIncrement;
00269 unsigned mValueIndex;
00270
00271 void checkBuffer() throw (LogicError);
00272 inline float nextValue();
00273 inline void nextFrame(SampleBuffer where);
00274 inline bool isReady();
00275 void resetPtr();
00276 virtual bool isActive();
00277 void dump();
00278 bool isFixed() { return (mPtrIncrement == 0); };
00279 };
00280
00281
00282
00283 inline sample Port::nextValue() {
00284 mValuePtr += mPtrIncrement;
00285 return *mValuePtr;
00286 }
00287
00288
00289
00290 inline void Port::nextFrame(SampleBuffer where) {
00291 for (unsigned i = 0; i < mBuffer->mNumChannels; i++)
00292 *where++ = mBuffer->mBuffers[i][mValueIndex];
00293 mValueIndex++;
00294 }
00295
00296
00297
00298 inline bool Port::isReady() {
00299 return (mValuePtr != 0);
00300 }
00301
00312
00313 class Controllable {
00314 public:
00315 Controllable() : mInputs() { };
00316 virtual ~Controllable() { };
00317
00318 protected:
00319 PortMap mInputs;
00320
00322 void addInput(CSL_MAP_KEY name, UnitGenerator & ugen);
00324 void addInput(CSL_MAP_KEY name, float value);
00327 void pullInput(Port * thePort, unsigned numFrames) throw (CException);
00328 void pullInput(Port * thePort, Buffer & theBuffer) throw (CException);
00329
00330 virtual void dump();
00331 };
00332
00340
00341 class Scalable : public virtual Controllable {
00342 public:
00343 Scalable();
00344 Scalable(float scale);
00345 Scalable(float scale, float offset);
00346 Scalable(UnitGenerator & scale, float offset);
00347 Scalable(UnitGenerator & scale, UnitGenerator & offset);
00348 ~Scalable();
00349
00350
00351 void setScale(UnitGenerator & scale);
00352 void setScale(float scale);
00353
00354 void setOffset(UnitGenerator & offset);
00355 void setOffset(float offset);
00356 };
00357
00360
00362
00363 #define DECLARE_SCALABLE_CONTROLS \
00364 Port * scalePort = mInputs[CSL_SCALE]; \
00365 Port * offsetPort = mInputs[CSL_OFFSET]; \
00366 float scaleValue, offsetValue
00367
00369
00370 #define LOAD_SCALABLE_CONTROLS \
00371 Controllable::pullInput(scalePort, numFrames); \
00372 scaleValue = scalePort->nextValue(); \
00373 Controllable::pullInput(offsetPort, numFrames); \
00374 offsetValue = offsetPort->nextValue()
00375
00376
00377
00378 #define UPDATE_SCALABLE_CONTROLS \
00379 scaleValue = scalePort->nextValue(); \
00380 offsetValue = offsetPort->nextValue()
00381
00382 #define CHECK_UPDATE_SCALABLE_CONTROLS \
00383 if (scalePort) \
00384 scaleValue = scalePort->nextValue(); \
00385 if (offsetPort) \
00386 offsetValue = offsetPort->nextValue()
00387
00393
00394 class Effect : public UnitGenerator, public virtual Controllable {
00395 public:
00396 Effect();
00397 Effect(UnitGenerator & input);
00398
00399 bool isActive() { return (mInputs[CSL_INPUT]->isActive()); };
00400
00401 void setInput(UnitGenerator & inp);
00402
00403 bool isInline;
00404 void setInline() { isInline = true; }
00405
00406 protected:
00407 SampleBuffer mInputPtr;
00408
00409 void pullInput(Buffer & outputBuffer) throw (CException);
00410 void pullInput(unsigned numFrames) throw (CException);
00412 inline Port * inPort() { return mInputs[CSL_INPUT]; };
00413 };
00414
00421
00422 class Phased : public virtual Controllable {
00423 public:
00424 Phased();
00425 Phased(float frequency, float phase = 0);
00426 Phased(UnitGenerator & frequency, float phase = 0);
00427 ~Phased();
00428
00430 void setFrequency(UnitGenerator & frequency);
00431 void setFrequency(float frequency);
00432 void setPhase(float phase) { mPhase = phase; };
00433
00434 protected:
00435 float mPhase;
00436 };
00437
00442
00444
00445 #define DECLARE_PHASED_CONTROLS \
00446 Port * freqPort = mInputs[CSL_FREQUENCY]; \
00447 float freqValue
00448
00452
00453 #define LOAD_PHASED_CONTROLS \
00454 Controllable::pullInput(freqPort, numFrames); \
00455 freqValue = freqPort->nextValue()
00456
00458
00459 #define UPDATE_PHASED_CONTROLS \
00460 freqValue = freqPort->nextValue()
00461
00462 #define CHECK_UPDATE_PHASED_CONTROLS \
00463 if (freqPort) \
00464 freqValue = freqPort->nextValue()
00465
00470 class Writeable {
00471 public:
00472 virtual void writeBuffer(Buffer& inputBuffer) throw(CException);
00473 virtual ~Writeable() { };
00474
00475 protected:
00476 virtual void writeBuffer(Buffer & inputBuffer, unsigned bufNum) throw(CException);
00477 };
00478
00482
00483 #ifdef CSL_ENUMS
00484 typedef enum {
00485 kPositionStart,
00486 kPositionCurrent,
00487 kPositionEnd
00488 } SeekPosition;
00489 #else
00490 #define kPositionStart 0
00491 #define kPositionCurrent 1
00492 #define kPositionEnd 2
00493 typedef int SeekPosition;
00494 #endif
00495
00500
00501 class Seekable {
00502 public:
00503 Seekable() : mCurrentFrame(0), mActualFrame(0.0) { }
00504 virtual ~Seekable() { };
00505
00506 unsigned mCurrentFrame;
00507 double mActualFrame;
00508
00510 virtual unsigned seekTo(int position, SeekPosition whence) throw(CException) = 0;
00511 virtual void reset() throw(CException);
00512 virtual unsigned duration() const = 0;
00513 };
00514
00518
00519 class Cacheable {
00520 public:
00521 Cacheable() : mUseCache(false) { } ;
00522 Cacheable(bool uC) : mUseCache(uC) { };
00523
00524 bool mUseCache;
00525 };
00526
00528
00536
00537 class FanOut : public Effect {
00538 public:
00539 FanOut(UnitGenerator & in, unsigned taps);
00540 ~FanOut() { };
00541
00542 virtual void nextBuffer(Buffer & outputBuffer) throw(CException);
00543
00544 protected:
00545 Buffer mBuffer;
00546 unsigned mOutputs;
00547 unsigned mCurrent;
00548 };
00549
00553
00554 class Splitter : public FanOut {
00555 public:
00556 Splitter(UnitGenerator & in, unsigned taps);
00557 ~Splitter() { };
00558
00559 void nextBuffer(Buffer & outputBuffer) throw(CException);
00560 };
00561
00565
00566 class Joiner : public Effect {
00567 public:
00568 Joiner() { };
00569 Joiner(UnitGenerator & in1, UnitGenerator & in2);
00570 ~Joiner() { };
00571
00572 void nextBuffer(Buffer & outputBuffer) throw(CException);
00573 void addInput(UnitGenerator & in);
00574
00575 protected:
00576 std::vector<UnitGenerator *>mInputs;
00577 };
00578
00583
00584 class Interleaver {
00585
00586 public:
00588 void interleave(Buffer & output, SampleBuffer samples, unsigned numFrames,
00589 unsigned numChannels) throw (CException);
00590 void interleave(Buffer & output, short * samples, unsigned numFrames,
00591 unsigned numChannels) throw (CException);
00592
00595 void interleaveAndRemap(Buffer & output, SampleBuffer samples, unsigned numFrames, unsigned numChannels,
00596 unsigned *channelMap) throw (CException);
00597
00599 void deinterleave(Buffer & output, SampleBuffer samples, unsigned numFrames,
00600 unsigned numChannels) throw (CException);
00601 void deinterleave(Buffer & output, short * samples, unsigned numFrames,
00602 unsigned numChannels) throw (CException);
00603 };
00604
00606
00607 #ifndef CSL_WINDOWS // on "normal" platforms
00608
00609 #ifdef DO_TIMING // Here are the macros and globals for the timing code
00610 #include <sys/time.h>
00611 #define GET_TIME(val) if (gettimeofday(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00612 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00613 #endif
00614
00615 #else // If on Windows
00616
00617 #ifdef DO_TIMING // Here are the macros and globals for the timing code
00618 #include <Winsock2.h>
00619 #include <winsock.h>
00620 #include <time.h>
00621 int getSysTime(timeval *val, void * e);
00622 #define GET_TIME(val) if (getSysTime(val, 0) != 0) logMsg(kLogError, "Output: Error reading current time");
00623 #define SUB_TIMES(t1, t2) (((t1->tv_sec - t2->tv_sec) * 1000000) + (t1->tv_usec - t2->tv_usec))
00624 #endif
00625
00626 #endif // Windows
00627
00628
00629
00630 #ifdef CSL_ENUMS
00631 typedef enum {
00632 kIONew,
00633 kIOInit,
00634 kIOOpen,
00635 kIORunning,
00636 kIOClosed,
00637 kIOExit
00638 } IO_Status;
00639 #else
00640 #define kIONew 0
00641 #define kIOInit 1
00642 #define kIOOpen 2
00643 #define kIORunning 3
00644 #define kIOClosed 4
00645 #define kIOExit 5
00646 typedef int IO_Status;
00647 #endif
00648
00660
00661 class IO {
00662 public:
00663 IO(unsigned s_rate = 44100, unsigned b_size = CGestalt::blockSize(),
00664 int in_device = -1, int out_device = -1,
00665 unsigned in_chans = 0, unsigned out_chans = 2);
00666 virtual ~IO() { };
00667
00668 virtual void open() throw(CException) { mStatus = kIOOpen; };
00669 virtual void close() throw(CException) { mStatus = kIOClosed; };
00670 virtual void start() throw(CException) { mStatus = kIORunning; };
00671 virtual void stop() throw(CException) { mStatus = kIOOpen; };
00672 virtual void test() throw(CException) { };
00673
00674 void setRoot(UnitGenerator & root);
00675 void clearRoot();
00677 void pullInput(Buffer & outBuffer, SampleBuffer out = 0) throw(CException);
00678
00679 virtual Buffer & getInput() throw(CException);
00680 virtual Buffer & getInput(unsigned numFrames, unsigned numChannels) throw(CException);
00681 unsigned getAndIncrementSequence();
00682
00683
00684 UnitGenerator * mGraph;
00685 Buffer mInputBuffer;
00686 Buffer mOutputBuffer;
00687 SampleBuffer mInputPointer;
00688 unsigned * mChannelMap;
00689
00690 unsigned mNumFramesPlayed;
00691 unsigned mSequence;
00692 unsigned mLoggingPeriod;
00693 unsigned mNumInChannels;
00694 unsigned mNumOutChannels;
00695 unsigned mNumRealInChannels;
00696 unsigned mNumRealOutChannels;
00697 IO_Status mStatus;
00698
00699 #ifdef DO_TIMING // This is for the performance timing code
00700 struct timeval mThen, mNow;
00701 long mTimeVals, mThisSec, mTimeSum;
00702
00703 void printTimeStatistics(struct timeval * tthen, struct timeval * tnow, long * tsecond,
00704 long * ttimeSum, long * ttimeVals);
00705 #endif
00706
00707 protected:
00708 virtual void initialize(unsigned sr, unsigned bs, int is, int os, unsigned ic, unsigned oc) { };
00709 };
00710
00715
00716 class IODevice {
00717 public:
00718 IODevice() { } ;
00719 IODevice(char * name, unsigned index, unsigned maxIn, unsigned maxOut, bool isIn, bool isOut);
00720 IODevice(string name, unsigned index, unsigned maxIn, unsigned maxOut, bool isIn, bool isOut);
00722 char mName[CSL_NAME_LEN];
00723 unsigned mIndex;
00724 unsigned mMaxInputChannels;
00725 unsigned mMaxOutputChannels;
00726 float mFrameRate;
00727 vector<float> mFrameRates;
00728 bool mIsDefaultIn;
00729 bool mIsDefaultOut;
00730 void dump();
00731 };
00732
00733 }
00734
00735 #endif // CSL_CORE_H