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.

129 lines
3.4KB

  1. #ifndef STK_WHISTLE_H
  2. #define STK_WHISTLE_H
  3. #include "Instrmnt.h"
  4. #include "Sphere.h"
  5. #include "Vector3D.h"
  6. #include "Noise.h"
  7. #include "SineWave.h"
  8. #include "OnePole.h"
  9. #include "Envelope.h"
  10. namespace stk {
  11. /***************************************************/
  12. /*! \class Whistle
  13. \brief STK police/referee whistle instrument class.
  14. This class implements a hybrid physical/spectral
  15. model of a police whistle (a la Cook).
  16. Control Change Numbers:
  17. - Noise Gain = 4
  18. - Fipple Modulation Frequency = 11
  19. - Fipple Modulation Gain = 1
  20. - Blowing Frequency Modulation = 2
  21. - Volume = 128
  22. by Perry R. Cook 1995--2017.
  23. */
  24. /***************************************************/
  25. class Whistle : public Instrmnt
  26. {
  27. public:
  28. //! Class constructor.
  29. /*!
  30. An StkError will be thrown if the rawwave path is incorrectly set.
  31. */
  32. Whistle( void );
  33. //! Class destructor.
  34. ~Whistle( void );
  35. //! Reset and clear all internal state.
  36. void clear( void );
  37. //! Set instrument parameters for a particular frequency.
  38. void setFrequency( StkFloat frequency );
  39. //! Apply breath velocity to instrument with given amplitude and rate of increase.
  40. void startBlowing( StkFloat amplitude, StkFloat rate );
  41. //! Decrease breath velocity with given rate of decrease.
  42. void stopBlowing( StkFloat rate );
  43. //! Start a note with the given frequency and amplitude.
  44. void noteOn( StkFloat frequency, StkFloat amplitude );
  45. //! Stop a note with the given amplitude (speed of decay).
  46. void noteOff( StkFloat amplitude );
  47. //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
  48. void controlChange( int number, StkFloat value );
  49. //! Compute and return one output sample.
  50. StkFloat tick( unsigned int channel = 0 );
  51. //! Fill a channel of the StkFrames object with computed outputs.
  52. /*!
  53. The \c channel argument must be less than the number of
  54. channels in the StkFrames argument (the first channel is specified
  55. by 0). However, range checking is only performed if _STK_DEBUG_
  56. is defined during compilation, in which case an out-of-range value
  57. will trigger an StkError exception.
  58. */
  59. StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
  60. protected:
  61. Vector3D *tempVectorP_;
  62. Vector3D tempVector_;
  63. OnePole onepole_;
  64. Noise noise_;
  65. Envelope envelope_;
  66. Sphere can_; // Declare a Spherical "can".
  67. Sphere pea_, bumper_; // One spherical "pea", and a spherical "bumper".
  68. SineWave sine_;
  69. StkFloat baseFrequency_;
  70. StkFloat noiseGain_;
  71. StkFloat fippleFreqMod_;
  72. StkFloat fippleGainMod_;
  73. StkFloat blowFreqMod_;
  74. StkFloat tickSize_;
  75. StkFloat canLoss_;
  76. int subSample_, subSampCount_;
  77. };
  78. inline StkFrames& Whistle :: tick( StkFrames& frames, unsigned int channel )
  79. {
  80. unsigned int nChannels = lastFrame_.channels();
  81. #if defined(_STK_DEBUG_)
  82. if ( channel > frames.channels() - nChannels ) {
  83. oStream_ << "Whistle::tick(): channel and StkFrames arguments are incompatible!";
  84. handleError( StkError::FUNCTION_ARGUMENT );
  85. }
  86. #endif
  87. StkFloat *samples = &frames[channel];
  88. unsigned int j, hop = frames.channels() - nChannels;
  89. if ( nChannels == 1 ) {
  90. for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
  91. *samples++ = tick();
  92. }
  93. else {
  94. for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
  95. *samples++ = tick();
  96. for ( j=1; j<nChannels; j++ )
  97. *samples++ = lastFrame_[j];
  98. }
  99. }
  100. return frames;
  101. }
  102. } // stk namespace
  103. #endif