pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_Wavetable.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_WAVETABLE_H
00040 #define PLONK_WAVETABLE_H
00041 
00042 #include "../core/plonk_CoreForwardDeclarations.h"
00043 #include "plonk_ContainerForwardDeclarations.h"
00044 #include "plonk_DynamicContainer.h"
00045 
00046 #include "../core/plonk_SmartPointer.h"
00047 #include "../core/plonk_WeakPointer.h"
00048 #include "plonk_ObjectArray.h"
00049 #include "plonk_SimpleArray.h"
00050 
00051 
00053 template<class SampleType>
00054 class WavetableBase : private NumericalArray<SampleType>
00055 {
00056 public:
00057     typedef NumericalArray<SampleType> Buffer;
00058     
00059     WavetableBase() throw()
00060     {
00061     }
00062     
00063     WavetableBase (Buffer const& buffer) throw()
00064     :   Buffer (Buffer::withSize (buffer.length() * 2, false))
00065     {
00066         const int bufferLength = buffer.length();
00067         plonk_assert (bufferLength > 0);
00068         
00069         const SampleType* const bufferSamples = buffer.getArray();     
00070         SampleType* tableSamples = Buffer::getArray();
00071         
00072         int i;
00073         
00074         // copy twice (could probably get away with copying just the first four samples
00075         // for most interpolation techniques)
00076         
00077         for (i = 0; i < bufferLength; ++i)
00078             *tableSamples++ = bufferSamples[i];
00079         
00080         for (i = 0; i < bufferLength; ++i)
00081             *tableSamples++ = bufferSamples[i];
00082     }
00083     
00086     WavetableBase (WavetableBase const& copy) throw()
00087     :   Buffer (static_cast<Buffer const&> (copy))
00088     {
00089     }
00090     
00091     WavetableBase (Dynamic const& other) throw()
00092     :   Buffer (other.as<WavetableBase>().getInternal())
00093     {
00094     }    
00095     
00097     WavetableBase& operator= (WavetableBase const& other) throw()
00098         {
00099                 if (this != &other)
00100             this->setInternal (other.getInternal());//this->setInternal (other.containerCopy().getInternal());
00101         
00102         return *this;
00103         }
00104     
00105 //    using Buffer::containerCopy;
00106     using Buffer::getInternal;
00107         
00108     int length() const throw()
00109     {
00110         return Buffer::length() / 2;
00111     }
00112     
00113     int size() const throw()
00114     { 
00115         return Buffer::size();
00116     }
00117         
00118     const SampleType* getArray() const throw()
00119     {
00120         return Buffer::getArray();
00121     }
00122     
00123     SampleType operator[] (const int index) const throw()
00124     {
00125         if ((index < 0) || (index >= this->length()))
00126             return SampleType (0);
00127         else
00128             return this->getArray()[index];
00129     }
00130     
00131     SampleType atUnchecked (const int index) const throw()
00132     {
00133         plonk_assert ((index >= 0) && (index < this->length()));
00134         return this->getArray()[index];
00135     }
00136 
00137     void put (const int index, SampleType const& value) throw()
00138     {
00139         const int tableLength = this->length();
00140         plonk_assert ((index >= 0) && (index < tableLength));
00141         SampleType* const tableSamples = Buffer::getArray();
00142         tableSamples[index] = value;
00143         tableSamples[index + tableLength] = value;
00144     }
00145     
00146     WavetableBase& normalise() throw()
00147     {
00148         Buffer::normalise();
00149         return *this;
00150     }
00151     
00152     static WavetableBase sineTable (const int size, const double repeats = 1.0) throw()
00153         {
00154                 return WavetableBase (Buffer::sineTable (size, repeats));
00155         }
00156         
00158         static WavetableBase cosineTable (const int size, const double repeats = 1.0) throw()
00159         {
00160                 return WavetableBase (Buffer::cosineTable (size, repeats));
00161         }
00162         
00164         static WavetableBase cosineWindow (const int size, const double repeats = 1.0) throw()
00165         {
00166                 return WavetableBase (Buffer::cosineWindow (size, repeats));
00167         }
00168         
00170         static WavetableBase triangleWindow (const int size) throw()
00171         {
00172                 return WavetableBase (Buffer::triangleWindow (size));
00173         }
00174         
00176         static WavetableBase bartlettWindow (const int size) throw()
00177         {
00178                 return WavetableBase (Buffer::bartlettWindow (size));
00179         }
00180         
00182         static WavetableBase hannWindow (const int size) throw()
00183         {
00184                 return WavetableBase (Buffer::hannWindow (size));
00185         }
00186         
00188         static WavetableBase hammingWindow (const int size) throw()
00189         {
00190                 return WavetableBase (Buffer::hammingWindow (size));
00191         }
00192         
00194         static WavetableBase blackmanWindow (const int size, const double alpha = 0.16) throw()
00195     {
00196                 return WavetableBase (Buffer::blackmanWindow (size, alpha));
00197     }
00198     
00199     static const WavetableBase& sine512() throw()
00200     {
00201         static const WavetableBase table (Buffer::sineTable (512, 1.0));
00202         return table;
00203     }    
00204         
00205     static const WavetableBase& sine8192() throw()
00206     {
00207         static const WavetableBase table (Buffer::sineTable (8192, 1.0));        
00208         return table;        
00209     }
00210     
00211     static const WavetableBase& cosine512() throw()
00212     {
00213         static const WavetableBase table (Buffer::cosineTable (512, 1.0));
00214         return table;
00215     }
00216     
00217     static const WavetableBase& cosine8192() throw()
00218     {
00219         static const WavetableBase table (Buffer::cosineTable (8192, 1.0));
00220         return table;
00221     }
00222     
00223     static WavetableBase harmonic (const int size, Buffer const& weights) throw()
00224         {
00225                 return WavetableBase (Buffer::harmonicTable (size, weights));
00226         }
00227 
00228     static WavetableBase harmonic8192 (Buffer const& weights) throw()
00229         {
00230                 return WavetableBase (Buffer::harmonicTable (8192, weights));
00231         }
00232     
00233     static const WavetableBase& harmonicSaw() throw()
00234         {
00235                 static const WavetableBase table (WavetableBase::harmonic8192 (Buffer::series (21, 1, 1)
00236                                                                        .reciprocal()
00237                                                                        .normalise()));
00238         return table;
00239         }
00240 
00241     static WavetableBase harmonicSaw (const int size, const int numHarmonics = 21) throw()
00242         {
00243                 return WavetableBase::harmonic (size, Buffer::series (numHarmonics, 1, 1)
00244                                         .reciprocal().normalise());
00245         }
00246     
00247     static const WavetableBase& harmonicSquare() throw()
00248         {
00249                 static const WavetableBase table (WavetableBase::harmonic8192 ((Buffer::series (21, 1, 1).reciprocal() * Buffer (SampleType (1), SampleType (0)))
00250                                                                        .normalise()));
00251         return table;
00252         }
00253     
00254     static WavetableBase harmonicSquare (const int size, const int numHarmonics = 21) throw()
00255         {
00256         plonk_assert (numHarmonics >= 2);
00257                 return WavetableBase::harmonic (size, (Buffer::series (numHarmonics, 1, 1).reciprocal()  * Buffer (SampleType (1), SampleType (0)))
00258                                         .normalise());
00259         }
00260     
00261     static const WavetableBase& harmonicTri() throw()
00262         {
00263                 static const WavetableBase table (WavetableBase::harmonic8192 ((Buffer::series (21, 1, 1).reciprocal() * Buffer (SampleType (1), SampleType (0), SampleType (-1), SampleType (0)))
00264                                                                        .squared()
00265                                                                        .normalise()));
00266         return table;
00267         }
00268     
00269     static WavetableBase harmonicTri (const int size, const int numHarmonics = 21) throw()
00270         {
00271         plonk_assert (numHarmonics >= 4);
00272                 return WavetableBase::harmonic (size, (Buffer::series (numHarmonics, 1, 1).reciprocal()  * Buffer (SampleType (1), SampleType (0), SampleType (-1), SampleType (0)))
00273                                         .squared()
00274                                         .normalise());
00275         }
00276 
00277     
00278     PLONK_OBJECTARROWOPERATOR(WavetableBase);
00279 
00280 };
00281 
00282 #endif // PLONK_WAVETABLE_H
 All Classes Functions Typedefs Enumerations Enumerator Properties