annotate stk/include/SineWave.h @ 1:2ca5d7440b5c tip

added README
author Fiore Martin <f.martin@qmul.ac.uk>
date Fri, 26 Feb 2016 16:11:20 +0000
parents 3004dd663202
children
rev   line source
f@0 1 #ifndef STK_SINEWAVE_H
f@0 2 #define STK_SINEWAVE_H
f@0 3
f@0 4 const unsigned long TABLE_SIZE = 2048;
f@0 5
f@0 6 #include "Generator.h"
f@0 7
f@0 8 namespace stk {
f@0 9
f@0 10 /***************************************************/
f@0 11 /*! \class SineWave
f@0 12 \brief STK sinusoid oscillator class.
f@0 13
f@0 14 This class computes and saves a static sine "table" that can be
f@0 15 shared by multiple instances. It has an interface similar to the
f@0 16 WaveLoop class but inherits from the Generator class. Output
f@0 17 values are computed using linear interpolation.
f@0 18
f@0 19 The "table" length, set in SineWave.h, is 2048 samples by default.
f@0 20
f@0 21 by Perry R. Cook and Gary P. Scavone, 1995--2014.
f@0 22 */
f@0 23 /***************************************************/
f@0 24
f@0 25 class SineWave : public Generator
f@0 26 {
f@0 27 public:
f@0 28 //! Default constructor.
f@0 29 SineWave( void );
f@0 30
f@0 31 //! Class destructor.
f@0 32 ~SineWave( void );
f@0 33
f@0 34 //! Clear output and reset time pointer to zero.
f@0 35 void reset( void );
f@0 36
f@0 37 //! Set the data read rate in samples. The rate can be negative.
f@0 38 /*!
f@0 39 If the rate value is negative, the data is read in reverse order.
f@0 40 */
f@0 41 void setRate( StkFloat rate ) { rate_ = rate; };
f@0 42
f@0 43 //! Set the data interpolation rate based on a looping frequency.
f@0 44 /*!
f@0 45 This function determines the interpolation rate based on the file
f@0 46 size and the current Stk::sampleRate. The \e frequency value
f@0 47 corresponds to file cycles per second. The frequency can be
f@0 48 negative, in which case the loop is read in reverse order.
f@0 49 */
f@0 50 void setFrequency( StkFloat frequency );
f@0 51
f@0 52 //! Increment the read pointer by \e time in samples, modulo the table size.
f@0 53 void addTime( StkFloat time );
f@0 54
f@0 55 //! Increment the read pointer by a normalized \e phase value.
f@0 56 /*!
f@0 57 This function increments the read pointer by a normalized phase
f@0 58 value, such that \e phase = 1.0 corresponds to a 360 degree phase
f@0 59 shift. Positive or negative values are possible.
f@0 60 */
f@0 61 void addPhase( StkFloat phase );
f@0 62
f@0 63 //! Add a normalized phase offset to the read pointer.
f@0 64 /*!
f@0 65 A \e phaseOffset = 1.0 corresponds to a 360 degree phase
f@0 66 offset. Positive or negative values are possible.
f@0 67 */
f@0 68 void addPhaseOffset( StkFloat phaseOffset );
f@0 69
f@0 70 //! Return the last computed output value.
f@0 71 StkFloat lastOut( void ) const { return lastFrame_[0]; };
f@0 72
f@0 73 //! Compute and return one output sample.
f@0 74 StkFloat tick( void );
f@0 75
f@0 76 //! Fill a channel of the StkFrames object with computed outputs.
f@0 77 /*!
f@0 78 The \c channel argument must be less than the number of
f@0 79 channels in the StkFrames argument (the first channel is specified
f@0 80 by 0). However, range checking is only performed if _STK_DEBUG_
f@0 81 is defined during compilation, in which case an out-of-range value
f@0 82 will trigger an StkError exception.
f@0 83 */
f@0 84 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
f@0 85
f@0 86 protected:
f@0 87
f@0 88 void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
f@0 89
f@0 90 static StkFrames table_;
f@0 91 StkFloat time_;
f@0 92 StkFloat rate_;
f@0 93 StkFloat phaseOffset_;
f@0 94 unsigned int iIndex_;
f@0 95 StkFloat alpha_;
f@0 96
f@0 97 };
f@0 98
f@0 99 inline StkFloat SineWave :: tick( void )
f@0 100 {
f@0 101 // Check limits of time address ... if necessary, recalculate modulo
f@0 102 // TABLE_SIZE.
f@0 103 while ( time_ < 0.0 )
f@0 104 time_ += TABLE_SIZE;
f@0 105 while ( time_ >= TABLE_SIZE )
f@0 106 time_ -= TABLE_SIZE;
f@0 107
f@0 108 iIndex_ = (unsigned int) time_;
f@0 109 alpha_ = time_ - iIndex_;
f@0 110 StkFloat tmp = table_[ iIndex_ ];
f@0 111 tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
f@0 112
f@0 113 // Increment time, which can be negative.
f@0 114 time_ += rate_;
f@0 115
f@0 116 lastFrame_[0] = tmp;
f@0 117 return lastFrame_[0];
f@0 118 }
f@0 119
f@0 120 inline StkFrames& SineWave :: tick( StkFrames& frames, unsigned int channel )
f@0 121 {
f@0 122 #if defined(_STK_DEBUG_)
f@0 123 if ( channel >= frames.channels() ) {
f@0 124 oStream_ << "SineWave::tick(): channel and StkFrames arguments are incompatible!";
f@0 125 handleError( StkError::FUNCTION_ARGUMENT );
f@0 126 }
f@0 127 #endif
f@0 128
f@0 129 StkFloat *samples = &frames[channel];
f@0 130 StkFloat tmp = 0.0;
f@0 131
f@0 132 unsigned int hop = frames.channels();
f@0 133 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
f@0 134
f@0 135 // Check limits of time address ... if necessary, recalculate modulo
f@0 136 // TABLE_SIZE.
f@0 137 while ( time_ < 0.0 )
f@0 138 time_ += TABLE_SIZE;
f@0 139 while ( time_ >= TABLE_SIZE )
f@0 140 time_ -= TABLE_SIZE;
f@0 141
f@0 142 iIndex_ = (unsigned int) time_;
f@0 143 alpha_ = time_ - iIndex_;
f@0 144 tmp = table_[ iIndex_ ];
f@0 145 tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
f@0 146 *samples = tmp;
f@0 147
f@0 148 // Increment time, which can be negative.
f@0 149 time_ += rate_;
f@0 150 }
f@0 151
f@0 152 lastFrame_[0] = tmp;
f@0 153 return frames;
f@0 154 }
f@0 155
f@0 156 } // stk namespace
f@0 157
f@0 158 #endif
f@0 159