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.

165 lines
4.4KB

  1. /***************************************************/
  2. /*! \class FMVoices
  3. \brief STK singing FM synthesis instrument.
  4. This class implements 3 carriers and a common
  5. modulator, also referred to as algorithm 6 of
  6. the TX81Z.
  7. \code
  8. Algorithm 6 is :
  9. /->1 -\
  10. 4-|-->2 - +-> Out
  11. \->3 -/
  12. \endcode
  13. Control Change Numbers:
  14. - Vowel = 2
  15. - Spectral Tilt = 4
  16. - LFO Speed = 11
  17. - LFO Depth = 1
  18. - ADSR 2 & 4 Target = 128
  19. The basic Chowning/Stanford FM patent expired
  20. in 1995, but there exist follow-on patents,
  21. mostly assigned to Yamaha. If you are of the
  22. type who should worry about this (making
  23. money) worry away.
  24. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  25. */
  26. /***************************************************/
  27. #include "FMVoices.h"
  28. #include "SKINImsg.h"
  29. #include "Phonemes.h"
  30. namespace stk {
  31. FMVoices :: FMVoices( void )
  32. : FM()
  33. {
  34. // Concatenate the STK rawwave path to the rawwave files
  35. for ( unsigned int i=0; i<3; i++ )
  36. waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
  37. waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
  38. this->setRatio(0, 2.00);
  39. this->setRatio(1, 4.00);
  40. this->setRatio(2, 12.0);
  41. this->setRatio(3, 1.00);
  42. gains_[3] = fmGains_[80];
  43. adsr_[0]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);
  44. adsr_[1]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);
  45. adsr_[2]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);
  46. adsr_[3]->setAllTimes( 0.01, 0.01, fmSusLevels_[15], 0.5);
  47. twozero_.setGain( 0.0 );
  48. modDepth_ = (StkFloat) 0.005;
  49. currentVowel_ = 0;
  50. tilt_[0] = 1.0;
  51. tilt_[1] = 0.5;
  52. tilt_[2] = 0.2;
  53. mods_[0] = 1.0;
  54. mods_[1] = 1.1;
  55. mods_[2] = 1.1;
  56. baseFrequency_ = 110.0;
  57. this->setFrequency( 110.0 );
  58. }
  59. FMVoices :: ~FMVoices( void )
  60. {
  61. }
  62. void FMVoices :: setFrequency( StkFloat frequency )
  63. {
  64. #if defined(_STK_DEBUG_)
  65. if ( frequency <= 0.0 ) {
  66. oStream_ << "FMVoices::setFrequency: argument is less than or equal to zero!";
  67. handleError( StkError::WARNING ); return;
  68. }
  69. #endif
  70. StkFloat temp, temp2 = 0.0;
  71. int tempi = 0;
  72. unsigned int i = 0;
  73. if (currentVowel_ < 32) {
  74. i = currentVowel_;
  75. temp2 = 0.9;
  76. }
  77. else if (currentVowel_ < 64) {
  78. i = currentVowel_ - 32;
  79. temp2 = 1.0;
  80. }
  81. else if (currentVowel_ < 96) {
  82. i = currentVowel_ - 64;
  83. temp2 = 1.1;
  84. }
  85. else if (currentVowel_ < 128) {
  86. i = currentVowel_ - 96;
  87. temp2 = 1.2;
  88. }
  89. else return;
  90. baseFrequency_ = frequency;
  91. temp = (temp2 * Phonemes::formantFrequency(i, 0) / baseFrequency_) + 0.5;
  92. tempi = (int) temp;
  93. this->setRatio( 0, (StkFloat) tempi );
  94. temp = (temp2 * Phonemes::formantFrequency(i, 1) / baseFrequency_) + 0.5;
  95. tempi = (int) temp;
  96. this->setRatio( 1, (StkFloat) tempi );
  97. temp = (temp2 * Phonemes::formantFrequency(i, 2) / baseFrequency_) + 0.5;
  98. tempi = (int) temp;
  99. this->setRatio( 2, (StkFloat) tempi );
  100. gains_[0] = 1.0;
  101. gains_[1] = 1.0;
  102. gains_[2] = 1.0;
  103. }
  104. void FMVoices :: noteOn( StkFloat frequency, StkFloat amplitude )
  105. {
  106. this->setFrequency( frequency );
  107. tilt_[0] = amplitude;
  108. tilt_[1] = amplitude * amplitude;
  109. tilt_[2] = tilt_[1] * amplitude;
  110. this->keyOn();
  111. }
  112. void FMVoices :: controlChange( int number, StkFloat value )
  113. {
  114. #if defined(_STK_DEBUG_)
  115. if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
  116. oStream_ << "FMVoices::controlChange: value (" << value << ") is out of range!";
  117. handleError( StkError::WARNING ); return;
  118. }
  119. #endif
  120. StkFloat normalizedValue = value * ONE_OVER_128;
  121. if (number == __SK_Breath_) // 2
  122. gains_[3] = fmGains_[(int) ( normalizedValue * 99.9 )];
  123. else if (number == __SK_FootControl_) { // 4
  124. currentVowel_ = (int) (normalizedValue * 127.0);
  125. this->setFrequency(baseFrequency_);
  126. }
  127. else if (number == __SK_ModFrequency_) // 11
  128. this->setModulationSpeed( normalizedValue * 12.0);
  129. else if (number == __SK_ModWheel_) // 1
  130. this->setModulationDepth( normalizedValue );
  131. else if (number == __SK_AfterTouch_Cont_) { // 128
  132. tilt_[0] = normalizedValue;
  133. tilt_[1] = normalizedValue * normalizedValue;
  134. tilt_[2] = tilt_[1] * normalizedValue;
  135. }
  136. #if defined(_STK_DEBUG_)
  137. else {
  138. oStream_ << "FMVoices::controlChange: undefined control number (" << number << ")!";
  139. handleError( StkError::WARNING );
  140. }
  141. #endif
  142. }
  143. } // stk namespace