pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_ChannelInternalBase.h
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_CHANNELINTERNALBASE_H
00040 #define PLONK_CHANNELINTERNALBASE_H
00041 
00042 #include "../plonk_GraphForwardDeclarations.h"
00043 #include "plonk_ChannelInternalCore.h"
00044 
00048 template<class SampleType>
00049 class ChannelInternalBase : public SenderInternal<ChannelBase<SampleType> >,
00050                             public ChannelInternalCore,
00051                             public IntVariable::Receiver
00052 {
00053 public:    
00054     typedef ChannelBase<SampleType>                 ChannelType;
00055     typedef UnitBase<SampleType>                    UnitType;
00056     typedef NumericalArray2D<ChannelType,UnitType>  UnitsType;
00057     typedef BusBuffer<SampleType>                   BusType;
00058     typedef PLONK_BUSARRAYBASETYPE<BusType>         BussesType;
00059 
00060     typedef NumericalArray<SampleType>              Buffer;
00061     typedef InputDictionary                         Inputs;    
00062     typedef ChannelBase<SampleType>                 Container;
00063     typedef Variable<SampleType>                    VariableType;
00064     typedef BreakpointsBase<SampleType>             BreakpointsType;
00065     typedef WavetableBase<SampleType>               WavetableType;
00066     typedef SignalBase<SampleType>                  SignalType;
00067     typedef LockFreeQueue<UnitType>                 QueueType;
00068 
00069     ChannelInternalBase (Inputs const& inputDictionary, 
00070                          BlockSize const& blockSize, 
00071                          SampleRate const& sampleRate) throw()
00072     :   ChannelInternalCore (inputDictionary, blockSize, sampleRate),
00073         outputBuffer (Buffer::newClear (blockSize.getValue())),
00074         usingExternalBuffer (false)
00075     {
00076 #ifdef PLONK_DEBUG
00077         hasInitialisedValue = false;
00078 #endif        
00079         this->getBlockSize().addReceiver (this);
00080     }
00081     
00082     ~ChannelInternalBase()
00083     {
00084         this->getBlockSize().removeReceiver (this);
00085     }
00086             
00087     inline const UnitType& getInputAsUnit (const int key) const throw()                     { return this->template getInputAs<UnitType> (key); }
00088     inline const UnitsType& getInputAsUnits (const int key) const throw()                   { return this->template getInputAs<UnitsType> (key); }
00089     inline const BusType& getInputAsBus (const int key) const throw()                       { return this->template getInputAs<BusType> (key); }
00090     inline const BussesType& getInputAsBusses (const int key) const throw()                 { return this->template getInputAs<BussesType> (key); }
00091     inline const Buffer& getInputAsBuffer (const int key) const throw()                     { return this->template getInputAs<Buffer> (key); }
00092     inline const VariableType& getInputAsVariable (const int key) const throw()             { return this->template getInputAs<VariableType> (key); }
00093     inline const BreakpointsType& getInputAsBreakpoints (const int key) const throw()       { return this->template getInputAs<BreakpointsType> (key); }
00094     inline const WavetableType& getInputAsWavetable (const int key) const throw()           { return this->template getInputAs<WavetableType> (key); }
00095     inline const SignalType& getInputAsSignal (const int key) const throw()                 { return this->template getInputAs<SignalType> (key); }
00096     inline const SampleRate& getInputAsSampleRate (const int key) const throw()             { return this->template getInputAs<SampleRate> (key); }
00097     inline const BlockSize& getInputAsBlockSize (const int key) const throw()               { return this->template getInputAs<BlockSize> (key); }
00098     inline const AudioFileReader& getInputAsAudioFileReader (const int key) const throw()   { return this->template getInputAs<AudioFileReader> (key); }
00099     inline const QueueType& getInputAsUnitQueue (const int key) const throw()               { return this->template getInputAs<QueueType> (key); }
00100 
00101     inline UnitType& getInputAsUnit (const int key) throw()                                 { return this->template getInputAs<UnitType> (key); }
00102     inline UnitsType& getInputAsUnits (const int key) throw()                               { return this->template getInputAs<UnitsType> (key); }
00103     inline BusType& getInputAsBus (const int key) throw()                                   { return this->template getInputAs<BusType> (key); }
00104     inline BussesType& getInputAsBusses (const int key) throw()                             { return this->template getInputAs<BussesType> (key); }
00105     inline Buffer& getInputAsBuffer (const int key) throw()                                 { return this->template getInputAs<Buffer> (key); }
00106     inline VariableType& getInputAsVariable (const int key) throw()                         { return this->template getInputAs<VariableType> (key); }
00107     inline BreakpointsType& getInputAsBreakpoints (const int key) throw()                   { return this->template getInputAs<BreakpointsType> (key); }
00108     inline WavetableType& getInputAsWavetable (const int key) throw()                       { return this->template getInputAs<WavetableType> (key); }
00109     inline SignalType& getInputAsSignal (const int key) throw()                             { return this->template getInputAs<SignalType> (key); }
00110     inline SampleRate& getInputAsSampleRate (const int key) throw()                         { return this->template getInputAs<SampleRate> (key); }
00111     inline BlockSize& getInputAsBlockSize (const int key) throw()                           { return this->template getInputAs<BlockSize> (key); }
00112     inline AudioFileReader& getInputAsAudioFileReader (const int key) throw()               { return this->template getInputAs<AudioFileReader> (key); }
00113     inline QueueType& getInputAsUnitQueue (const int key) throw()                           { return this->template getInputAs<QueueType> (key); }
00114 
00115     inline const Buffer& getOutputBuffer() const throw()                                    { return outputBuffer; }
00116     inline Buffer& getOutputBuffer() throw()                                                { return outputBuffer; }
00117     inline const SampleType* getOutputSamples() const throw()                               { return outputBuffer.getArray(); }
00118     inline SampleType* getOutputSamples() throw()                                           { return outputBuffer.getArray(); }
00119     
00120     inline const SampleType& getValue() const throw() 
00121     { 
00122         // the underlying Channel or Unit may not have called initValue()
00123         plonk_assert (this->isNull() || hasInitialisedValue == true); 
00124         return outputBuffer.last();
00125     }
00126     
00127     inline void setOutputBuffer (Buffer const& externalBuffer) throw()
00128     {
00129         plonk_assert (this->canUseExternalBuffer());
00130         plonk_assert (externalBuffer.length() == this->getBlockSize().getValue());
00131         usingExternalBuffer = true;
00132         outputBuffer = externalBuffer;
00133     }
00134     
00135     inline bool isUsingExternalBuffer() const throw() { return usingExternalBuffer; }
00136     
00137     inline void removeExternalBuffer() throw()
00138     {
00139         plonk_assert (usingExternalBuffer == true);
00140         usingExternalBuffer = false;
00141         outputBuffer = Buffer::newClear (this->getBlockSize().getValue());
00142     }
00143     
00144     virtual void setBlockSize (BlockSize const& newBlockSize) throw()
00145     {        
00146         if (newBlockSize != this->getBlockSize())
00147         {
00148             plonk_assert (newBlockSize.getValue() > 0);
00149 
00150             this->getBlockSize().removeReceiver (this);
00151             this->setBlockSizeInternal (newBlockSize);
00152             this->getBlockSize().addReceiver (this);
00153             this->updateBlockSize();
00154         }
00155     }
00156     
00157     virtual void setSampleRate (SampleRate const& newSampleRate) = 0;
00158     virtual void setOverlap (DoubleVariable const& newOverlap) = 0;
00159     
00160     virtual ChannelInternalBase* getChannel (const int index) = 0;
00161             
00162     virtual void initValue (SampleType const& value) throw()
00163     {
00164 #ifdef PLONK_DEBUG
00165         plonk_assert (outputBuffer.length() > 0);
00166         hasInitialisedValue = true;
00167 #endif                
00168         outputBuffer.last() = value;
00169     }
00170     
00171     inline const Text getOutputTypeName() const throw()         { return TypeUtility<SampleType>::getTypeName(); }
00172     virtual const Text getInputTypeName() const throw()         { return TypeUtility<SampleType>::getTypeName(); }
00173     inline int getOutputTypeCode() const throw()                { return TypeUtility<SampleType>::getTypeCode(); }
00174     virtual int getInputTypeCode() const throw()                { return TypeUtility<SampleType>::getTypeCode(); }
00175     
00176     void changed (IntVariable::Sender const& source, Text const& message, Dynamic const& payload) throw()
00177     {
00178         (void)message;
00179         (void)payload;
00180         
00181         BlockSize blockSizeSource = static_cast<BlockSize> (source);
00182         
00183         if (blockSizeSource == this->getBlockSize())
00184         {
00185             this->updateBlockSize();
00186             return;
00187         }
00188     }
00189     
00190     inline void updateBlockSize() throw()
00191     {
00192         if (usingExternalBuffer == false)
00193         {
00194             const int size = this->getBlockSize().getValue();
00195             
00196             if (size != outputBuffer.length())
00197                 outputBuffer.setSize (size, false);
00198         }
00199     }
00200     
00201 private:
00202     Buffer outputBuffer;
00203     bool usingExternalBuffer;
00204     
00205 #ifdef PLONK_DEBUG
00206     bool hasInitialisedValue;
00207 #endif
00208     
00209     ChannelInternalBase();
00210     ChannelInternalBase (const ChannelInternalBase&);
00211         const ChannelInternalBase& operator= (const ChannelInternalBase&);
00212 };
00213 
00214 
00215 #endif // PLONK_CHANNELINTERNALBASE_H
 All Classes Functions Typedefs Enumerations Enumerator Properties