![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLONK_CHANNEL_H 00040 #define PLONK_CHANNEL_H 00041 00042 #include "../plonk_GraphForwardDeclarations.h" 00043 #include "../../containers/plonk_DynamicContainer.h" 00044 #include "../../containers/variables/plonk_Variable.h" 00045 #include "../../core/plonk_SmartPointer.h" 00046 #include "../../core/plonk_WeakPointer.h" 00047 #include "../../core/plonk_SmartPointerContainer.h" 00048 #include "../utility/plonk_ProcessInfo.h" 00049 #include "../utility/plonk_BlockSize.h" 00050 #include "../utility/plonk_SampleRate.h" 00051 #include "../utility/plonk_TimeStamp.h" 00052 #include "../utility/plonk_InputDictionary.h" 00053 00054 //------------------------------------------------------------------------------ 00055 00061 template<class SampleType> 00062 class ChannelBase : public SmartPointerContainer< ChannelInternalBase<SampleType> > 00063 { 00064 protected: 00065 typedef PLONK_UNITBASETYPE<ChannelBase> UnitType; 00066 00067 public: 00068 typedef ChannelInternalBase<SampleType> Internal; 00069 typedef SmartPointerContainer<Internal> Base; 00070 typedef WeakPointerContainer<ChannelBase> Weak; 00071 typedef NumericalArray<SampleType> Buffer; 00072 typedef InputDictionary Inputs; 00073 typedef Variable<SampleType> VariableType; 00074 typedef ReceiverInternal<ChannelBase> Receiver; 00075 00076 00079 ChannelBase() throw() 00080 : Base (ChannelBase::getNull().getInternal()) 00081 { 00082 } 00083 00085 ChannelBase (Internal *internal) throw() 00086 : Base (internal) 00087 { 00088 } 00089 00091 ChannelBase (UnitType const& unit) throw() 00092 : Base (static_cast<Base const&> (unit.atUnchecked (0))) 00093 { 00094 plonk_assert (unit.getNumChannels() == 1); 00095 } 00096 00098 ChannelBase (UnitBase<SampleType> const& unit) throw() 00099 : Base (static_cast<Base const&> (unit.atUnchecked (0))) 00100 { 00101 plonk_assert (unit.getNumChannels() == 1); 00102 } 00103 00104 00107 ChannelBase (ChannelBase const& copy) throw() 00108 : Base (static_cast<Base const&> (copy)) 00109 { 00110 } 00111 00113 ChannelBase& operator= (ChannelBase const& other) throw() 00114 { 00115 if (this != &other) 00116 this->setInternal (other.getInternal());//this->setInternal (other.containerCopy().getInternal()); 00117 00118 return *this; 00119 } 00120 00121 // ChannelBase (Dynamic const& other) throw() 00122 // : Base (static_cast<Internal*> (other.getItem().getInternal())) 00123 // { 00124 // if (this->getInternal() == 0) 00125 // operator= (ChannelBase()); 00126 // else 00127 // plonk_assert (other.getTypeCode() == TypeUtility<ChannelBase>::getTypeCode()); 00128 // } 00129 00133 static ChannelBase fromWeak (Weak const& weak) throw() 00134 { 00135 return weak.fromWeak(); 00136 } 00137 00138 static const ChannelBase& getNull() throw() 00139 { 00140 static ChannelBase null (static_cast<Internal*> (new NullChannelInternal<SampleType>())); 00141 return null; 00142 } 00143 00145 template<class ValueType> 00146 ChannelBase (ValueType const& valueInit) throw() 00147 : Base (new ConstantChannelInternal<SampleType> (valueInit)) 00148 { 00149 } 00150 00151 inline bool isNull() const throw() { return this->getInternal()->isNull(); } 00152 inline bool isNotNull() const throw() { return ! this->getInternal()->isNull(); } 00153 inline bool isConstant() const throw() { return this->getInternal()->isConstant(); } 00154 inline bool isNotConstant() const throw() { return ! this->getInternal()->isConstant(); } 00155 inline bool isTypeConverter() const throw() { return this->getInternal()->isTypeConverter(); } 00156 00157 inline const Text getName() const throw() { return this->getInternal()->getName(); } 00158 inline const Text getLabel() const throw() { return this->getInternal()->getLabel(); } 00159 inline void setLabel(Text const& newId) throw() { this->getInternal()->setLabel(newId); } 00160 inline const Text getOutputTypeName() const throw() { return this->getInternal()->getOutputTypeName(); } 00161 inline const Text getInputTypeName() const throw() { return this->getInternal()->getInputTypeName(); } 00162 inline int getOutputTypeCode() const throw() { return this->getInternal()->getOutputTypeCode(); } 00163 inline int getInputTypeCode() const throw() { return this->getInternal()->getInputTypeCode(); } 00164 00165 inline const BlockSize& getBlockSize() const throw() { return this->getInternal()->getBlockSize(); } 00166 inline BlockSize& getBlockSize() throw() { return this->getInternal()->getBlockSize(); } 00167 inline void setBlockSize (BlockSize const& newBlockSize) throw() { this->getInternal()->setBlockSize (newBlockSize); } 00168 00169 inline const SampleRate& getSampleRate() const throw() { return this->getInternal()->getSampleRate(); } 00170 inline SampleRate& getSampleRate() throw() { return this->getInternal()->getSampleRate(); } 00171 inline void setSampleRate (SampleRate const& newSampleRate) throw() { this->getInternal()->setSampleRate (newSampleRate); } 00172 inline double getSampleDurationInTicks() const throw() { return this->getInternal()->getSampleDurationInTicks(); } 00173 inline double getBlockDurationInTicks() const throw() { return this->getInternal()->getBlockDurationInTicks(); } 00174 00175 inline const DoubleVariable& getOverlap() const throw() { return this->getInternal()->getOverlap(); } 00176 inline DoubleVariable& getOverlap() throw() { return this->getInternal()->getOverlap(); } 00177 inline void setOverlap (DoubleVariable const& newOverlap) throw() { this->getInternal()->setOverlap (newOverlap); } 00178 00179 inline const Inputs& getInputs() const throw() { return this->getInternal()->getInputs(); } 00180 inline Inputs getInputs() throw() { return this->getInternal()->getInputs(); } 00181 00182 inline const Buffer& getOutputBuffer() const throw() { return this->getInternal()->getOutputBuffer(); } 00183 inline Buffer& getOutputBuffer() throw() { return this->getInternal()->getOutputBuffer(); } 00184 inline const SampleType* getOutputSamples() const throw() { return this->getInternal()->getOutputSamples(); } 00185 inline SampleType* getOutputSamples() throw() { return this->getInternal()->getOutputSamples(); } 00186 inline void setOutputBuffer (Buffer const& externalBuffer) throw() { this->getInternal()->setOutputBuffer (externalBuffer); } 00187 00188 inline int getNumChannels() const throw() { return this->getInternal()->getNumChannels(); } 00189 00190 inline void initValue (SampleType const& value) throw() { return this->getInternal()->initValue (value); } 00191 inline void initChannel (const int index) throw() { this->getInternal()->initChannel (index); } 00192 inline const SampleType& getValue() const throw() { return this->getInternal()->getValue(); } 00193 00194 inline ChannelBase getChannel (const int index) throw() { return ChannelBase (this->getInternal()->getChannel (index)); } 00195 inline ChannelBase operator[] (const int index) throw() { return ChannelBase (this->getInternal()->getChannel (index)); } 00196 00197 inline const TimeStamp& getNextTimeStamp() const throw() { return this->getInternal()->getNextTimeStamp(); } 00198 inline bool shouldBeDeletedNow (TimeStamp const& time) const throw() { return this->getInternal()->shouldBeDeletedNow (time); } 00199 00200 inline void resetIfExpired() throw() { this->getInternal()->setExpiryTimeStamp (TimeStamp::getMaximum()); } 00201 00202 // /** Returns @c true if this unit needs to process for the given timestamp. */ 00203 // inline bool needsToProcess (ProcessInfo const& info, const int channel) const throw() 00204 // { 00205 // (void)channel; 00206 // 00207 // const TimeStamp& nextTimeStamp = this->getInternal()->getNextTimeStamp(); 00208 // const TimeStamp& infoTimeStamp = info.getTimeStamp(); 00209 // 00210 // return (infoTimeStamp >= nextTimeStamp); 00211 // } 00212 00214 inline bool needsToProcess (ProcessInfo const& info) const throw() 00215 { 00216 const TimeStamp& nextTimeStamp = this->getInternal()->getNextTimeStamp(); 00217 const TimeStamp& infoTimeStamp = info.getTimeStamp(); 00218 00219 return (infoTimeStamp >= nextTimeStamp); 00220 } 00221 00222 inline void process (ProcessInfo& info, const int channel) throw() 00223 { 00224 if (this->needsToProcess (info)) 00225 { 00226 this->getInternal()->process (info, channel); 00227 this->getInternal()->setLastTimeStamp (info.getTimeStamp()); 00228 this->getInternal()->updateTimeStamp(); 00229 00230 if (info.getShouldDelete() == true) 00231 this->getInternal()->setExpiryTimeStamp (this->getInternal()->getNextTimeStamp()); 00232 } 00233 } 00234 00235 int getTypeCode() const throw() 00236 { 00237 return TypeUtility<ChannelBase>::getTypeCode(); 00238 } 00239 00240 int getSampleTypeCode() const throw() 00241 { 00242 return TypeUtility<SampleType>::getTypeCode(); 00243 } 00244 00245 }; 00246 00247 00248 00249 #endif // PLONK_CHANNEL_H