You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.7KB

  1. #ifndef STK_MODULATE_H
  2. #define STK_MODULATE_H
  3. #include "Generator.h"
  4. #include "SineWave.h"
  5. #include "Noise.h"
  6. #include "OnePole.h"
  7. namespace stk {
  8. /***************************************************/
  9. /*! \class Modulate
  10. \brief STK periodic/random modulator.
  11. This class combines random and periodic
  12. modulations to give a nice, natural human
  13. modulation function.
  14. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  15. */
  16. /***************************************************/
  17. class Modulate : public Generator
  18. {
  19. public:
  20. //! Class constructor.
  21. /*!
  22. An StkError can be thrown if the rawwave path is incorrect.
  23. */
  24. Modulate( void );
  25. //! Class destructor.
  26. ~Modulate( void );
  27. //! Reset internal state.
  28. void reset( void ) { lastFrame_[0] = 0.0; };
  29. //! Set the periodic (vibrato) rate or frequency in Hz.
  30. void setVibratoRate( StkFloat rate ) { vibrato_.setFrequency( rate ); };
  31. //! Set the periodic (vibrato) gain.
  32. void setVibratoGain( StkFloat gain ) { vibratoGain_ = gain; };
  33. //! Set the random modulation gain.
  34. void setRandomGain( StkFloat gain );
  35. //! Return the last computed output value.
  36. StkFloat lastOut( void ) const { return lastFrame_[0]; };
  37. //! Compute and return one output sample.
  38. StkFloat tick( void );
  39. //! Fill a channel of the StkFrames object with computed outputs.
  40. /*!
  41. The \c channel argument must be less than the number of
  42. channels in the StkFrames argument (the first channel is specified
  43. by 0). However, range checking is only performed if _STK_DEBUG_
  44. is defined during compilation, in which case an out-of-range value
  45. will trigger an StkError exception.
  46. */
  47. StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
  48. protected:
  49. void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
  50. SineWave vibrato_;
  51. Noise noise_;
  52. OnePole filter_;
  53. StkFloat vibratoGain_;
  54. StkFloat randomGain_;
  55. unsigned int noiseRate_;
  56. unsigned int noiseCounter_;
  57. };
  58. inline StkFloat Modulate :: tick( void )
  59. {
  60. // Compute periodic and random modulations.
  61. lastFrame_[0] = vibratoGain_ * vibrato_.tick();
  62. if ( noiseCounter_++ >= noiseRate_ ) {
  63. noise_.tick();
  64. noiseCounter_ = 0;
  65. }
  66. lastFrame_[0] += filter_.tick( noise_.lastOut() );
  67. return lastFrame_[0];
  68. }
  69. inline StkFrames& Modulate :: tick( StkFrames& frames, unsigned int channel )
  70. {
  71. #if defined(_STK_DEBUG_)
  72. if ( channel >= frames.channels() ) {
  73. oStream_ << "Modulate::tick(): channel and StkFrames arguments are incompatible!";
  74. handleError( StkError::FUNCTION_ARGUMENT );
  75. }
  76. #endif
  77. StkFloat *samples = &frames[channel];
  78. unsigned int hop = frames.channels();
  79. for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
  80. *samples = Modulate::tick();
  81. return frames;
  82. }
  83. } // stk namespace
  84. #endif