pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_WhiteNoise.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_WHITENOISE_H
00040 #define PLONK_WHITENOISE_H
00041 
00042 #include "../channel/plonk_ChannelInternalCore.h"
00043 #include "../plonk_GraphForwardDeclarations.h"
00044 
00045 template<class SampleType> class WhiteNoiseChannelInternal;
00046 
00047 PLONK_CHANNELDATA_DECLARE(WhiteNoiseChannelInternal,SampleType)
00048 {    
00049     ChannelInternalCore::Data base;
00050     
00051     SampleType minValue;
00052     SampleType maxValue;
00053     PlankRNG rng;
00054 };              
00055 
00056 PLONK_CHANNELDATA_SPECIAL(WhiteNoiseChannelInternal,short)
00057 {    
00058     ChannelInternalCore::Data base;
00059     
00060     int minValue;
00061     int maxValue;
00062     PlankRNG rng;
00063 };      
00064 
00065 //------------------------------------------------------------------------------
00066 
00068 template<class SampleType>
00069 class WhiteNoiseChannelInternal 
00070 :   public ChannelInternal<SampleType, PLONK_CHANNELDATA_NAME(WhiteNoiseChannelInternal,SampleType)>
00071 {
00072 public:
00073     typedef PLONK_CHANNELDATA_NAME(WhiteNoiseChannelInternal,SampleType)    Data;
00074     typedef InputDictionary                                                 Inputs;
00075     typedef ChannelBase<SampleType>                                         ChannelType;
00076     typedef WhiteNoiseChannelInternal<SampleType>                           WhiteNoiseInternal;
00077     typedef ChannelInternal<SampleType,Data>                                Internal;
00078     typedef ChannelInternalBase<SampleType>                                 InternalBase;
00079     typedef UnitBase<SampleType>                                            UnitType;
00080     
00081     WhiteNoiseChannelInternal (Inputs const& inputs, 
00082                                Data const& data, 
00083                                BlockSize const& blockSize,
00084                                SampleRate const& sampleRate) throw()
00085     :   Internal (inputs, data, blockSize, sampleRate)
00086     {
00087         rng.seed (data.rng.value);
00088     }
00089             
00090     Text getName() const throw()
00091     {
00092         return "White Noise";
00093     }       
00094     
00095     IntArray getInputKeys() const throw()
00096     {
00097         const IntArray keys;
00098         return keys;
00099     }    
00100     
00101     InternalBase* getChannel (const int index) throw()
00102     {
00103         return this;
00104     }
00105     
00106     void initChannel (const int channel) throw()
00107     {                        
00108         this->initValue (SampleType (0));
00109     }    
00110     
00111     void process (ProcessInfo& info, const int channel) throw()
00112     {        
00113         Data& data = this->getState();        
00114         SampleType* const outputSamples = this->getOutputSamples();
00115         const int outputBufferLength = this->getOutputBuffer().length();
00116         
00117         for (int i = 0; i < outputBufferLength; ++i) 
00118             outputSamples[i] = SampleType (rng.uniform (data.minValue, data.maxValue));
00119     }
00120     
00121 private:
00122     RNG rng;
00123 };
00124 
00125 //------------------------------------------------------------------------------
00126 
00127 #ifdef PLONK_USEPLINK
00128 
00129 template<>
00130 class WhiteNoiseChannelInternal<float> : public ChannelInternal<float, WhiteNoiseProcessStateF>
00131 {
00132 public:
00133     typedef WhiteNoiseProcessStateF             Data;
00134     typedef InputDictionary                     Inputs;
00135     typedef ChannelBase<float>                  ChannelType;
00136     typedef WhiteNoiseChannelInternal<float>    WhiteNoiseInternal;
00137     typedef ChannelInternal<float,Data>         Internal;
00138     typedef ChannelInternalBase<float>          InternalBase;
00139     typedef UnitBase<float>                     UnitType;
00140         
00141     
00142     enum Outputs { Output, NumOutputs };
00143     enum InputIndices  { NumInputs };
00144     enum Buffers { OutputBuffer, NumBuffers };
00145     
00146     typedef PlinkProcess<NumBuffers> Process;
00147     
00148     WhiteNoiseChannelInternal (Inputs const& inputs, 
00149                                Data const& data, 
00150                                BlockSize const& blockSize,
00151                                SampleRate const& sampleRate) throw()
00152     :   Internal (inputs, data, blockSize, sampleRate)
00153     {
00154         plonk_staticassert (NumBuffers == (NumInputs + NumOutputs));
00155         
00156         Process::init (&p, this, NumOutputs, NumInputs);
00157     }
00158     
00159     Text getName() const throw()
00160     {
00161         return "White Noise";
00162     }       
00163     
00164     IntArray getInputKeys() const throw()
00165     {
00166         const IntArray keys;
00167         return keys;
00168     }    
00169     
00170     InternalBase* getChannel (const int index) throw()
00171     {
00172         return this;
00173     }    
00174     
00175     void initChannel (const int channel) throw()
00176     {        
00177         this->initValue (0.f);
00178     }        
00179     
00180     void process (ProcessInfo& info, const int channel) throw()
00181     {                        
00182         p.buffers[0].bufferSize = this->getOutputBuffer().length();;
00183         p.buffers[0].buffer     = this->getOutputSamples();
00184         
00185         plink_WhiteNoiseProcessF_N (&p, &this->getState());
00186     }
00187     
00188 private:
00189     Process p;
00190 };
00191 
00192 #endif
00193 
00194 //------------------------------------------------------------------------------
00195 
00209 template<class SampleType>
00210 class WhiteNoiseUnit
00211 {
00212 public:    
00213     typedef WhiteNoiseChannelInternal<SampleType>   WhiteNoiseInternal;
00214     typedef typename WhiteNoiseInternal::Data       Data;
00215     typedef InputDictionary                         Inputs;
00216     typedef ChannelBase<SampleType>                 ChannelType;
00217     typedef ChannelInternal<SampleType,Data>        Internal;
00218     typedef ChannelInternalBase<SampleType>         ChannelInternalType;
00219     typedef UnitBase<SampleType>                    UnitType;
00220     
00221     static inline UnitInfos getInfo() throw()
00222     {
00223         const double blockSize = (double)BlockSize::getDefault().getValue();
00224         const double sampleRate = SampleRate::getDefault().getValue();
00225         const double peak = (double)TypeUtility<SampleType>::getTypePeak(); // will be innaccurate for LongLong
00226         
00227         return UnitInfo ("WhiteNoise", "A white noise generator.",
00228                          
00229                          // output
00230                          ChannelCount::VariableChannelCount, 
00231                          IOKey::Generic,    Measure::None,      0.0,        IOLimit::Clipped,   Measure::NormalisedBipolar, -peak, peak,
00232                          IOKey::End,
00233                          
00234                          // inputs
00235                          IOKey::Multiply,   Measure::Factor,    1.0,        IOLimit::None,
00236                          IOKey::Add,        Measure::None,      0.0,        IOLimit::None,
00237                          IOKey::BlockSize,  Measure::Samples,   blockSize,  IOLimit::Minimum,   Measure::Samples,           1.0,
00238                          IOKey::SampleRate, Measure::Hertz,     sampleRate, IOLimit::Minimum,   Measure::Hertz,             0.0,
00239                          IOKey::End);
00240     }
00241     
00243     static UnitType ar (UnitType const& mul = SampleType (1),
00244                         UnitType const& add = SampleType (0),
00245                         BlockSize const& preferredBlockSize = BlockSize::getDefault(),
00246                         SampleRate const& preferredSampleRate = SampleRate::getDefault()) throw()
00247     {                                
00248         const LongLong peak = SampleType (TypeUtility<SampleType>::getTypePeak());
00249         
00250         const int numChannels = plonk::max (mul.getNumChannels(), add.getNumChannels());
00251         UnitType result (UnitType::withSize (numChannels));
00252         
00253         Inputs inputs;
00254         
00255         for (int i = 0; i < numChannels; ++i) 
00256         {
00257             PlankRNG rng;
00258             pl_RNG_Init (&rng);
00259             pl_RNG_Seed (&rng, RNG::global().uniformInt());
00260             Data data = { { -1.0, -1.0 }, -peak, peak, rng };
00261             ChannelInternalType* internal = new WhiteNoiseInternal (inputs, 
00262                                                                     data, 
00263                                                                     preferredBlockSize, 
00264                                                                     preferredSampleRate);
00265             internal->initChannel (i);
00266             result.put (i, ChannelType (internal));
00267         }
00268         
00269         return UnitType::applyMulAdd (result, mul, add);
00270     }
00271     
00273     static UnitType kr (UnitType const& mul = SampleType (1),
00274                         UnitType const& add = SampleType (0)) throw()
00275     {
00276         return ar (mul, add, 
00277                    BlockSize::getControlRateBlockSize(), 
00278                    SampleRate::getControlRate());
00279     }        
00280 };
00281 
00282 typedef WhiteNoiseUnit<PLONK_TYPE_DEFAULT> WhiteNoise;
00283 
00284 
00285 #endif // PLONK_WHITENOISE_H
00286 
 All Classes Functions Typedefs Enumerations Enumerator Properties