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.

128 lines
3.5KB

  1. #ifndef STK_BEETHREE_H
  2. #define STK_BEETHREE_H
  3. #include "FM.h"
  4. namespace stk {
  5. /***************************************************/
  6. /*! \class BeeThree
  7. \brief STK Hammond-oid organ FM synthesis instrument.
  8. This class implements a simple 4 operator
  9. topology, also referred to as algorithm 8 of
  10. the TX81Z.
  11. \code
  12. Algorithm 8 is :
  13. 1 --.
  14. 2 -\|
  15. +-> Out
  16. 3 -/|
  17. 4 --
  18. \endcode
  19. Control Change Numbers:
  20. - Operator 4 (feedback) Gain = 2
  21. - Operator 3 Gain = 4
  22. - LFO Speed = 11
  23. - LFO Depth = 1
  24. - ADSR 2 & 4 Target = 128
  25. The basic Chowning/Stanford FM patent expired
  26. in 1995, but there exist follow-on patents,
  27. mostly assigned to Yamaha. If you are of the
  28. type who should worry about this (making
  29. money) worry away.
  30. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  31. */
  32. /***************************************************/
  33. class BeeThree : public FM
  34. {
  35. public:
  36. //! Class constructor.
  37. /*!
  38. An StkError will be thrown if the rawwave path is incorrectly set.
  39. */
  40. BeeThree( void );
  41. //! Class destructor.
  42. ~BeeThree( void );
  43. //! Start a note with the given frequency and amplitude.
  44. void noteOn( StkFloat frequency, StkFloat amplitude );
  45. //! Compute and return one output sample.
  46. StkFloat tick( unsigned int channel = 0 );
  47. //! Fill a channel of the StkFrames object with computed outputs.
  48. /*!
  49. The \c channel argument must be less than the number of
  50. channels in the StkFrames argument (the first channel is specified
  51. by 0). However, range checking is only performed if _STK_DEBUG_
  52. is defined during compilation, in which case an out-of-range value
  53. will trigger an StkError exception.
  54. */
  55. StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
  56. protected:
  57. };
  58. inline StkFloat BeeThree :: tick( unsigned int )
  59. {
  60. StkFloat temp;
  61. if ( modDepth_ > 0.0 ) {
  62. temp = 1.0 + ( modDepth_ * vibrato_.tick() * 0.1 );
  63. waves_[0]->setFrequency( baseFrequency_ * temp * ratios_[0] );
  64. waves_[1]->setFrequency( baseFrequency_ * temp * ratios_[1] );
  65. waves_[2]->setFrequency( baseFrequency_ * temp * ratios_[2] );
  66. waves_[3]->setFrequency( baseFrequency_ * temp * ratios_[3] );
  67. }
  68. waves_[3]->addPhaseOffset( twozero_.lastOut() );
  69. temp = control1_ * 2.0 * gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
  70. twozero_.tick( temp );
  71. temp += control2_ * 2.0 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
  72. temp += gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
  73. temp += gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
  74. lastFrame_[0] = temp * 0.125;
  75. return lastFrame_[0];
  76. }
  77. inline StkFrames& BeeThree :: tick( StkFrames& frames, unsigned int channel )
  78. {
  79. unsigned int nChannels = lastFrame_.channels();
  80. #if defined(_STK_DEBUG_)
  81. if ( channel > frames.channels() - nChannels ) {
  82. oStream_ << "BeeThree::tick(): channel and StkFrames arguments are incompatible!";
  83. handleError( StkError::FUNCTION_ARGUMENT );
  84. }
  85. #endif
  86. StkFloat *samples = &frames[channel];
  87. unsigned int j, hop = frames.channels() - nChannels;
  88. if ( nChannels == 1 ) {
  89. for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
  90. *samples++ = tick();
  91. }
  92. else {
  93. for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
  94. *samples++ = tick();
  95. for ( j=1; j<nChannels; j++ )
  96. *samples++ = lastFrame_[j];
  97. }
  98. }
  99. return frames;
  100. }
  101. } // stk namespace
  102. #endif