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.

180 lines
4.3KB

  1. /***************************************************/
  2. /*! \class FM
  3. \brief STK abstract FM synthesis base class.
  4. This class controls an arbitrary number of
  5. waves and envelopes, determined via a
  6. constructor argument.
  7. Control Change Numbers:
  8. - Control One = 2
  9. - Control Two = 4
  10. - LFO Speed = 11
  11. - LFO Depth = 1
  12. - ADSR 2 & 4 Target = 128
  13. The basic Chowning/Stanford FM patent expired
  14. in 1995, but there exist follow-on patents,
  15. mostly assigned to Yamaha. If you are of the
  16. type who should worry about this (making
  17. money) worry away.
  18. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  19. */
  20. /***************************************************/
  21. #include "FM.h"
  22. #include "SKINImsg.h"
  23. namespace stk {
  24. FM :: FM( unsigned int operators )
  25. : nOperators_(operators)
  26. {
  27. if ( nOperators_ == 0 ) {
  28. oStream_ << "FM::FM: Number of operators must be greater than zero!";
  29. handleError( StkError::FUNCTION_ARGUMENT );
  30. }
  31. twozero_.setB2( -1.0 );
  32. twozero_.setGain( 0.0 );
  33. vibrato_.setFrequency( 6.0 );
  34. unsigned int j;
  35. adsr_.resize( nOperators_ );
  36. waves_.resize( nOperators_ );
  37. for (j=0; j<nOperators_; j++ ) {
  38. ratios_.push_back( 1.0 );
  39. gains_.push_back( 1.0 );
  40. adsr_[j] = new ADSR();
  41. }
  42. modDepth_ = 0.0;
  43. control1_ = 1.0;
  44. control2_ = 1.0;
  45. baseFrequency_ = 440.0;
  46. int i;
  47. StkFloat temp = 1.0;
  48. for (i=99; i>=0; i--) {
  49. fmGains_[i] = temp;
  50. temp *= 0.933033;
  51. }
  52. temp = 1.0;
  53. for (i=15; i>=0; i--) {
  54. fmSusLevels_[i] = temp;
  55. temp *= 0.707101;
  56. }
  57. temp = 8.498186;
  58. for (i=0; i<32; i++) {
  59. fmAttTimes_[i] = temp;
  60. temp *= 0.707101;
  61. }
  62. }
  63. FM :: ~FM( void )
  64. {
  65. for (unsigned int i=0; i<nOperators_; i++ ) {
  66. delete waves_[i];
  67. delete adsr_[i];
  68. }
  69. }
  70. void FM :: loadWaves( const char **filenames )
  71. {
  72. for (unsigned int i=0; i<nOperators_; i++ )
  73. waves_[i] = new FileLoop( filenames[i], true );
  74. }
  75. void FM :: setFrequency( StkFloat frequency )
  76. {
  77. #if defined(_STK_DEBUG_)
  78. if ( frequency <= 0.0 ) {
  79. oStream_ << "FM::setFrequency: argument is less than or equal to zero!";
  80. handleError( StkError::WARNING ); return;
  81. }
  82. #endif
  83. baseFrequency_ = frequency;
  84. for ( unsigned int i=0; i<nOperators_; i++ )
  85. waves_[i]->setFrequency( baseFrequency_ * ratios_[i] );
  86. }
  87. void FM :: setRatio( unsigned int waveIndex, StkFloat ratio )
  88. {
  89. if ( waveIndex >= nOperators_ ) {
  90. oStream_ << "FM:setRatio: waveIndex parameter is greater than the number of operators!";
  91. handleError( StkError::WARNING ); return;
  92. }
  93. ratios_[waveIndex] = ratio;
  94. if (ratio > 0.0)
  95. waves_[waveIndex]->setFrequency( baseFrequency_ * ratio );
  96. else
  97. waves_[waveIndex]->setFrequency( ratio );
  98. }
  99. void FM :: setGain( unsigned int waveIndex, StkFloat gain )
  100. {
  101. if ( waveIndex >= nOperators_ ) {
  102. oStream_ << "FM::setGain: waveIndex parameter is greater than the number of operators!";
  103. handleError( StkError::WARNING ); return;
  104. }
  105. gains_[waveIndex] = gain;
  106. }
  107. void FM :: keyOn( void )
  108. {
  109. for ( unsigned int i=0; i<nOperators_; i++ )
  110. adsr_[i]->keyOn();
  111. }
  112. void FM :: keyOff( void )
  113. {
  114. for ( unsigned int i=0; i<nOperators_; i++ )
  115. adsr_[i]->keyOff();
  116. }
  117. void FM :: noteOff( StkFloat amplitude )
  118. {
  119. this->keyOff();
  120. }
  121. void FM :: controlChange( int number, StkFloat value )
  122. {
  123. #if defined(_STK_DEBUG_)
  124. if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
  125. oStream_ << "FM::controlChange: value (" << value << ") is out of range!";
  126. handleError( StkError::WARNING ); return;
  127. }
  128. #endif
  129. StkFloat normalizedValue = value * ONE_OVER_128;
  130. if (number == __SK_Breath_) // 2
  131. this->setControl1( normalizedValue );
  132. else if (number == __SK_FootControl_) // 4
  133. this->setControl2( normalizedValue );
  134. else if (number == __SK_ModFrequency_) // 11
  135. this->setModulationSpeed( normalizedValue * 12.0);
  136. else if (number == __SK_ModWheel_) // 1
  137. this->setModulationDepth( normalizedValue );
  138. else if (number == __SK_AfterTouch_Cont_) { // 128
  139. //adsr_[0]->setTarget( normalizedValue );
  140. adsr_[1]->setTarget( normalizedValue );
  141. //adsr_[2]->setTarget( normalizedValue );
  142. adsr_[3]->setTarget( normalizedValue );
  143. }
  144. #if defined(_STK_DEBUG_)
  145. else {
  146. oStream_ << "FM::controlChange: undefined control number (" << number << ")!";
  147. handleError( StkError::WARNING );
  148. }
  149. #endif
  150. }
  151. } // stk namespace