pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLONK_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