pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_SignalRead.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_SignalRead_H
00040 #define PLONK_SignalRead_H
00041 
00042 #include "../channel/plonk_ChannelInternalCore.h"
00043 #include "../plonk_GraphForwardDeclarations.h"
00044 
00045 template<class SampleType> class SignalReadChannelInternal;
00046 
00047 PLONK_CHANNELDATA_DECLARE(SignalReadChannelInternal,SampleType)
00048 {    
00049     typedef typename TypeUtility<SampleType>::IndexType PositionType;
00050 
00051     ChannelInternalCore::Data base;
00052 };      
00053 
00054 //------------------------------------------------------------------------------
00055 
00057 template<class SampleType>
00058 class SignalReadChannelInternal 
00059 :   public ChannelInternal<SampleType, PLONK_CHANNELDATA_NAME(SignalReadChannelInternal,SampleType)>
00060 {
00061 public:
00062 
00063     typedef PLONK_CHANNELDATA_NAME(SignalReadChannelInternal,SampleType)  Data;
00064     typedef ChannelBase<SampleType>                                 ChannelType;
00065     typedef SignalReadChannelInternal<SampleType>                   SignalReadInternal;
00066     typedef ChannelInternal<SampleType,Data>                        Internal;
00067     typedef ChannelInternalBase<SampleType>                         InternalBase;
00068     typedef UnitBase<SampleType>                                    UnitType;
00069     typedef InputDictionary                                         Inputs;
00070     typedef NumericalArray<SampleType>                              Buffer;
00071     typedef SignalBase<SampleType>                                  SignalType;
00072 
00073     typedef typename TypeUtility<SampleType>::IndexType             PositionType;
00074     typedef UnitBase<PositionType>                                  PositionUnitType;
00075     typedef NumericalArray<PositionType>                            PositionBufferType;
00076     typedef InterpLinear<SampleType,PositionType>                   InterpType;
00077 
00078     SignalReadChannelInternal (Inputs const& inputs, 
00079                                Data const& data,
00080                                BlockSize const& blockSize,
00081                                SampleRate const& sampleRate) throw()
00082     :   Internal (inputs, data, blockSize, sampleRate)
00083     {
00084     }
00085             
00086     Text getName() const throw()
00087     {
00088         return "Signal Read";
00089     }       
00090     
00091     IntArray getInputKeys() const throw()
00092     {
00093         const IntArray keys (IOKey::Signal, 
00094                              IOKey::Time);
00095         return keys;
00096     }    
00097     
00098     InternalBase* getChannel (const int index) throw()
00099     {
00100         const Inputs channelInputs = this->getInputs().getChannel (index);
00101         return new SignalReadInternal (channelInputs, 
00102                                        this->getState(), 
00103                                        this->getBlockSize(), 
00104                                        this->getSampleRate());
00105     }
00106     
00107     void initChannel (const int channel) throw()
00108     {        
00109         const PositionUnitType& positionUnit = ChannelInternalCore::getInputAs<PositionUnitType> (IOKey::Time);
00110         
00111         this->setBlockSize (BlockSize::decide (positionUnit.getBlockSize (channel),
00112                                                this->getBlockSize()));
00113         this->setSampleRate (SampleRate::decide (positionUnit.getSampleRate (channel),
00114                                                  this->getSampleRate()));
00115         
00116         this->setOverlap (positionUnit.getOverlap (channel));
00117         
00118         this->initValue (0);//
00119     }    
00120     
00121     void process (ProcessInfo& info, const int channel) throw()
00122     {                
00123         PositionUnitType& positionUnit = ChannelInternalCore::getInputAs<PositionUnitType> (IOKey::Time);
00124         const PositionBufferType& positionBuffer (positionUnit.process (info, channel));
00125         
00126         SampleType* const outputSamples = this->getOutputSamples();
00127         const int outputBufferLength = this->getOutputBuffer().length();
00128         
00129         const PositionType* const positionSamples = positionBuffer.getArray();
00130         const int positionBufferLength = positionBuffer.length();
00131         
00132         const SignalType& signal (this->getInputAsSignal (IOKey::Signal));
00133         const SampleType* const signalSamples = signal.getSamples (channel);         
00134         const unsigned int signalFrameStride = signal.getFrameStride();
00135         const unsigned int numSignalFrames (signal.getNumFrames());
00136         
00137         const PositionType positionScale (signal.getSampleRate().getValue());
00138         
00139         int i;
00140         
00141         if (positionBufferLength == outputBufferLength)
00142         {
00143             for (i = 0; i < outputBufferLength; ++i) 
00144             {
00145                 const PositionType currentPosition = positionSamples[i] * positionScale;
00146                 
00147                 const unsigned int sampleA (plonk::max (PositionType (0), currentPosition));
00148                 const unsigned int sampleB (sampleA + 1);
00149                 const PositionType frac (plonk::frac (currentPosition));
00150                 
00151                 outputSamples[i] = InterpType::interp (signalSamples[(sampleA % numSignalFrames) * signalFrameStride], 
00152                                                        signalSamples[(sampleB % numSignalFrames) * signalFrameStride], 
00153                                                        frac);                
00154             }
00155         }
00156         else if (positionBufferLength == 1)
00157         {
00158             const PositionType currentPosition = positionSamples[0] * positionScale;
00159             const unsigned int sampleA (plonk::max (PositionType (0), currentPosition));
00160             const unsigned int sampleB (sampleA + 1);
00161             const PositionType frac (plonk::frac (currentPosition));
00162             const SampleType value = InterpType::interp (signalSamples[(sampleA % numSignalFrames) * signalFrameStride],
00163                                                          signalSamples[(sampleB % numSignalFrames) * signalFrameStride],
00164                                                          frac);
00165             
00166             NumericalArrayFiller<SampleType>::fill (outputSamples, value, outputBufferLength);
00167         }
00168         else
00169         {
00170             double positionPosition = 0.0;
00171             const double positionIncrement = double (positionBufferLength) / double (outputBufferLength);
00172             
00173             for (i = 0; i < outputBufferLength; ++i) 
00174             {
00175                 const PositionType currentPosition = positionSamples[int (positionPosition)] * positionScale;
00176                 
00177                 const unsigned int sampleA (plonk::max (PositionType (0), currentPosition));
00178                 const unsigned int sampleB (sampleA + 1);
00179                 const PositionType frac (plonk::frac (currentPosition));
00180                 
00181                 outputSamples[i] = InterpType::interp (signalSamples[(sampleA % numSignalFrames) * signalFrameStride], 
00182                                                        signalSamples[(sampleB % numSignalFrames) * signalFrameStride], 
00183                                                        frac);
00184                 
00185                 positionPosition += positionIncrement;
00186             }                    
00187         }
00188         
00189     }
00190     
00191 private:
00192 };
00193 
00194 //------------------------------------------------------------------------------
00195 
00211 template<class SampleType>
00212 class SignalReadUnit
00213 {
00214 public:    
00215     typedef SignalReadChannelInternal<SampleType>       SignalReadInternal;
00216     typedef typename SignalReadInternal::Data           Data;
00217     typedef ChannelBase<SampleType>                     ChannelType;
00218     typedef ChannelInternal<SampleType,Data>            Internal;
00219     typedef UnitBase<SampleType>                        UnitType;
00220     typedef InputDictionary                             Inputs;
00221     typedef SignalBase<SampleType>                      SignalType;
00222     
00223     typedef typename SignalReadInternal::PositionType         PositionType;
00224     typedef typename SignalReadInternal::PositionUnitType     PositionUnitType;
00225     typedef typename SignalReadInternal::PositionBufferType   PositionBufferType;
00226     
00227     static inline UnitInfos getInfo() throw()
00228     {
00229         const double blockSize = (double)BlockSize::getDefault().getValue();
00230         const double sampleRate = SampleRate::getDefault().getValue();
00231         
00232         return UnitInfo ("SignalRead", "A signal reader generator",
00233                          
00234                          // output
00235                          ChannelCount::VariableChannelCount, 
00236                          IOKey::Generic,    Measure::None,      0.0,                    IOLimit::None,
00237                          IOKey::End,
00238                          
00239                          // inputs
00240                          IOKey::Signal,     Measure::None,
00241                          IOKey::Time,       Measure::Seconds,   IOInfo::NoDefault,      IOLimit::Minimum,   Measure::Seconds,           0.0,
00242                          IOKey::Multiply,   Measure::Factor,    1.0,                    IOLimit::None,
00243                          IOKey::Add,        Measure::None,      0.0,                    IOLimit::None,
00244                          IOKey::BlockSize,  Measure::Samples,   blockSize,              IOLimit::Minimum,   Measure::Samples,           1.0,
00245                          IOKey::SampleRate, Measure::Hertz,     sampleRate,             IOLimit::Minimum,   Measure::Hertz,             0.0,
00246                          IOKey::End);
00247     }
00248     
00250     static UnitType ar (SignalType const& signal, 
00251                         PositionUnitType const& position,
00252                         UnitType const& mul = SampleType (1),
00253                         UnitType const& add = SampleType (0),
00254                         BlockSize const& preferredBlockSize = BlockSize::getDefault(),
00255                         SampleRate const& preferredSampleRate = SampleRate::getDefault()) throw()
00256     {             
00257         Inputs inputs;
00258         inputs.put (IOKey::Signal, signal);
00259         inputs.put (IOKey::Time, position);
00260         inputs.put (IOKey::Multiply, mul);
00261         inputs.put (IOKey::Add, add);
00262                         
00263         Data data = { { -1.0, -1.0 } };
00264         
00265         return UnitType::template createFromInputs<SignalReadInternal> (inputs, 
00266                                                                         data, 
00267                                                                         preferredBlockSize, 
00268                                                                         preferredSampleRate);
00269     }
00270     
00272     static UnitType kr (SignalType const& signal,
00273                         PositionUnitType const& position,
00274                         UnitType const& mul = SampleType (1),
00275                         UnitType const& add = SampleType (0)) throw()
00276     {
00277         return ar (signal, position, mul, add, 
00278                    BlockSize::getControlRateBlockSize(), 
00279                    SampleRate::getControlRate());
00280     }        
00281 };
00282 
00283 typedef SignalReadUnit<PLONK_TYPE_DEFAULT> SignalRead;
00284 
00285 
00286 #endif // PLONK_SignalRead_H
00287 
 All Classes Functions Typedefs Enumerations Enumerator Properties