pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_BusWriteChannel.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_BUSWRITECHANNEL_H
00040 #define PLONK_BUSWRITECHANNEL_H
00041 
00042 #include "../channel/plonk_ChannelInternalCore.h"
00043 #include "../plonk_GraphForwardDeclarations.h"
00044 
00045 
00048 template<class SampleType>
00049 class BusWriteChannelInternal 
00050 :   public ChannelInternal<SampleType, ChannelInternalCore::Data>
00051 {
00052 public:
00053     typedef ChannelInternalCore::Data                           Data;
00054     typedef ChannelBase<SampleType>                             ChannelType;
00055     typedef BusWriteChannelInternal<SampleType>                 BusWriteInternal;
00056     typedef ChannelInternal<SampleType,Data>                    Internal;
00057     typedef ChannelInternalBase<SampleType>                     InternalBase;
00058     typedef UnitBase<SampleType>                                UnitType;
00059     typedef InputDictionary                                     Inputs;
00060     typedef NumericalArray<SampleType>                          Buffer;
00061     typedef BusBuffer<SampleType>                               Bus;
00062     typedef PLONK_BUSARRAYBASETYPE<Bus>                         Busses;
00063         
00064     BusWriteChannelInternal (Inputs const& inputs, 
00065                              Data const& data, 
00066                              BlockSize const& blockSize,
00067                              SampleRate const& sampleRate) throw()
00068     :   Internal (inputs, data, blockSize, sampleRate)
00069     {
00070     }
00071     
00072     Text getName() const throw()
00073     {
00074         const Busses& busses (this->getInputAsBusses (IOKey::Busses));
00075         const int numBusses = busses.length();
00076         
00077         Text name = "Bus Write (";
00078         
00079         for (int i = 0; i < numBusses; ++i)
00080         {
00081             name += busses.atUnchecked (i).getName();
00082             
00083             if (i < (numBusses - 1))
00084                 name += ", ";
00085         }
00086         
00087         name += ")";
00088         
00089         return name;
00090     }   
00091     
00092     IntArray getInputKeys() const throw()
00093     {
00094         const IntArray keys (IOKey::Generic,
00095                        IOKey::Busses);
00096         return keys;
00097     }    
00098     
00099     InternalBase* getChannel (const int index) throw()
00100     {
00101         const Inputs channelInputs = this->getInputs().getChannel (index);
00102         return new BusWriteInternal (channelInputs, 
00103                                      this->getState(), 
00104                                      this->getBlockSize(),
00105                                      this->getSampleRate());
00106     }    
00107     
00108     void initChannel (const int channel) throw()
00109     {
00110         const Busses& busses (this->getInputAsBusses (IOKey::Busses));
00111         this->setSampleRate (busses.wrapAt (channel).getSampleRate());
00112 
00113         const UnitType& input = this->getInputAsUnit (IOKey::Generic);
00114         this->setBlockSize (BlockSize::decide (input.getBlockSize (channel),
00115                                                this->getBlockSize()));
00116         
00117         plonk_assert (input.getOverlap (channel) == Math<DoubleVariable>::get1());
00118         
00119         this->initValue (SampleType (0));
00120     }    
00121     
00122     void process (ProcessInfo& info, const int channel) throw()
00123     {        
00124         int i;
00125         
00126         SampleType* const outputSamples = this->getOutputSamples();
00127         const int outputBufferLength = this->getOutputBuffer().length();
00128 
00129         Busses& busses (this->getInputAsBusses (IOKey::Busses));
00130         Bus& bus = busses.wrapAt (channel);
00131 
00132         plonk_assert (bus.getSampleRate() == this->getSampleRate());
00133 
00134         UnitType& inputUnit (this->getInputAsUnit (IOKey::Generic));
00135         
00136         const Buffer& inputBuffer (inputUnit.process (info, channel));
00137         const SampleType* const inputSamples = inputBuffer.getArray();
00138         const int inputBufferLength = inputBuffer.length();
00139         
00140         if (inputBufferLength == outputBufferLength)
00141         {
00142             Buffer::copyData (outputSamples, inputSamples, outputBufferLength);
00143         }
00144         else
00145         {
00146             double inputPosition = 0.0;
00147             double inputIncrement = double (inputBufferLength) / double (outputBufferLength);
00148             
00149             for (i = 0; i < outputBufferLength; ++i) 
00150             {
00151                 outputSamples[i] = inputSamples[int (inputPosition)];
00152                 inputPosition += inputIncrement;
00153             }        
00154         }
00155         
00156         bus.write (info.getTimeStamp(), outputBufferLength, outputSamples);
00157     }
00158 
00159 private:
00160 };
00161 
00162 //------------------------------------------------------------------------------
00163 
00166 template<class SampleType>
00167 class BusWriteUnit
00168 {
00169 public:    
00170     typedef BusWriteChannelInternal<SampleType>     BusWriteInternal;
00171     typedef typename BusWriteInternal::Data         Data;
00172     typedef ChannelBase<SampleType>                 ChannelType;
00173     typedef ChannelInternal<SampleType,Data>        Internal;
00174     typedef ChannelInternalBase<SampleType>         InternaBase;
00175     typedef UnitBase<SampleType>                    UnitType;
00176     typedef InputDictionary                         Inputs;
00177     typedef NumericalArray<SampleType>              Buffer;
00178     typedef BusBuffer<SampleType>                   Bus;
00179     typedef PLONK_BUSARRAYBASETYPE<Bus>             Busses;
00180     
00181     static inline UnitInfos getInfo() throw()
00182     {
00183         const double blockSize = (double)BlockSize::getDefault().getValue();
00184 
00185         return UnitInfo ("BusWrite", "Writes samples to a bus (and copies this to its output).",
00186                          
00187                          // output
00188                          ChannelCount::VariableChannelCount, 
00189                          IOKey::Generic,     Measure::None,      IOInfo::NoDefault,  IOLimit::None,      IOKey::End,
00190                          
00191                          // inputs
00192                          IOKey::Busses,     Measure::None,
00193                          IOKey::Generic,     Measure::None,      IOInfo::NoDefault,  IOLimit::None,
00194                          IOKey::BlockSize,  Measure::Samples,   blockSize,          IOLimit::Minimum,   Measure::Samples,   1.0,
00195                          IOKey::End);
00196     }    
00197     
00198     
00200     static UnitType ar (Busses const& busses,
00201                         UnitType const& input,
00202                         BlockSize const& preferredBlockSize = BlockSize::noPreference()) throw()
00203     {                
00204         Inputs inputs;
00205         inputs.put (IOKey::Generic, input);   
00206         inputs.put (IOKey::Busses, busses);
00207         
00208         Data data = { -1.0, -1.0 };
00209         
00210         return UnitType::template createFromInputs<BusWriteInternal> (inputs, 
00211                                                                       data, 
00212                                                                       preferredBlockSize, 
00213                                                                       SampleRate::noPreference());
00214     }
00215         
00216     static inline UnitType kr (Busses const& busses,
00217                                UnitType const& input) throw()
00218     {
00219         return ar (busses, input, BlockSize::getControlRateBlockSize());
00220     }    
00221     
00222 };
00223 
00224 typedef BusWriteUnit<PLONK_TYPE_DEFAULT> BusWrite;
00225 
00226 
00227 
00228 
00229 #endif // PLONK_BUSWRITECHANNEL_H
00230 
00231 
 All Classes Functions Typedefs Enumerations Enumerator Properties