pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_DelayFormCombDecay.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_DELAYFORMCOMBDECAY_H
00040 #define PLONK_DELAYFORMCOMBDECAY_H
00041 
00042 #include "../channel/plonk_ChannelInternalCore.h"
00043 #include "plonk_DelayForwardDeclarations.h"
00044 
00045 
00046 template<class SampleType, Interp::TypeCode InterpTypeCode>
00047 class DelayFormCombDecay
00048 :   public DelayFormCombFB<SampleType>
00049 {
00050 public:
00051     typedef DelayFormCombFB<SampleType>                             Base;
00052 
00053     enum InParams
00054     {
00055         DurationIn,
00056         DecayIn,
00057         NumInParams
00058     };
00059             
00060     typedef typename Base::Data                                     Data;
00061     typedef typename Data::DelayState                               DelayState;
00062     typedef DelayFormCombDecay                                      FormType;
00063     
00064     typedef SampleType                                              SampleDataType;
00065     typedef Delay2ParamChannelInternal<FormType>                    DelayInternal;
00066     typedef ChannelBase<SampleType>                                 ChannelType;
00067     typedef ChannelInternal<SampleType,Data>                        Internal;
00068     typedef UnitBase<SampleType>                                    UnitType;
00069     typedef InputDictionary                                         Inputs;
00070     typedef NumericalArray<SampleType>                              Buffer;
00071     
00072     typedef typename TypeUtility<SampleType>::IndexType             Param1Type;  
00073     typedef Param1Type                                              DurationType;    
00074     typedef UnitBase<DurationType>                                  DurationUnitType;
00075     
00076     typedef typename TypeUtility<SampleType>::IndexType             Param2Type;  
00077     typedef Param2Type                                              DecayType;    
00078     typedef UnitBase<DecayType>                                     DecayUnitType;
00079     
00080     typedef InterpSelect<SampleType,DurationType,InterpTypeCode>    InterpSelectType;
00081     typedef typename InterpSelectType::InterpType                   InterpType;
00082     typedef typename InterpType::ExtensionBuffer                    ExtensionBuffer;
00083     
00084     static inline IntArray getInputKeys() throw()
00085     {
00086         const IntArray keys (IOKey::Generic, IOKey::Duration, IOKey::Decay);
00087         return keys;
00088     }    
00089         
00090     static inline void param1Process (Data& data, DelayState& state, DurationType const& duration) throw()
00091     {
00092         if (state.paramsIn[DurationIn] != duration)
00093         {
00094             state.paramsIn[DurationIn] = duration;
00095             state.paramsOut[Base::DurationInSamplesOut] = DurationType (duration * data.base.sampleRate);
00096             plonk_assert (state.paramsOut[Base::DurationInSamplesOut] >= 0 && 
00097                           state.paramsOut[Base::DurationInSamplesOut] <= state.bufferLengthIndex);
00098             state.paramsOut[Base::FeedbackOut] = plonk::decayFeedback (state.paramsIn[DurationIn], state.paramsIn[DecayIn]);
00099         }
00100     }
00101 
00102     static inline void param2Ignore (Data&, DelayState&, DecayType const&) throw() { }
00103     static inline void param2Process (Data&, DelayState& state, DecayType const& decay) throw()
00104     {                        
00105         if (state.paramsIn[DecayIn] != decay)
00106         {
00107             state.paramsIn[DecayIn] = decay;
00108             state.paramsOut[Base::FeedbackOut] = plonk::decayFeedback (state.paramsIn[DurationIn], decay);
00109         }
00110     }
00111         
00112     static inline UnitType ar (UnitType const& input,
00113                                DurationUnitType const& duration,
00114                                DecayUnitType const& decay,
00115                                const DurationType maximumDuration,
00116                                UnitType const& mul,
00117                                UnitType const& add,
00118                                BlockSize const& preferredBlockSize,
00119                                SampleRate const& preferredSampleRate) throw()
00120     {             
00121         const Data data = { { -1.0, -1.0 }, maximumDuration, 0 };
00122         
00123         const int numInputChannels = input.getNumChannels();
00124         const int numDurationChannels = duration.getNumChannels();
00125         const int numDecayChannels = decay.getNumChannels();
00126         const int numChannels = plonk::max (numInputChannels, numDurationChannels, numDecayChannels);
00127         
00128         UnitType mainUnit = UnitType::emptyChannels (numChannels);
00129         
00130         for (int i = 0; i < numChannels; ++i)
00131         {
00132             Inputs inputs;
00133             inputs.put (IOKey::Generic, input[i]);
00134             inputs.put (IOKey::Duration, duration[i]);
00135             inputs.put (IOKey::Decay, decay[i]);
00136             
00137             UnitType unit = UnitType::template proxiesFromInputs<DelayInternal> (inputs, 
00138                                                                                 data, 
00139                                                                                 preferredBlockSize, 
00140                                                                                 preferredSampleRate);
00141             mainUnit.put (i, unit);
00142         }
00143         
00144         return UnitType::applyMulAdd (mainUnit, mul, add);
00145     }
00146 };
00147 
00148 
00149 //------------------------------------------------------------------------------
00150 
00151 
00168 template<class SampleType, Interp::TypeCode InterpTypeCode>
00169 class CombDecayUnit
00170 {
00171 public:    
00172     typedef DelayFormCombDecay<SampleType,InterpTypeCode>       FormType;
00173     typedef DelayFormCombFB<SampleType,InterpTypeCode>          AltFormType;
00174 
00175     typedef Delay2ParamChannelInternal<FormType>                DelayInternal;
00176     typedef UnitBase<SampleType>                                UnitType;
00177     typedef InputDictionary                                     Inputs;
00178     
00179     typedef typename DelayInternal::Param1Type                  DurationType;
00180     typedef UnitBase<DurationType>                              DurationUnitType;
00181     
00182     typedef typename DelayInternal::Param2Type                  DecayType;
00183     typedef UnitBase<DecayType>                                 DecayUnitType;
00184     
00185     typedef CombDecayUnit<SampleType, Interp::Lagrange3>        HQ;
00186     typedef CombDecayUnit<SampleType, Interp::None>             N;
00187     
00188     static inline UnitInfos getInfo() throw()
00189     {
00190         const double blockSize = (double)BlockSize::getDefault().getValue();
00191         const double sampleRate = SampleRate::getDefault().getValue();
00192         
00193         return UnitInfo ("CombDecay", "A comb filter setting the decay as a time to decay by 60dB.",
00194                          
00195                          // output
00196                          ChannelCount::VariableChannelCount, 
00197                          IOKey::Generic,            Measure::None,      0.0,                IOLimit::None,                         
00198                          IOKey::End,
00199                          
00200                          // inputs
00201                          IOKey::Generic,            Measure::None,      IOInfo::NoDefault,  IOLimit::None,
00202                          IOKey::Duration,           Measure::Seconds,   0.5,                IOLimit::Minimum,   Measure::Seconds,   0.0,
00203                          IOKey::Decay,              Measure::Seconds,   1.0,                IOLimit::None,
00204                          IOKey::MaximumDuration,    Measure::Seconds,   1.0,                IOLimit::Minimum,   Measure::Samples,   1.0,
00205                          IOKey::Multiply,           Measure::Factor,    1.0,                IOLimit::None,
00206                          IOKey::Add,                Measure::None,      0.0,                IOLimit::None,
00207                          IOKey::BlockSize,          Measure::Samples,   blockSize,          IOLimit::Minimum,   Measure::Samples,   1.0,
00208                          IOKey::SampleRate,         Measure::Hertz,     sampleRate,         IOLimit::Minimum,   Measure::Hertz,     0.0,
00209                          IOKey::End);
00210     }
00211     
00213     static UnitType ar (UnitType const& input,
00214                         DurationUnitType const& duration = DurationType (0.5),
00215                         DecayUnitType const& decay = DecayType (1.0),
00216                         const DurationType maximumDuration = DurationType (1.0),
00217                         UnitType const& mul = SampleType (1),
00218                         UnitType const& add = SampleType (0),
00219                         BlockSize const& preferredBlockSize = BlockSize::getDefault(),
00220                         SampleRate const& preferredSampleRate = SampleRate::getDefault()) throw()
00221     {             
00222         if (duration.isEachChannelConstant() && decay.isEachChannelConstant())
00223             return AltFormType::ar (input, duration, duration.getValues().decayFeedback (decay.getValues()), maximumDuration,
00224                                     mul, add, preferredBlockSize, preferredSampleRate);
00225         else 
00226             return FormType::ar (input, duration, decay, maximumDuration, 
00227                                  mul, add, preferredBlockSize, preferredSampleRate);
00228     }
00229     
00230 };
00231 
00232 typedef CombDecayUnit<PLONK_TYPE_DEFAULT> CombDecay;
00233 
00234 
00235 #endif // PLONK_DELAYFORMCOMBDECAY_H
00236 
 All Classes Functions Typedefs Enumerations Enumerator Properties