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.

137 lines
3.9KB

  1. #ifndef STK_SINGWAVE_H
  2. #define STK_SINGWAVE_H
  3. #include "FileLoop.h"
  4. #include "Modulate.h"
  5. #include "Envelope.h"
  6. namespace stk {
  7. /***************************************************/
  8. /*! \class SingWave
  9. \brief STK "singing" looped soundfile class.
  10. This class loops a specified soundfile and modulates it both
  11. periodically and randomly to produce a pitched musical sound, like
  12. a simple voice or violin. In general, it is not be used alone
  13. because of "munchkinification" effects from pitch shifting.
  14. Within STK, it is used as an excitation source for other
  15. instruments.
  16. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  17. */
  18. /***************************************************/
  19. class SingWave : public Generator
  20. {
  21. public:
  22. //! Class constructor taking filename argument.
  23. /*!
  24. An StkError will be thrown if the file is not found, its format
  25. is unknown, or a read error occurs. If the soundfile has no
  26. header, the second argument should be \e true and the file data
  27. will be assumed to consist of 16-bit signed integers in big-endian
  28. byte order at a sample rate of 22050 Hz.
  29. */
  30. SingWave( std::string fileName, bool raw = false );
  31. //! Class destructor.
  32. ~SingWave( void );
  33. //! Reset file to beginning.
  34. void reset( void ) { wave_.reset(); lastFrame_[0] = 0.0; };
  35. //! Normalize the file to a maximum of +-1.0.
  36. void normalize( void ) { wave_.normalize(); };
  37. //! Normalize the file to a maximum of \e +- peak.
  38. void normalize( StkFloat peak ) { wave_.normalize( peak ); };
  39. //! Set looping parameters for a particular frequency.
  40. void setFrequency( StkFloat frequency );
  41. //! Set the vibrato frequency in Hz.
  42. void setVibratoRate( StkFloat rate ) { modulator_.setVibratoRate( rate ); };
  43. //! Set the vibrato gain.
  44. void setVibratoGain( StkFloat gain ) { modulator_.setVibratoGain( gain ); };
  45. //! Set the random-ness amount.
  46. void setRandomGain( StkFloat gain ) { modulator_.setRandomGain( gain ); };
  47. //! Set the sweep rate.
  48. void setSweepRate( StkFloat rate ) { sweepRate_ = rate; };
  49. //! Set the gain rate.
  50. void setGainRate( StkFloat rate ) { envelope_.setRate( rate ); };
  51. //! Set the gain target value.
  52. void setGainTarget( StkFloat target ) { envelope_.setTarget( target ); };
  53. //! Start a note.
  54. void noteOn( void ) { envelope_.keyOn(); };
  55. //! Stop a note.
  56. void noteOff( void ) { envelope_.keyOff(); };
  57. //! Return the last computed output value.
  58. StkFloat lastOut( void ) const { return lastFrame_[0]; };
  59. //! Compute and return one output sample.
  60. StkFloat tick( void );
  61. //! Fill a channel of the StkFrames object with computed outputs.
  62. /*!
  63. The \c channel argument must be less than the number of
  64. channels in the StkFrames argument (the first channel is specified
  65. by 0). However, range checking is only performed if _STK_DEBUG_
  66. is defined during compilation, in which case an out-of-range value
  67. will trigger an StkError exception.
  68. */
  69. StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
  70. protected:
  71. FileLoop wave_;
  72. Modulate modulator_;
  73. Envelope envelope_;
  74. Envelope pitchEnvelope_;
  75. StkFloat rate_;
  76. StkFloat sweepRate_;
  77. };
  78. inline StkFloat SingWave :: tick( void )
  79. {
  80. // Set the wave rate.
  81. StkFloat newRate = pitchEnvelope_.tick();
  82. newRate += newRate * modulator_.tick();
  83. wave_.setRate( newRate );
  84. lastFrame_[0] = wave_.tick();
  85. lastFrame_[0] *= envelope_.tick();
  86. return lastFrame_[0];
  87. }
  88. inline StkFrames& SingWave :: tick( StkFrames& frames, unsigned int channel )
  89. {
  90. #if defined(_STK_DEBUG_)
  91. if ( channel >= frames.channels() ) {
  92. oStream_ << "SingWave::tick(): channel and StkFrames arguments are incompatible!";
  93. handleError( StkError::FUNCTION_ARGUMENT );
  94. }
  95. #endif
  96. StkFloat *samples = &frames[channel];
  97. unsigned int hop = frames.channels();
  98. for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
  99. *samples = SingWave::tick();
  100. return frames;
  101. }
  102. } // stk namespace
  103. #endif