![]() |
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_DELAY1PARAM_H 00040 #define PLONK_DELAY1PARAM_H 00041 00042 #include "../channel/plonk_ChannelInternalCore.h" 00043 #include "plonk_DelayForwardDeclarations.h" 00044 00045 00047 template<class FormType> 00048 class Delay1ParamChannelInternal 00049 : public DelayChannelInternalBase<FormType> 00050 { 00051 public: 00052 typedef typename FormType::SampleDataType SampleType; 00053 typedef typename FormType::Data Data; 00054 typedef typename FormType::DelayState DelayState; 00055 00056 typedef ObjectArray<DelayState> DelayStateArray; 00057 00058 typedef ChannelBase<SampleType> ChannelType; 00059 typedef ObjectArray<ChannelType> ChannelArrayType; 00060 typedef Delay1ParamChannelInternal<FormType> DelayInternal; 00061 typedef DelayChannelInternalBase<FormType> Internal; 00062 typedef ChannelInternalBase<SampleType> InternalBase; 00063 typedef UnitBase<SampleType> UnitType; 00064 typedef InputDictionary Inputs; 00065 typedef NumericalArray<SampleType> Buffer; 00066 00067 typedef typename TypeUtility<SampleType>::IndexType DurationType; 00068 00069 typedef typename FormType::Param1Type Param1Type; 00070 typedef UnitBase<Param1Type> Param1UnitType; 00071 typedef NumericalArray<Param1Type> Param1BufferType; 00072 00073 typedef typename FormType::InputFunction InputFunction; 00074 typedef typename FormType::ReadFunction ReadFunction; 00075 typedef typename FormType::WriteFunction WriteFunction; 00076 typedef typename FormType::OutputFunction OutputFunction; 00077 typedef typename FormType::Param1Function Param1Function; 00078 00079 enum Params 00080 { 00081 Param1, 00082 NumParams 00083 }; 00084 00085 Delay1ParamChannelInternal (Inputs const& inputs, 00086 Data const& data, 00087 BlockSize const& blockSize, 00088 SampleRate const& sampleRate, 00089 ChannelArrayType& channels) throw() 00090 : Internal (getNumChannelsFromInputs (inputs), // num proxies 00091 inputs, data, blockSize, sampleRate, channels), 00092 inputKeys (FormType::getInputKeys()) 00093 { 00094 } 00095 00096 void process (ProcessInfo& info, const int /*channel*/) throw() 00097 { 00098 Data& data = this->getState(); 00099 DelayStateArray& delayStates = this->getDelayStates(); 00100 00101 UnitType& inputUnit = this->getInputAsUnit (IOKey::Generic); 00102 const Buffer& inputBuffer (inputUnit.process (info, 0)); 00103 Param1UnitType& param1Unit = ChannelInternalCore::getInputAs<Param1UnitType> (inputKeys.atUnchecked (1)); 00104 00105 plonk_assert (inputBuffer.length() == this->getOutputBuffer (0).length()); 00106 00107 const int writePosition = process<FormType::inputRead, 00108 FormType::readRead, 00109 FormType::writeWrite, 00110 FormType::outputWrite, 00111 FormType::param1Process> 00112 (this->getOutputSamples (0), 00113 this->getOutputBuffer (0).length(), 00114 inputBuffer.getArray(), 00115 param1Unit, 00116 data, delayStates.atUnchecked (0), info, 0); 00117 00118 const int numChannels = this->getNumChannels(); 00119 00120 for (int i = 1; i < numChannels; ++i) 00121 { 00122 plonk_assert (inputBuffer.length() == this->getOutputBuffer (i).length()); 00123 00124 process<FormType::inputIgnore, 00125 FormType::readRead, 00126 FormType::writeIgnore, 00127 FormType::outputWrite, 00128 FormType::param1Process> 00129 (this->getOutputSamples (i), 00130 this->getOutputBuffer (i).length(), 00131 0, 00132 param1Unit, 00133 data, delayStates.atUnchecked (i), info, i); 00134 } 00135 00136 data.writePosition = writePosition; // update the write position from the first channel write 00137 } 00138 00139 private: 00140 IntArray inputKeys; 00141 00142 static inline int getNumChannelsFromInputs (Inputs const& inputs) throw() 00143 { 00144 return inputs[FormType::getInputKeys().atUnchecked (1)].template asUnchecked<Param1UnitType>().getNumChannels(); 00145 } 00146 00147 template<InputFunction inputFunction, 00148 ReadFunction readFunction, 00149 WriteFunction writeFunction, 00150 OutputFunction outputFunction, 00151 Param1Function param1Function> 00152 static int process (SampleType* const outputSamples, 00153 const int outputBufferLength, 00154 const SampleType* inputSamples, 00155 Param1UnitType& param1Unit, 00156 Data& data, 00157 DelayState& state, 00158 ProcessInfo& info, 00159 const int channel) throw() 00160 { 00161 state.outputSamples = outputSamples; 00162 state.outputBufferLength = outputBufferLength; 00163 state.inputSamples = inputSamples; 00164 state.writePosition = data.writePosition; 00165 00166 const Param1BufferType& param1Buffer (param1Unit.process (info, channel)); 00167 const Param1Type* param1Samples = param1Buffer.getArray(); 00168 const int param1BufferLength = param1Buffer.length(); 00169 00170 int numSamplesToProcess = outputBufferLength; 00171 00172 if (param1BufferLength == outputBufferLength) 00173 { 00174 while (numSamplesToProcess > 0) 00175 { 00176 int bufferSamplesRemaining = state.bufferLength - state.writePosition; 00177 int numSamplesThisTime = plonk::min (bufferSamplesRemaining, numSamplesToProcess); 00178 numSamplesToProcess -= numSamplesThisTime; 00179 00180 while (numSamplesThisTime--) 00181 { 00182 param1Function (data, state, *param1Samples++); 00183 FormType::template tick<inputFunction, readFunction, writeFunction, outputFunction> (data, state); 00184 } 00185 00186 if (state.writePosition >= state.bufferLength) 00187 state.writePosition = 0; 00188 } 00189 } 00190 else if (param1BufferLength == 1) 00191 { 00192 param1Function (data, state, param1Samples[0]); 00193 00194 while (numSamplesToProcess > 0) 00195 { 00196 int bufferSamplesRemaining = state.bufferLength - state.writePosition; 00197 int numSamplesThisTime = plonk::min (bufferSamplesRemaining, numSamplesToProcess); 00198 numSamplesToProcess -= numSamplesThisTime; 00199 00200 while (numSamplesThisTime--) 00201 FormType::template tick<inputFunction, readFunction, writeFunction, outputFunction> (data, state); 00202 00203 if (state.writePosition >= state.bufferLength) 00204 state.writePosition = 0; 00205 } 00206 } 00207 else 00208 { 00209 double param1Position = 0.0; 00210 const double param1Increment = double (param1BufferLength) / double (outputBufferLength); 00211 00212 while (numSamplesToProcess > 0) 00213 { 00214 int bufferSamplesRemaining = state.bufferLength - state.writePosition; 00215 int numSamplesThisTime = plonk::min (bufferSamplesRemaining, numSamplesToProcess); 00216 numSamplesToProcess -= numSamplesThisTime; 00217 00218 while (numSamplesThisTime--) 00219 { 00220 param1Function (data, state, param1Samples[int (param1Position)]); 00221 FormType::template tick<inputFunction, readFunction, writeFunction, outputFunction> (data, state); 00222 param1Position += param1Increment; 00223 } 00224 00225 if (state.writePosition >= state.bufferLength) 00226 state.writePosition = 0; 00227 } 00228 } 00229 00230 return state.writePosition; 00231 } 00232 }; 00233 00234 00235 00236 00237 00238 #endif // PLONK_DELAY1PARAM_H 00239