pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_Unit.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_UNIT_H
00040 #define PLONK_UNIT_H
00041 
00042 #include "plonk_GraphForwardDeclarations.h"
00043 #include "utility/plonk_ProcessInfo.h"
00044 #include "utility/plonk_BlockSize.h"
00045 #include "utility/plonk_SampleRate.h"
00046 #include "info/plonk_InfoHeaders.h"
00047 
00078 template<class SampleType>
00079 class UnitBase : public NumericalArray<ChannelBase<SampleType> >
00080 {
00081 protected:
00082     typedef ChannelBase<SampleType>                     ChannelType;
00083     typedef ObjectArray<ChannelType>                    ChannelArrayType;          
00084     typedef ChannelInternalBase<SampleType>             ChannelInternalType;
00085     typedef NumericalArray<ChannelType>                 UnitType;
00086     typedef NumericalArray2D<ChannelType,UnitBase>      UnitArray;
00087     typedef NumericalArray2D<SampleType>                BufferArrayType;
00088     typedef NullChannelInternal<SampleType>             NullInternal;
00089     typedef Variable<SampleType>                        VariableType;
00090     typedef AtomicValue<SampleType>                     AtomicType;
00091     typedef Variable<AtomicType&>                       AtomicVariableType;
00092     typedef AtomicVariableUnit<SampleType>              AtomicVariableUnitType;
00093     typedef typename ChannelBase<SampleType>::Receiver  Receiver;
00094 
00095     typedef typename BinaryOpFunctionsHelper<SampleType>::BinaryOpFunctionsType BinaryOpFunctionsType;
00096     typedef typename UnaryOpFunctionsHelper<SampleType>::UnaryOpFunctionsType UnaryOpFunctionsType;
00097 
00098     typedef typename TypeUtility<SampleType>::IndexType IndexType;
00099 
00100 public:
00101     typedef ObjectArrayInternal<ChannelType>    Internal;    
00102     typedef UnitType                            Base;    
00103     typedef WeakPointerContainer<UnitBase>      Weak;
00104     typedef NumericalArray<SampleType>          Buffer;
00105     typedef InputDictionary                     Inputs;    
00106     
00107     class InitialUnit
00108     {
00109         public:
00110                 InitialUnit() throw() 
00111         :   value (UnitBase::getNull()), 
00112             valid (false) 
00113         { 
00114         }
00115         
00116                 InitialUnit (UnitBase const& initialValue) throw()
00117                 :       value (initialValue), 
00118             valid (true) 
00119                 { 
00120                 }
00121         
00122                 template<class OtherType>
00123                 InitialUnit (OtherType const& initialValue) throw()
00124                 :       value (initialValue), 
00125             valid (true) 
00126                 { 
00127                 }
00128                 
00129                 const UnitBase value;
00130                 const bool valid;
00131         
00132         private:
00133                 InitialUnit& operator= (InitialUnit const&); // to prevent assignment and MSVC complaining!
00134         };
00135 
00136     
00139     inline UnitBase() throw()
00140     :   Base (ChannelType())
00141     {
00142     }
00143         
00144     explicit UnitBase (Internal* internal) throw()
00145     :   Base (internal)
00146     {
00147     }
00148     
00149     UnitBase (Dynamic const& other) throw()
00150     :   Base (other.as<UnitBase>().getInternal())
00151     {
00152     }          
00153 
00157     static UnitBase fromWeak (Weak const& weak) throw()
00158     {
00159         return weak.fromWeak();
00160     }       
00161     
00162     static const UnitBase& getNull() throw()
00163         {
00164                 static UnitBase null;
00165                 return null;
00166         }                                   
00167     
00168     static const UnitBase emptyChannels (const int numChannels) throw()
00169     {
00170         return UnitBase::withSize (numChannels);
00171     }
00172     
00174     UnitBase (ChannelType const& channel) throw()
00175     :   UnitType (channel)
00176     {
00177         this->atUnchecked (0).initChannel (0);
00178     }
00179     
00183     template<class ValueType>
00184     inline UnitBase (ValueType const& valueInit) throw()
00185     :   UnitType (ChannelType (valueInit))
00186     {
00187         this->atUnchecked (0).initChannel (0);
00188     }
00189     
00193     template<class ValueType>
00194     inline UnitBase (NumericalArray<ValueType> const& values) throw()
00195     :   UnitType (UnitType::template collect<ChannelType> (values))
00196     {
00197         for (int i = 0; i < this->getNumChannels(); ++i)
00198             this->atUnchecked (i).initChannel (i);
00199     }    
00200     
00201     inline UnitBase (VariableType const& variable) throw()
00202     :   UnitType (ParamUnit<SampleType>::kr (variable))
00203     {
00204     }
00205     
00206     UnitBase (AtomicVariableType const& variable) throw()
00207     :   UnitType (AtomicVariableUnitType::kr (variable))
00208     {
00209     }
00210         
00211     UnitBase (NumericalArray<VariableType> const& variables) throw()
00212     :   UnitType (UnitType::withSize (variables.length()))
00213     {
00214         for (int i = 0; i < this->getNumChannels(); ++i) 
00215         {
00216             UnitBase variable = variables.atUnchecked (i);
00217             this->put (i, variable.atUnchecked (0));
00218         }
00219     }
00220     
00222     inline UnitBase (UnitBase const& copy) throw()
00223         :       UnitType (static_cast<UnitType const&> (copy))
00224         {
00225         }                
00226     
00227     
00228     template<template <typename> class OtherUnitType, class OtherSampleType>
00229     inline UnitBase (OtherUnitType<OtherSampleType> const& other)
00230     :   UnitType (TypeUnit<SampleType,OtherSampleType>::ar (other))
00231     {
00232     }
00233     
00234     UnitBase (UnitBase const& i00,
00235               UnitBase const& i01) throw()
00236     :   Base (i00, i01)
00237     {
00238     }
00239     
00240 private:
00241     static int countValidChannels (InitialUnit const& i00,
00242                                    InitialUnit const& i01,
00243                                    InitialUnit const& i02,
00244                                    InitialUnit const& i03) throw()
00245     {
00246         int numChannels = 0;
00247         
00248         if (i00.valid) numChannels += i00.value.getNumChannels();
00249         if (i01.valid) numChannels += i01.value.getNumChannels();
00250         if (i02.valid) numChannels += i02.value.getNumChannels();        
00251         if (i03.valid) numChannels += i03.value.getNumChannels();
00252 
00253         return numChannels;
00254     }
00255     
00256 public:
00257     UnitBase (InitialUnit const& i00,
00258               InitialUnit const& i01,
00259               InitialUnit const& i02,
00260               InitialUnit const& i03 = InitialUnit()) throw()
00261         :       Base (NumericalArraySpec (countValidChannels (i00, i01, i02, i03), false))
00262         {
00263         int i;
00264         ChannelType* array = this->getArray();
00265         
00266         if (i00.valid) { for (i = 0; i < i00.value.getNumChannels(); ++i) *array++ = i00.value.atUnchecked (i); }
00267         if (i01.valid) { for (i = 0; i < i01.value.getNumChannels(); ++i) *array++ = i01.value.atUnchecked (i); }
00268         if (i02.valid) { for (i = 0; i < i02.value.getNumChannels(); ++i) *array++ = i02.value.atUnchecked (i); }
00269         if (i03.valid) { for (i = 0; i < i03.value.getNumChannels(); ++i) *array++ = i03.value.atUnchecked (i); }
00270         }
00271     
00272 private:
00273     static int countValidChannels (InitialUnit const& i00,
00274                                    InitialUnit const& i01,
00275                                    InitialUnit const& i02,
00276                                    InitialUnit const& i03,
00277                                    InitialUnit const& i04,
00278                                    InitialUnit const& i05,
00279                                    InitialUnit const& i06,
00280                                    InitialUnit const& i07) throw()
00281     {
00282         int numChannels = 0;
00283         
00284         if (i00.valid) numChannels += i00.value.getNumChannels();
00285         if (i01.valid) numChannels += i01.value.getNumChannels();
00286         if (i02.valid) numChannels += i02.value.getNumChannels();        
00287         if (i03.valid) numChannels += i03.value.getNumChannels();
00288         if (i04.valid) numChannels += i04.value.getNumChannels();
00289         if (i05.valid) numChannels += i05.value.getNumChannels();
00290         if (i06.valid) numChannels += i06.value.getNumChannels();
00291         if (i07.valid) numChannels += i07.value.getNumChannels();
00292         
00293         return numChannels;
00294     }
00295     
00296 public:
00297     UnitBase (InitialUnit const& i00,
00298               InitialUnit const& i01,
00299               InitialUnit const& i02,
00300               InitialUnit const& i03,
00301               InitialUnit const& i04,
00302               InitialUnit const& i05 = InitialUnit(),
00303               InitialUnit const& i06 = InitialUnit(),
00304               InitialUnit const& i07 = InitialUnit()) throw()
00305         :       Base (NumericalArraySpec (countValidChannels (i00, i01, i02, i03,
00306                                                       i04, i05, i06, i07), false))
00307         {
00308         int i;
00309         ChannelType* array = this->getArray();
00310         
00311         if (i00.valid) { for (i = 0; i < i00.value.getNumChannels(); ++i) *array++ = i00.value.atUnchecked (i); }
00312         if (i01.valid) { for (i = 0; i < i01.value.getNumChannels(); ++i) *array++ = i01.value.atUnchecked (i); }
00313         if (i02.valid) { for (i = 0; i < i02.value.getNumChannels(); ++i) *array++ = i02.value.atUnchecked (i); }
00314         if (i03.valid) { for (i = 0; i < i03.value.getNumChannels(); ++i) *array++ = i03.value.atUnchecked (i); }
00315         if (i04.valid) { for (i = 0; i < i04.value.getNumChannels(); ++i) *array++ = i04.value.atUnchecked (i); }
00316         if (i05.valid) { for (i = 0; i < i05.value.getNumChannels(); ++i) *array++ = i05.value.atUnchecked (i); }
00317         if (i06.valid) { for (i = 0; i < i06.value.getNumChannels(); ++i) *array++ = i06.value.atUnchecked (i); }
00318         if (i07.valid) { for (i = 0; i < i07.value.getNumChannels(); ++i) *array++ = i07.value.atUnchecked (i); }
00319         }
00320     
00321 private:
00322     static int countValidChannels (InitialUnit const& i00,
00323                                    InitialUnit const& i01,
00324                                    InitialUnit const& i02,
00325                                    InitialUnit const& i03,
00326                                    InitialUnit const& i04,
00327                                    InitialUnit const& i05,
00328                                    InitialUnit const& i06,
00329                                    InitialUnit const& i07,
00330                                    InitialUnit const& i08,
00331                                    InitialUnit const& i09,
00332                                    InitialUnit const& i10,
00333                                    InitialUnit const& i11,
00334                                    InitialUnit const& i12,
00335                                    InitialUnit const& i13,
00336                                    InitialUnit const& i14,
00337                                    InitialUnit const& i15) throw()
00338     {
00339         int numChannels = 0;
00340         
00341         if (i00.valid) numChannels += i00.value.getNumChannels();
00342         if (i01.valid) numChannels += i01.value.getNumChannels();
00343         if (i02.valid) numChannels += i02.value.getNumChannels();        
00344         if (i03.valid) numChannels += i03.value.getNumChannels();
00345         if (i04.valid) numChannels += i04.value.getNumChannels();
00346         if (i05.valid) numChannels += i05.value.getNumChannels();
00347         if (i06.valid) numChannels += i06.value.getNumChannels();
00348         if (i07.valid) numChannels += i07.value.getNumChannels();
00349         if (i08.valid) numChannels += i08.value.getNumChannels();
00350         if (i09.valid) numChannels += i09.value.getNumChannels();
00351         if (i10.valid) numChannels += i10.value.getNumChannels();
00352         if (i11.valid) numChannels += i11.value.getNumChannels();
00353         if (i12.valid) numChannels += i12.value.getNumChannels();
00354         if (i13.valid) numChannels += i13.value.getNumChannels();
00355         if (i14.valid) numChannels += i14.value.getNumChannels();
00356         if (i15.valid) numChannels += i15.value.getNumChannels();
00357         
00358         return numChannels;
00359     }
00360     
00361 public:
00362     UnitBase (InitialUnit const &i00,
00363               InitialUnit const &i01,
00364               InitialUnit const &i02,
00365               InitialUnit const &i03,
00366               InitialUnit const &i04,
00367               InitialUnit const &i05,
00368               InitialUnit const &i06,
00369               InitialUnit const &i07,
00370               InitialUnit const &i08,
00371               InitialUnit const &i09 = InitialUnit(),
00372               InitialUnit const &i10 = InitialUnit(),
00373               InitialUnit const &i11 = InitialUnit(),
00374               InitialUnit const &i12 = InitialUnit(),
00375               InitialUnit const &i13 = InitialUnit(),
00376               InitialUnit const &i14 = InitialUnit(),
00377               InitialUnit const &i15 = InitialUnit()) throw()
00378         :       Base (NumericalArraySpec (countValidChannels (i00, i01, i02, i03,
00379                                                       i04, i05, i06, i07,
00380                                                       i08, i09, i10, i11,
00381                                                       i12, i13, i14, i15), false))
00382         {
00383         int i;
00384         ChannelType* array = this->getArray();
00385         
00386         if (i00.valid) { for (i = 0; i < i00.value.getNumChannels(); ++i) *array++ = i00.value.atUnchecked (i); }
00387         if (i01.valid) { for (i = 0; i < i01.value.getNumChannels(); ++i) *array++ = i01.value.atUnchecked (i); }
00388         if (i02.valid) { for (i = 0; i < i02.value.getNumChannels(); ++i) *array++ = i02.value.atUnchecked (i); }
00389         if (i03.valid) { for (i = 0; i < i03.value.getNumChannels(); ++i) *array++ = i03.value.atUnchecked (i); }
00390         if (i04.valid) { for (i = 0; i < i04.value.getNumChannels(); ++i) *array++ = i04.value.atUnchecked (i); }
00391         if (i05.valid) { for (i = 0; i < i05.value.getNumChannels(); ++i) *array++ = i05.value.atUnchecked (i); }
00392         if (i06.valid) { for (i = 0; i < i06.value.getNumChannels(); ++i) *array++ = i06.value.atUnchecked (i); }
00393         if (i07.valid) { for (i = 0; i < i07.value.getNumChannels(); ++i) *array++ = i07.value.atUnchecked (i); }
00394         if (i08.valid) { for (i = 0; i < i08.value.getNumChannels(); ++i) *array++ = i08.value.atUnchecked (i); }
00395         if (i09.valid) { for (i = 0; i < i09.value.getNumChannels(); ++i) *array++ = i09.value.atUnchecked (i); }
00396         if (i10.valid) { for (i = 0; i < i10.value.getNumChannels(); ++i) *array++ = i10.value.atUnchecked (i); }
00397         if (i11.valid) { for (i = 0; i < i11.value.getNumChannels(); ++i) *array++ = i11.value.atUnchecked (i); }
00398         if (i12.valid) { for (i = 0; i < i12.value.getNumChannels(); ++i) *array++ = i12.value.atUnchecked (i); }
00399         if (i13.valid) { for (i = 0; i < i13.value.getNumChannels(); ++i) *array++ = i13.value.atUnchecked (i); }
00400         if (i14.valid) { for (i = 0; i < i14.value.getNumChannels(); ++i) *array++ = i14.value.atUnchecked (i); }
00401         if (i15.valid) { for (i = 0; i < i15.value.getNumChannels(); ++i) *array++ = i15.value.atUnchecked (i); }
00402     }
00403     
00404 private:
00405     static int countValidChannels (InitialUnit const& i00,
00406                                    InitialUnit const& i01,
00407                                    InitialUnit const& i02,
00408                                    InitialUnit const& i03,
00409                                    InitialUnit const& i04,
00410                                    InitialUnit const& i05,
00411                                    InitialUnit const& i06,
00412                                    InitialUnit const& i07,
00413                                    InitialUnit const& i08,
00414                                    InitialUnit const& i09,
00415                                    InitialUnit const& i10,
00416                                    InitialUnit const& i11,
00417                                    InitialUnit const& i12,
00418                                    InitialUnit const& i13,
00419                                    InitialUnit const& i14,
00420                                    InitialUnit const& i15,
00421                                    InitialUnit const& i16,
00422                                    InitialUnit const& i17,
00423                                    InitialUnit const& i18,
00424                                    InitialUnit const& i19,
00425                                    InitialUnit const& i20,
00426                                    InitialUnit const& i21,
00427                                    InitialUnit const& i22,
00428                                    InitialUnit const& i23,
00429                                    InitialUnit const& i24,
00430                                    InitialUnit const& i25,
00431                                    InitialUnit const& i26,
00432                                    InitialUnit const& i27,
00433                                    InitialUnit const& i28,
00434                                    InitialUnit const& i29,
00435                                    InitialUnit const& i30,
00436                                    InitialUnit const& i31) throw()
00437     {
00438         int numChannels = 0;
00439         
00440         if (i00.valid) numChannels += i00.value.getNumChannels();
00441         if (i01.valid) numChannels += i01.value.getNumChannels();
00442         if (i02.valid) numChannels += i02.value.getNumChannels();        
00443         if (i03.valid) numChannels += i03.value.getNumChannels();
00444         if (i04.valid) numChannels += i04.value.getNumChannels();
00445         if (i05.valid) numChannels += i05.value.getNumChannels();
00446         if (i06.valid) numChannels += i06.value.getNumChannels();
00447         if (i07.valid) numChannels += i07.value.getNumChannels();
00448         if (i08.valid) numChannels += i08.value.getNumChannels();
00449         if (i09.valid) numChannels += i09.value.getNumChannels();
00450         if (i10.valid) numChannels += i10.value.getNumChannels();
00451         if (i11.valid) numChannels += i11.value.getNumChannels();
00452         if (i12.valid) numChannels += i12.value.getNumChannels();
00453         if (i13.valid) numChannels += i13.value.getNumChannels();
00454         if (i14.valid) numChannels += i14.value.getNumChannels();
00455         if (i15.valid) numChannels += i15.value.getNumChannels();
00456         if (i16.valid) numChannels += i16.value.getNumChannels();
00457         if (i17.valid) numChannels += i17.value.getNumChannels();
00458         if (i18.valid) numChannels += i18.value.getNumChannels();
00459         if (i19.valid) numChannels += i19.value.getNumChannels();
00460         if (i20.valid) numChannels += i20.value.getNumChannels();
00461         if (i21.valid) numChannels += i21.value.getNumChannels();
00462         if (i22.valid) numChannels += i22.value.getNumChannels();
00463         if (i23.valid) numChannels += i23.value.getNumChannels();
00464         if (i24.valid) numChannels += i24.value.getNumChannels();
00465         if (i25.valid) numChannels += i25.value.getNumChannels();
00466         if (i26.valid) numChannels += i26.value.getNumChannels();
00467         if (i27.valid) numChannels += i27.value.getNumChannels();
00468         if (i28.valid) numChannels += i28.value.getNumChannels();
00469         if (i29.valid) numChannels += i29.value.getNumChannels();
00470         if (i30.valid) numChannels += i30.value.getNumChannels();
00471         if (i31.valid) numChannels += i31.value.getNumChannels();
00472         
00473         return numChannels;
00474     }
00475     
00476 public:
00477     UnitBase (InitialUnit const &i00,
00478               InitialUnit const &i01,
00479               InitialUnit const &i02,
00480               InitialUnit const &i03,
00481               InitialUnit const &i04,
00482               InitialUnit const &i05,
00483               InitialUnit const &i06,
00484               InitialUnit const &i07,
00485               InitialUnit const &i08,
00486               InitialUnit const &i09,
00487               InitialUnit const &i10,
00488               InitialUnit const &i11,
00489               InitialUnit const &i12,
00490               InitialUnit const &i13,
00491               InitialUnit const &i14,
00492               InitialUnit const &i15,
00493               InitialUnit const &i16,
00494               InitialUnit const &i17 = InitialUnit(),
00495               InitialUnit const &i18 = InitialUnit(),
00496               InitialUnit const &i19 = InitialUnit(),
00497               InitialUnit const &i20 = InitialUnit(),
00498               InitialUnit const &i21 = InitialUnit(),
00499               InitialUnit const &i22 = InitialUnit(),
00500               InitialUnit const &i23 = InitialUnit(),
00501               InitialUnit const &i24 = InitialUnit(),
00502               InitialUnit const &i25 = InitialUnit(),
00503               InitialUnit const &i26 = InitialUnit(),
00504               InitialUnit const &i27 = InitialUnit(),
00505               InitialUnit const &i28 = InitialUnit(),
00506               InitialUnit const &i29 = InitialUnit(),
00507               InitialUnit const &i30 = InitialUnit(),
00508               InitialUnit const &i31 = InitialUnit()) throw()
00509         :       Base (NumericalArraySpec (countValidChannels (i00, i01, i02, i03,
00510                                                       i04, i05, i06, i07,
00511                                                       i08, i09, i10, i11,
00512                                                       i12, i13, i14, i15,
00513                                                       i16, i17, i18, i19,
00514                                                       i20, i21, i22, i23,
00515                                                       i24, i25, i26, i27, 
00516                                                       i28, i29, i30, i31), false))
00517         {
00518         int i;
00519         ChannelType* array = this->getArray();
00520         
00521         if (i00.valid) { for (i = 0; i < i00.value.getNumChannels(); ++i) *array++ = i00.value.atUnchecked (i); }
00522         if (i01.valid) { for (i = 0; i < i01.value.getNumChannels(); ++i) *array++ = i01.value.atUnchecked (i); }
00523         if (i02.valid) { for (i = 0; i < i02.value.getNumChannels(); ++i) *array++ = i02.value.atUnchecked (i); }
00524         if (i03.valid) { for (i = 0; i < i03.value.getNumChannels(); ++i) *array++ = i03.value.atUnchecked (i); }
00525         if (i04.valid) { for (i = 0; i < i04.value.getNumChannels(); ++i) *array++ = i04.value.atUnchecked (i); }
00526         if (i05.valid) { for (i = 0; i < i05.value.getNumChannels(); ++i) *array++ = i05.value.atUnchecked (i); }
00527         if (i06.valid) { for (i = 0; i < i06.value.getNumChannels(); ++i) *array++ = i06.value.atUnchecked (i); }
00528         if (i07.valid) { for (i = 0; i < i07.value.getNumChannels(); ++i) *array++ = i07.value.atUnchecked (i); }
00529         if (i08.valid) { for (i = 0; i < i08.value.getNumChannels(); ++i) *array++ = i08.value.atUnchecked (i); }
00530         if (i09.valid) { for (i = 0; i < i09.value.getNumChannels(); ++i) *array++ = i09.value.atUnchecked (i); }
00531         if (i10.valid) { for (i = 0; i < i10.value.getNumChannels(); ++i) *array++ = i10.value.atUnchecked (i); }
00532         if (i11.valid) { for (i = 0; i < i11.value.getNumChannels(); ++i) *array++ = i11.value.atUnchecked (i); }
00533         if (i12.valid) { for (i = 0; i < i12.value.getNumChannels(); ++i) *array++ = i12.value.atUnchecked (i); }
00534         if (i13.valid) { for (i = 0; i < i13.value.getNumChannels(); ++i) *array++ = i13.value.atUnchecked (i); }
00535         if (i14.valid) { for (i = 0; i < i14.value.getNumChannels(); ++i) *array++ = i14.value.atUnchecked (i); }
00536         if (i15.valid) { for (i = 0; i < i15.value.getNumChannels(); ++i) *array++ = i15.value.atUnchecked (i); }
00537         if (i16.valid) { for (i = 0; i < i16.value.getNumChannels(); ++i) *array++ = i16.value.atUnchecked (i); }
00538         if (i17.valid) { for (i = 0; i < i17.value.getNumChannels(); ++i) *array++ = i17.value.atUnchecked (i); }
00539         if (i18.valid) { for (i = 0; i < i18.value.getNumChannels(); ++i) *array++ = i18.value.atUnchecked (i); }
00540         if (i19.valid) { for (i = 0; i < i19.value.getNumChannels(); ++i) *array++ = i19.value.atUnchecked (i); }
00541         if (i20.valid) { for (i = 0; i < i20.value.getNumChannels(); ++i) *array++ = i20.value.atUnchecked (i); }
00542         if (i21.valid) { for (i = 0; i < i21.value.getNumChannels(); ++i) *array++ = i21.value.atUnchecked (i); }
00543         if (i22.valid) { for (i = 0; i < i22.value.getNumChannels(); ++i) *array++ = i22.value.atUnchecked (i); }
00544         if (i23.valid) { for (i = 0; i < i23.value.getNumChannels(); ++i) *array++ = i23.value.atUnchecked (i); }
00545         if (i24.valid) { for (i = 0; i < i24.value.getNumChannels(); ++i) *array++ = i24.value.atUnchecked (i); }
00546         if (i25.valid) { for (i = 0; i < i25.value.getNumChannels(); ++i) *array++ = i25.value.atUnchecked (i); }
00547         if (i26.valid) { for (i = 0; i < i26.value.getNumChannels(); ++i) *array++ = i26.value.atUnchecked (i); }
00548         if (i27.valid) { for (i = 0; i < i27.value.getNumChannels(); ++i) *array++ = i27.value.atUnchecked (i); }
00549         if (i28.valid) { for (i = 0; i < i28.value.getNumChannels(); ++i) *array++ = i28.value.atUnchecked (i); }
00550         if (i29.valid) { for (i = 0; i < i29.value.getNumChannels(); ++i) *array++ = i29.value.atUnchecked (i); }
00551         if (i30.valid) { for (i = 0; i < i30.value.getNumChannels(); ++i) *array++ = i30.value.atUnchecked (i); }
00552         if (i31.valid) { for (i = 0; i < i31.value.getNumChannels(); ++i) *array++ = i31.value.atUnchecked (i); }
00553     }
00554     
00555     UnitBase (ChannelArrayType const& copy) throw()
00556         :       UnitType (static_cast<UnitType const&> (copy))
00557         {
00558         }    
00559     
00561     UnitBase& operator= (UnitBase const& other) throw()
00562         {
00563                 if (this != &other)
00564             this->setInternal (other.getInternal());
00565         
00566         return *this;
00567         }
00568     
00570     UnitBase& operator= (ChannelType const& other) throw()
00571         {
00572                 return operator= (UnitBase (other));
00573         }
00574     
00576     UnitBase& operator= (UnitType const& other) throw()
00577         {
00578                 return operator= (static_cast<UnitBase const&> (other));
00579         }
00580     
00582     UnitBase& operator= (ObjectArray<ChannelType> const& other) throw()
00583         {
00584                 return operator= (static_cast<UnitBase const&> (other));
00585         }    
00586     
00588     inline operator const ChannelType& () const throw()
00589     {
00590         plonk_assert (this->getNumChannels() == 1);
00591         return this->atUnchecked (0);
00592     }
00593     
00595     inline operator ChannelType& () throw()
00596     {
00597         plonk_assert (this->getNumChannels() == 1);
00598         return this->atUnchecked (0);
00599     }
00600     
00603     template<class ChannelInternalClassType>
00604     static inline UnitBase createFromInputs (Inputs const& inputs, 
00605                                              typename ChannelInternalClassType::Data const& data,
00606                                              BlockSize const& preferredBlockSize,
00607                                              SampleRate const& preferredSampleRate) throw()
00608     {        
00609         Inputs mainInputs = inputs;
00610         mainInputs.resetExpiredUnits();
00611 
00612         const Dynamic add = mainInputs.remove (IOKey::Add);
00613         const Dynamic mul = mainInputs.remove (IOKey::Multiply);
00614                         
00615         const int numChannels = mainInputs.getMaxNumChannels();
00616         UnitBase result (UnitBase::withSize (numChannels));
00617         
00618         for (int i = 0; i < numChannels; ++i) 
00619         {
00620             ChannelInternalType* internal = new ChannelInternalClassType (mainInputs, 
00621                                                                           data, 
00622                                                                           preferredBlockSize, 
00623                                                                           preferredSampleRate);
00624             
00625             plonk_assert ((internal->isProxyOwner() == false) || (internal->getNumChannels() == 1));
00626 
00627             internal->initChannel (i);
00628                         
00629             result.put (i, ChannelType (internal));
00630         }
00631         
00632         return applyMulAdd (result, UnitBase (mul), UnitBase (add));
00633     }     
00634     
00637     template<class ProxyOwnerChannelInternalClassType>
00638     static inline UnitBase proxiesFromInputs (Inputs const& inputs, 
00639                                               typename ProxyOwnerChannelInternalClassType::Data const& data,
00640                                               BlockSize const& preferredBlockSize,
00641                                               SampleRate const& preferredSampleRate) throw()
00642     {        
00643         Inputs mainInputs = inputs;
00644         mainInputs.resetExpiredUnits();
00645         
00646         const Dynamic add = mainInputs.remove (IOKey::Add);
00647         const Dynamic mul = mainInputs.remove (IOKey::Multiply);
00648                 
00649         ChannelArrayType channels;        
00650         new ProxyOwnerChannelInternalClassType (mainInputs, 
00651                                                 data, 
00652                                                 preferredBlockSize, 
00653                                                 preferredSampleRate, 
00654                                                 channels);
00655         const int numChannels = channels.length();
00656         for (int i = 0; i < numChannels; ++i)
00657             channels.atUnchecked (i).initChannel (i);
00658         
00659         UnitBase result (channels);        
00660         return applyMulAdd (result, UnitBase (mul), UnitBase (add));
00661     }        
00662     
00669     static inline UnitBase applyMulAdd (UnitBase const& mainUnit, 
00670                                         UnitBase const& mul,
00671                                         UnitBase const& add) throw()
00672     {
00673         UnitBase result = mainUnit;
00674         
00675         bool hasMul = true;
00676         bool hasAdd = true;
00677                                 
00678         if (mul.isNull() || (mul.isConstant() && (mul.getValue (0) == SampleType (1))))
00679             hasMul = false;
00680         
00681         if (add.isNull() || (add.isConstant() && (add.getValue (0) == SampleType (0))))
00682             hasAdd = false;
00683         
00684         if (hasMul && hasAdd)
00685             result = MulAddUnit<SampleType>::ar (result, mul, add, BlockSize::noPreference(), SampleRate::noPreference());
00686         else if (hasMul)
00687             result *= mul;
00688         else if (hasAdd)
00689             result += add;
00690             
00691         return result;        
00692     }
00693     
00696     UnitBase ar (const Interp::TypeCode interpType,
00697                  BlockSize const& preferredBlockSize = BlockSize::getDefault(),
00698                  SampleRate const& preferredSampleRate = SampleRate::getDefault()) const throw()
00699     {
00700         typedef UnitBase<IndexType> RateUnitType;
00701         const RateUnitType& rateOne (Math<RateUnitType>::get1());
00702 
00703         switch (interpType)
00704         {
00705             case Interp::Linear:    return ResampleUnit<SampleType,Interp::Linear>::ar (*this, rateOne, preferredBlockSize, preferredSampleRate);
00706             case Interp::Lagrange3: return ResampleUnit<SampleType,Interp::Lagrange3>::ar (*this, rateOne, preferredBlockSize, preferredSampleRate);
00707             default:                return ResampleUnit<SampleType,Interp::Linear>::ar (*this, rateOne, preferredBlockSize, preferredSampleRate);
00708         }
00709     }
00710     
00713     inline UnitBase ar() const throw()
00714     {
00715         return ResampleUnit<SampleType,Interp::Linear>::ar (*this);
00716     }
00717     
00719     UnitBase kr (const Interp::TypeCode interpType) const throw()
00720     {        
00721         switch (interpType)
00722         {
00723             case Interp::Linear:    return ResampleUnit<SampleType,Interp::Linear>::kr (*this);
00724             case Interp::Lagrange3: return ResampleUnit<SampleType,Interp::Lagrange3>::kr (*this);
00725             default:                return ResampleUnit<SampleType,Interp::Linear>::kr (*this);
00726         }
00727     }
00728     
00730     inline UnitBase kr() const throw()
00731     {
00732         return ResampleUnit<SampleType,Interp::Linear>::kr (*this);
00733     }
00734     
00735 //    inline UnitBase reblock (BlockSize const& newBlockSize) const throw()
00736 //    {
00737 //        typedef UnitBase<IndexType> RateUnitType;
00738 //        const RateUnitType& rateOne (Math<RateUnitType>::get1());
00739 //        return ResampleUnit<SampleType,Interp::Linear>::ar (*this, rateOne, newBlockSize);
00740 //    }
00741 //    inline UnitBase reblock() const throw()
00742 //    {
00743 //        return ar();
00744 //    }
00745 
00746 
00747     inline UnitBase reblock (BlockSize const& newBlockSize) const throw()
00748     {
00749         return ReblockUnit<SampleType>::ar (*this, newBlockSize);
00750     }
00751     
00752     inline UnitBase reblock() const throw()
00753     {
00754         return ReblockUnit<SampleType>::ar (*this, BlockSize::getDefault());
00755     }
00756     
00757     inline UnitBase lag (UnitBase const& duration) const throw()
00758     {
00759         return LagUnit<SampleType>::ar (*this, duration);
00760     }
00761 
00762     inline UnitBase lag() const throw()
00763     {
00764         return LagUnit<SampleType>::ar (*this);
00765     }
00766     
00767     inline UnitBase dc (UnitBase const& control) const throw()
00768     {
00769         return DCUnit<SampleType>::ar (*this, control);
00770     }
00771     
00772     inline UnitBase dc() const throw()
00773     {
00774         return DCUnit<SampleType>::ar (*this);
00775     }
00776 
00778     inline UnitBase mix() const throw()
00779     {
00780         return MixerUnit<SampleType>::ar (*this, true);
00781     }
00782     
00785     inline UnitBase mixBarrier() const throw()
00786     {
00787         return MixerUnit<SampleType>::ar (*this, false);
00788     }
00789     
00791     UnitBase overlapMake (DoubleVariable const& overlap = Math<DoubleVariable>::get0_5(), const bool zeroPad = false) const throw()
00792     {
00793         return OverlapMakeUnit<SampleType>::ar (*this, overlap, zeroPad);
00794     }
00795     
00797     UnitBase overlapZeroPad (DoubleVariable const& overlap = Math<DoubleVariable>::get0_5()) const throw()
00798     {
00799         return OverlapMakeUnit<SampleType>::ar (*this, overlap, true);
00800     }
00801     
00803     UnitBase overlapMix (DoubleVariable const& overlap = Math<DoubleVariable>::get0_5()) const throw()
00804     {
00805         return OverlapMixUnit<SampleType>::ar (*this, overlap);
00806     }
00807     
00809     template<PLONK_BINARYOPFUNCTION(SampleType, op)>
00810     UnitBase binary (UnitBase const& rightOperand) const throw() 
00811     {        
00812         typedef BinaryOpChannelInternal<SampleType,op>      ChannelInternalClassType;
00813         typedef typename ChannelInternalClassType::Data     Data;
00814                 
00815         Inputs inputs;
00816         inputs.put (IOKey::LeftOperand, *this);
00817         inputs.put (IOKey::RightOperand, rightOperand);
00818         
00819         Data data = { -1.0, -1.0 }; // dummy sample rate data
00820         
00821         return createFromInputs<ChannelInternalClassType> (inputs, 
00822                                                            data, 
00823                                                            BlockSize::noPreference(), 
00824                                                            SampleRate::noPreference());
00825     }
00826 
00828     template<PLONK_UNARYOPFUNCTION(SampleType, op)>
00829     UnitBase unary() const throw() 
00830     {        
00831         typedef UnaryOpChannelInternal<SampleType,op>       ChannelInternalClassType;
00832         typedef typename ChannelInternalClassType::Data     Data;
00833         
00834         Inputs inputs;
00835         inputs.put (IOKey::Generic, *this);
00836         
00837         Data data = { -1.0, -1.0 }; // dummy sample rate data
00838         
00839         return createFromInputs<ChannelInternalClassType> (inputs, 
00840                                                            data, 
00841                                                            BlockSize::noPreference(), 
00842                                                            SampleRate::noPreference());
00843     }
00844      
00845     PLONK_BINARYOPS(UnitBase);
00846     PLONK_UNARYOPS(UnitBase);
00847     
00849     inline UnitBase linlin (UnitBase const& inLow, UnitBase const& inHigh,
00850                             UnitBase const& outLow, UnitBase const& outHigh) const throw()
00851     {
00852         return plonk::linlin (*this, inLow, inHigh, outLow, outHigh);
00853     }
00854     
00856     inline UnitBase linlin (UnitBase const& outLow, UnitBase const& outHigh) const throw()
00857     {
00858         const SampleType peak (TypeUtility<SampleType>::getTypePeak());
00859         const SampleType peak2peak (peak * Math<SampleType>::get2());
00860         return plonk::linlin2 (*this, 
00861                                UnitBase (-peak), UnitBase (peak2peak), 
00862                                outLow, (outHigh - outLow));
00863     }
00864     
00867     inline UnitBase linexp (UnitBase const& inLow, UnitBase const& inHigh,
00868                             UnitBase const& outLow, UnitBase const& outHigh) const throw()
00869     {
00870         return plonk::linexp (*this, inLow, inHigh, outLow, outHigh);
00871     }
00872     
00875     inline UnitBase linexp (UnitBase const& outLow, UnitBase const& outHigh) const throw()
00876     {
00877         const SampleType peak (TypeUtility<SampleType>::getTypePeak());
00878         const SampleType peak2peak (peak * Math<SampleType>::get2());
00879         const SampleType reciprocalInRange (plonk::reciprocal (peak2peak));
00880         return plonk::linexp2 (*this, 
00881                                UnitBase (reciprocalInRange), UnitBase (-peak * reciprocalInRange), 
00882                                outLow, (outHigh / outLow));
00883     }
00884     
00886     inline UnitBase linsin (UnitBase const& inLow, UnitBase const& inHigh, 
00887                      UnitBase const& outLow, UnitBase const& outHigh) const throw()
00888     {
00889         return plonk::linsin (*this, inLow, inHigh, outLow, outHigh);
00890     }
00891     
00893     inline UnitBase linsin (UnitBase const& outLow, UnitBase const& outHigh) const throw()
00894     {
00895         const SampleType peak (TypeUtility<SampleType>::getTypePeak());
00896         return plonk::linsin2 (*this, UnitBase (-peak), UnitBase (peak), outLow, outHigh);
00897     }
00898     
00900     inline UnitBase linwelch (UnitBase const& inLow, UnitBase const& inHigh, 
00901                        UnitBase const& outLow, UnitBase const& outHigh) const throw()
00902     {
00903         return plonk::linwelch (*this, inLow, inHigh, outLow, outHigh);
00904     }
00905     
00907     inline UnitBase linwelch (UnitBase const& outLow, UnitBase const& outHigh) const throw()
00908     {
00909         const SampleType peak (TypeUtility<SampleType>::getTypePeak());
00910         return plonk::linwelch (*this, UnitBase (-peak), UnitBase (peak), outLow, outHigh);
00911     }
00912     
00915     inline UnitBase explin (UnitBase const& inLow, UnitBase const& inHigh, 
00916                      UnitBase const& outLow, UnitBase const& outHigh) const throw()
00917     {
00918         return plonk::explin (*this, inLow, inHigh, outLow, outHigh);
00919     }
00920         
00921 //    /** Create a array of units by concatenation. */
00922 //    const UnitArray operator<< (UnitType const& other) const throw()   { return UnitArray (*this, other); }
00923 //    
00924 //    /** Create a array of units by concatenation. */
00925 //      const UnitArray operator<< (UnitBase const& other) const throw()   { return UnitArray (*this, other); }
00926     
00928     UnitBase operator, (UnitType const& other) const throw();
00929     UnitBase operator, (UnitBase const& other) const throw();
00930     
00933     UnitBase& setLabel (Text const& unitId) throw()
00934     {
00935         const int numChannels = this->getNumChannels();
00936         ChannelType* channels = this->getArray();
00937         
00938         for (int i = 0; i < numChannels; ++i) 
00939             channels[i].setLabel (unitId);        
00940             
00941         return *this;
00942     }
00943 
00945     inline int getNumChannels() const throw() { return this->length(); }
00946     
00950     inline UnitBase getChannel (const int index) throw() { return this->wrapAt (index).getChannel (index); }
00951     
00955     inline UnitBase getChannel (const int index) const throw() { return this->copy().wrapAt (index).getChannel (index); }
00956 
00960     inline ChannelType getChannelObject (const int index) throw() { return this->wrapAt (index).getChannel (index); }
00961     
00965     inline ChannelType getChannelObject (const int index) const throw() { return this->copy().wrapAt (index).getChannel (index); }
00966     
00970     UnitBase operator[] (const int index) throw() { return this->getChannel (index); }
00971     
00975     UnitBase operator[] (const int index) const throw() { return this->getChannel (index); }
00976     
00979     UnitBase& put (const int index, UnitBase const& channel) throw()
00980     {
00981         plonk_assert (channel.getNumChannels() == 1); // channel MUST be only a single channel
00982         plonk_assert (index >= 0);
00983         plonk_assert (index < this->getNumChannels());
00984         
00985         this->getArray() [index] = channel.atUnchecked (0);
00986         return *this;
00987     }
00988     
00989     UnitBase flatten() const throw()
00990     {
00991         const int numChannels = this->getNumChannels();
00992         UnitBase result = UnitBase::emptyChannels(numChannels);
00993         
00994         for (int i = 0; i < numChannels; ++i)
00995             result.put (i, this->getChannel (i));
00996         
00997         return result;
00998     }
00999     
01000     UnitArray group (const int groupSize) const throw()
01001     {
01002                 return this->flatten().Base::group (groupSize);
01003     }
01004     
01006     BlockSize getMinBlockSize() const throw();
01007     
01009     BlockSize getMaxBlockSize() const throw();
01010         
01012     inline BlockSize getBlockSize (const int index) const throw()            { return this->wrapAt (index).getBlockSize(); }
01013 
01015     void setBlockSize (BlockSize const& newBlockSize) throw()
01016     {
01017         const int numChannels = this->getNumChannels();
01018         ChannelType* channels = this->getArray();
01019         
01020         for (int i = 0; i < numChannels; ++i) 
01021             channels[i].setBlockSize (newBlockSize);        
01022     }
01023     
01025     BlockSizes getBlockSizes() const throw()
01026     {
01027         BlockSizes result (BlockSizes::withSize (this->getNumChannels()));
01028         
01029         for (int i = 0; i < this->getNumChannels(); ++i)
01030             result.put (i, this->getBlockSize (i));
01031         
01032         return result;
01033     }
01034     
01036     SampleRate getMinSampleRate() const throw();
01037     
01039     SampleRate getMaxSampleRate() const throw();
01040         
01043     inline SampleRate getSampleRate (const int index) const throw()          { return this->wrapAt (index).getSampleRate(); }
01044     
01046     void setSampleRate (SampleRate const& newSampleRate) throw()
01047     {
01048         const int numChannels = this->getNumChannels();
01049         ChannelType* channels = this->getArray();
01050         
01051         for (int i = 0; i < numChannels; ++i) 
01052             channels[i].setSampleRate (newSampleRate);        
01053     }   
01054     
01056     SampleRates getSampleRates() const throw()
01057     {
01058         SampleRates result (SampleRates::withSize (this->getNumChannels()));
01059         
01060         for (int i = 0; i < this->getNumChannels(); ++i)
01061             result.put (i, this->getSampleRate (i));
01062         
01063         return result;
01064     }
01065     
01066     inline double getSampleDurationInTicks (const int index) const throw()         { return this->wrapAt (index)->getSampleDurationInTicks(); }
01067     inline double getBlockDurationInTicks (const int index) const throw()          { return this->wrapAt (index)->getBlockDurationInTicks(); }
01068     
01069     inline const DoubleVariable& getOverlap (const int index) const throw()        { return this->wrapAt (index).getOverlap(); }
01070     inline DoubleVariable& getOverlap (const int index) throw()                    { return this->wrapAt (index).getOverlap(); }
01071     
01072     inline bool channelsHaveSameOverlap() const throw()
01073     {
01074         const int numChannels = this->getNumChannels();
01075         plonk_assert (numChannels > 0);
01076 
01077         const ChannelType* channels = this->getArray();
01078         DoubleVariable overlap = channels[0].getOverlap();
01079         
01080         for (int i = 1; i < numChannels; ++i)
01081             if (channels[i].getOverlap() != overlap)
01082                 return false;
01083         
01084         return true;
01085     }
01086     
01087     inline bool channelsHaveSameBlockSize() const throw()
01088     {
01089         const int numChannels = this->getNumChannels();
01090         plonk_assert (numChannels > 0);
01091         
01092         const ChannelType* channels = this->getArray();
01093         BlockSize blockSize = channels[0].getBlockSize();
01094         
01095         for (int i = 1; i < numChannels; ++i)
01096             if (channels[i].getBlockSize() != blockSize)
01097                 return false;
01098         
01099         return true;
01100     }
01101     
01102     inline bool channelsHaveSameSampleRate() const throw()
01103     {
01104         const int numChannels = this->getNumChannels();
01105         plonk_assert (numChannels > 0);
01106         
01107         const ChannelType* channels = this->getArray();
01108         SampleRate sampleRate = channels[0].getSampleRate();
01109         
01110         for (int i = 1; i < numChannels; ++i)
01111             if (channels[i].getSampleRate() != sampleRate)
01112                 return false;
01113         
01114         return true;
01115     }
01116     
01119     inline const Buffer& getOutputBuffer (const int index) const throw() 
01120     { 
01121         return this->wrapAt (index).getOutputBuffer();
01122     }
01123     
01124 //    /** Get the output buffer of a specific channel.  
01125 //     Indices out of range will be wrapped to the available channels. */
01126 //    inline Buffer& getOutputBuffer (const int index) throw() 
01127 //    { 
01128 //        return this->wrapAt (index).getOutputBuffer();
01129 //    }
01130     
01133     inline const SampleType* getOutputSamples (const int index) const throw()
01134     { 
01135         return this->wrapAt (index)->getOutputSamples(); 
01136     }
01137     
01140     inline SampleType* getOutputSamples (const int index) throw()
01141     { 
01142         return this->wrapAt (index)->getOutputSamples(); 
01143     }
01144     
01146     inline void setOutputBuffer (const int index, Buffer const& externalBuffer) throw()
01147     {
01148         this->atUnchecked (index).setOutputBuffer (externalBuffer);
01149     }
01150     
01152     void setOutputBuffer (BufferArrayType const& externalBuffer) throw()
01153     {
01154         const int numBufferChannels = externalBuffer.length();
01155         const Buffer* bufferChannels = externalBuffer.getArray();
01156         
01157         for (int i = 0; i < numBufferChannels; ++i) 
01158             setOutputBuffer (i, bufferChannels[i]);
01159     }    
01160     
01163     inline const SampleType& getValue (const int index) const throw()
01164     {
01165         return this->wrapAt (index).getValue();
01166     }
01167     
01168     inline const Buffer getValues() const throw()
01169     {
01170         const int numChannels = this->getNumChannels();
01171         Buffer result = Buffer::withSize (numChannels);
01172         SampleType* const resultArray = result.getArray();
01173         
01174         for (int i = 0; i < numChannels; ++i)
01175             resultArray[i] = this->atUnchecked (i).getValue();
01176         
01177         return result;
01178     }
01179     
01180     inline const TimeStamp getNextTimeStamp(const int index) const throw()
01181     {
01182         return this->wrapAt (index).getNextTimeStamp();
01183     }
01184     
01185     inline UnitBase setNull() throw()
01186     {
01187         this->operator= (UnitBase::getNull());
01188         return *this;
01189     }
01190     
01191     inline bool isNull (const int index) const throw()
01192     {
01193         return this->wrapAt (index).isNull();
01194     }
01195     
01196     inline bool isNotNull (const int index) const throw()
01197     {
01198         return ! this->isNull (index);
01199     }
01200     
01201     inline bool isConstant (const int index) const throw()
01202     {
01203         return this->wrapAt (index).isConstant();
01204     }
01205     
01206     inline bool isEachChannelConstant() const throw()
01207     {        
01208         for (int i = 0; i < this->getNumChannels(); ++i)
01209             if (!this->atUnchecked (i).isConstant())
01210                 return false;
01211         
01212         return true;
01213     }
01214     
01215     inline bool isNotConstant (const int index) const throw()
01216     {
01217         return ! this->isConstant (index);
01218     }    
01219     
01221     inline bool isNull() const throw()
01222     {
01223         if (this->getNumChannels() != 1)
01224             return false;
01225         else if (this->at(0).isNull())
01226             return true;
01227         else
01228             return false;
01229     }
01230     
01232     inline bool isNotNull() const throw()
01233     {
01234         return ! this->isNull();
01235     }
01236     
01238     inline bool isConstant() const throw()
01239     {
01240         if (this->getNumChannels() != 1)
01241             return false;
01242         else if (this->at (0).isConstant())
01243             return true;
01244         else
01245             return false;
01246     }
01247     
01249     inline bool isNotConstant() const throw()
01250     {
01251         return ! this->isConstant();
01252     }    
01253     
01254     inline void setToNull() throw()
01255     {
01256         this->setSize (1, true);
01257         this->put (0, ChannelType::getNull());
01258     }
01259     
01260     inline TextArray getNames() throw()
01261     {
01262         TextArray names;
01263         for (int i = 0; i < this->getNumChannels(); ++i)
01264             names.add (this->at (i).getName());
01265         return names;
01266     }
01267     
01269     inline bool needsToProcess (ProcessInfo const& info, const int channel) const throw()
01270     {        
01271         return this->wrapAt (channel).needsToProcess (info, channel);
01272     }
01273     
01275     inline bool shouldBeDeletedNow (ProcessInfo const& info) const throw()
01276     {
01277         bool flag = true;
01278         
01279         const int numChannels = this->getNumChannels();
01280         const ChannelType* channels = this->getArray();
01281         
01282         for (int i = 0; i < numChannels; ++i)
01283         {
01284             if (!channels[i].shouldBeDeletedNow (info.getTimeStamp()))
01285             {
01286                 flag = false;
01287                 break;
01288             }
01289         }
01290         
01291         return flag;
01292     }
01293     
01294     void resetIfExpired() throw()
01295     {
01296         const int numChannels = this->getNumChannels();
01297         ChannelType* channels = this->getArray();
01298         
01299         for (int i = 0; i < numChannels; ++i)
01300             channels[i].resetIfExpired();
01301     }
01302     
01303 //    /** Process a specific channel in this unit.
01304 //     The host should prepare a ProcessInfo which is passed to this function
01305 //     for each required block of data. This is generally used by ChannelInternal
01306 //     subclasses when obtaining input data. 
01307 //     @return The buffer from the requested channel. */
01308 //    inline const Buffer& process (ProcessInfo& info, const int channel) throw()
01309 //    {
01310 //        ChannelType& theChannel (this->wrapAt (channel));
01311 //        
01312 //        if (theChannel.shouldBeDeletedNow (info.getTimeStamp()))
01313 //        {
01314 //            Buffer& buffer = theChannel.getOutputBuffer();
01315 //            buffer.zero();
01316 //            return buffer;
01317 //        }
01318 //        else
01319 //        {
01320 //            theChannel.process (info, channel);
01321 //            return this->getOutputBuffer (channel);
01322 //        }
01323 //        
01324 //    }
01325     
01331     inline const Buffer& process (ProcessInfo& info, const int channel) throw()
01332     {
01333         this->wrapAt (channel).process (info, channel);
01334         return this->getOutputBuffer (channel);
01335     }
01336 
01337     
01338 //    /** Process all channels in this unit.
01339 //     The host should prepare a ProcessInfo which is passed to this function
01340 //     for each required block of data. */    
01341 //    void process (ProcessInfo& info) throw()
01342 //    {        
01343 //        const int numChannels = this->getNumChannels();
01344 //        ChannelType* channels = this->getArray();
01345 //                        
01346 //        if (numChannels > 0)
01347 //        {
01348 //            int i;
01349 //            bool didDelete = false;
01350 //            
01351 //            for (i = 0; i < numChannels; ++i) 
01352 //            {
01353 //                if (channels[i].shouldBeDeletedNow (info.getTimeStamp()))
01354 //                {
01355 //                    didDelete = true;
01356 //                    break;
01357 //                }
01358 //            }
01359 //                        
01360 //            if (didDelete == false)
01361 //            {
01362 //                for (i = 0; i < numChannels; ++i)
01363 //                    channels[i].process (info, i);
01364 //            }
01365 //            else
01366 //            {
01367 //                this->setToNull();
01368 //                this->atUnchecked (0).process (info, 0); // probably unnecessary?
01369 //            }
01370 //        }
01371 //    }
01372 
01373 //    /** Process all channels in this unit.
01374 //     The host should prepare a ProcessInfo which is passed to this function
01375 //     for each required block of data. */
01376 //    void process (ProcessInfo& info) throw()
01377 //    {
01378 //        const int numChannels = this->getNumChannels();
01379 //        ChannelType* channels = this->getArray();
01380 //        
01381 //        for (int i = 0; i < numChannels; ++i)
01382 //        {
01383 //            if (channels[i].shouldBeDeletedNow (info.getTimeStamp()))
01384 //                channels[i].getOutputBuffer().zero();
01385 //            else
01386 //                channels[i].process (info, i);
01387 //        }
01388 //    }
01389     
01393     void process (ProcessInfo& info) throw()
01394     {
01395         const int numChannels = this->getNumChannels();
01396         ChannelType* channels = this->getArray();
01397         
01398         for (int i = 0; i < numChannels; ++i)
01399             channels[i].process (info, i);
01400     }
01401 
01402     
01403     int getTypeCode() const throw()
01404     {
01405         return TypeUtility<UnitBase>::getTypeCode();
01406     }
01407     
01408     int getSampleTypeCode() const throw()
01409     {
01410         return TypeUtility<SampleType>::getTypeCode();
01411     }          
01412     
01413     typename TypeUtility<SampleType>::PeakType getTypePeak() const throw()
01414     {
01415         return TypeUtility<SampleType>::getTypePeak();
01416     }
01417     
01418     typename TypeUtility<SampleType>::IndexType getTypeScale() const throw()
01419     {
01420         return TypeUtility<SampleType>::getTypeScale();
01421     }
01422     
01423     void addReceiverToChannels (Receiver* const receiver)
01424     {
01425         const int numChannels = this->getNumChannels();
01426         ChannelType* channels = this->getArray();
01427 
01428         for (int i = 0; i < numChannels; ++i)
01429             channels[i].getInternal()->addReceiver (receiver);
01430     }
01431     
01432     void removeReceiverFromChannels (Receiver* const receiver)
01433     {
01434         const int numChannels = this->getNumChannels();
01435         ChannelType* channels = this->getArray();
01436         
01437         for (int i = 0; i < numChannels; ++i)
01438             channels[i].getInternal()->removeReceiver (receiver);
01439     }
01440 
01441     
01442     PLONK_OBJECTARROWOPERATOR(UnitBase);
01443     
01444 private:
01445     UnitBase (BlockSize const& blockSize) throw()
01446     :   UnitType (ChannelType())
01447     {
01448         (void)blockSize;
01449         // you must have got your arguments mixed up, perhaps you tried to 
01450         // set a unit block size but missed out mul or add arguments? 
01451         plonk_assertfalse; 
01452     }
01453     
01454     UnitBase (SampleRate const& sampleRate) throw()
01455     :   UnitType (ChannelType())
01456     {
01457         (void)sampleRate;
01458         // you must have got your arguments mixed up, perhaps you tried to 
01459         // set a unit sample rate but missed out mul or add arguments? 
01460         plonk_assertfalse;
01461     }        
01462 };
01463 
01464 PLONK_BINARYOPGLOBALS_TEMPLATE(UnitBase,SampleType); // declares global functions with the same name as the binary operators
01465 PLONK_UNARYOPGLOBALS_TEMPLATE(UnitBase,SampleType);  // declares global functions with the same name as the unary operators
01466 
01467 //template<class SampleType>
01468 //inline UnitBase<SampleType> explin (UnitBase<SampleType> const& input, 
01469 //                                    UnitBase<SampleType> const& inLow, UnitBase<SampleType> const& inHigh, 
01470 //                                    UnitBase<SampleType> const& outLow, UnitBase<SampleType> const& outHigh) throw()
01471 //{
01472 //    const UnitBase<SampleType> clipped (clip (input, inLow, inHigh));
01473 //    return log (clipped / inLow) / log (inHigh / inLow) * (outHigh - outLow) + outLow;
01474 //}
01475 
01478 template<class SampleType>
01479 UnitBase<SampleType> ar (UnitBase<SampleType> const& unit,
01480                          BlockSize const& preferredBlockSize = BlockSize::getDefault(),
01481                          SampleRate const& preferredSampleRate = SampleRate::getDefault()) throw()
01482 {
01483     return unit.ar (preferredBlockSize, preferredSampleRate);
01484 }    
01485 
01487 template<class SampleType>
01488 inline UnitBase<SampleType> kr (UnitBase<SampleType> const& unit) throw()
01489 {
01490     return unit.kr();
01491 }
01492 
01494 template<class SampleType>
01495 inline UnitBase<SampleType> mix (UnitBase<SampleType> const& unit) throw()
01496 {
01497     return unit.mix();
01498 }
01499 
01500 
01501 //------------------------------------------------------------------------------
01502 
01503 template<class SampleType>
01504 UnitBase<SampleType> UnitBase<SampleType>::operator, (UnitType const& other) const throw()
01505 { 
01506     return operator, (UnitBase (other));
01507 }
01508 
01509 template<class SampleType>
01510 UnitBase<SampleType> UnitBase<SampleType>::operator, (UnitBase const& other) const throw()
01511 { 
01512     const int numChannels = getNumChannels() + other.getNumChannels();
01513     UnitBase result (UnitBase::withSize (numChannels));
01514     
01515     int resultIndex = 0;
01516     int sourceIndex;
01517     
01518     for (sourceIndex = 0; sourceIndex < getNumChannels(); ++sourceIndex) 
01519         result.put (resultIndex++, this->at (sourceIndex));
01520     
01521     for (sourceIndex = 0; sourceIndex < other.getNumChannels(); ++sourceIndex) 
01522         result.put (resultIndex++, other.at (sourceIndex));
01523     
01524     return result;        
01525 }
01526 
01527 template<class SampleType>
01528 BlockSize UnitBase<SampleType>::getMinBlockSize() const throw()
01529 {
01530     const int numChannels = this->getNumChannels();
01531     BlockSize blockSize = this->atUnchecked (0).getBlockSize();
01532     
01533     for (int i = 1; i < numChannels; ++i) 
01534     {
01535         const BlockSize& channelBlockSize = this->atUnchecked (i).getBlockSize();
01536         blockSize = blockSize.selectMin (channelBlockSize);        
01537     }
01538     
01539     return blockSize;
01540 }
01541 
01542 template<class SampleType>
01543 BlockSize UnitBase<SampleType>::getMaxBlockSize() const throw()
01544 {
01545     const int numChannels = this->getNumChannels();
01546     BlockSize blockSize = this->atUnchecked (0).getBlockSize();
01547     
01548     for (int i = 1; i < numChannels; ++i) 
01549     {
01550         const BlockSize& channelBlockSize = this->atUnchecked (i).getBlockSize();
01551         blockSize = blockSize.selectMax (channelBlockSize);        
01552     }
01553     
01554     return blockSize;
01555 }
01556 
01557 template<class SampleType>
01558 SampleRate UnitBase<SampleType>::getMinSampleRate() const throw()
01559 {
01560     const int numChannels = this->getNumChannels();
01561     SampleRate sampleRate = this->atUnchecked (0).getSampleRate();
01562     
01563     for (int i = 1; i < numChannels; ++i) 
01564     {
01565         const SampleRate& channelSampleRate = this->atUnchecked (i).getSampleRate();
01566         sampleRate = sampleRate.selectMin (channelSampleRate);        
01567     }
01568     
01569     return sampleRate;    
01570 }
01571 
01572 template<class SampleType>
01573 SampleRate UnitBase<SampleType>::getMaxSampleRate() const throw()
01574 {
01575     const int numChannels = this->getNumChannels();
01576     SampleRate sampleRate = this->atUnchecked (0).getSampleRate();
01577     
01578     for (int i = 1; i < numChannels; ++i) 
01579     {
01580         const SampleRate& channelSampleRate = this->atUnchecked (i).getSampleRate();
01581         sampleRate = sampleRate.selectMax (channelSampleRate);        
01582     }
01583     
01584     return sampleRate;        
01585 }
01586 
01587 
01588 #endif // PLONK_UNIT_H
 All Classes Functions Typedefs Enumerations Enumerator Properties