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.

183 lines
5.4KB

  1. /***************************************************/
  2. /*! \class ModalBar
  3. \brief STK resonant bar instrument class.
  4. This class implements a number of different
  5. struck bar instruments. It inherits from the
  6. Modal class.
  7. Control Change Numbers:
  8. - Stick Hardness = 2
  9. - Stick Position = 4
  10. - Vibrato Gain = 8
  11. - Vibrato Frequency = 11
  12. - Direct Stick Mix = 1
  13. - Volume = 128
  14. - Modal Presets = 16
  15. - Marimba = 0
  16. - Vibraphone = 1
  17. - Agogo = 2
  18. - Wood1 = 3
  19. - Reso = 4
  20. - Wood2 = 5
  21. - Beats = 6
  22. - Two Fixed = 7
  23. - Clump = 8
  24. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  25. */
  26. /***************************************************/
  27. #include "ModalBar.h"
  28. #include "SKINImsg.h"
  29. #include <cmath>
  30. namespace stk {
  31. ModalBar :: ModalBar( void )
  32. : Modal()
  33. {
  34. // Concatenate the STK rawwave path to the rawwave file
  35. wave_ = new FileWvIn( (Stk::rawwavePath() + "marmstk1.raw").c_str(), true );
  36. wave_->setRate( 0.5 * 22050.0 / Stk::sampleRate() );
  37. // Set the resonances for preset 0 (marimba).
  38. this->setPreset( 0 );
  39. }
  40. ModalBar :: ~ModalBar( void )
  41. {
  42. delete wave_;
  43. }
  44. void ModalBar :: setStickHardness( StkFloat hardness )
  45. {
  46. if ( hardness < 0.0 || hardness > 1.0 ) {
  47. oStream_ << "ModalBar::setStickHardness: parameter is out of range!";
  48. handleError( StkError::WARNING ); return;
  49. }
  50. stickHardness_ = hardness;
  51. wave_->setRate( (0.25 * pow(4.0, stickHardness_) ) );
  52. masterGain_ = 0.1 + (1.8 * stickHardness_);
  53. }
  54. void ModalBar :: setStrikePosition( StkFloat position )
  55. {
  56. if ( position < 0.0 || position > 1.0 ) {
  57. oStream_ << "ModalBar::setStrikePosition: parameter is out of range!";
  58. handleError( StkError::WARNING ); return;
  59. }
  60. strikePosition_ = position;
  61. // Hack only first three modes.
  62. StkFloat temp2 = position * PI;
  63. StkFloat temp = sin(temp2);
  64. this->setModeGain(0, 0.12 * temp);
  65. temp = sin(0.05 + (3.9 * temp2));
  66. this->setModeGain(1, -0.03 * temp);
  67. temp = sin(-0.05 + (11 * temp2));
  68. this->setModeGain(2, 0.11 * temp);
  69. }
  70. void ModalBar :: setPreset( int preset )
  71. {
  72. // Presets:
  73. // First line: relative modal frequencies (negative number is
  74. // a fixed mode that doesn't scale with frequency
  75. // Second line: resonances of the modes
  76. // Third line: mode volumes
  77. // Fourth line: stickHardness, strikePosition, and direct stick
  78. // gain (mixed directly into the output
  79. static StkFloat presets[9][4][4] = {
  80. {{1.0, 3.99, 10.65, -2443}, // Marimba
  81. {0.9996, 0.9994, 0.9994, 0.999},
  82. {0.04, 0.01, 0.01, 0.008},
  83. {0.429688, 0.445312, 0.093750}},
  84. {{1.0, 2.01, 3.9, 14.37}, // Vibraphone
  85. {0.99995, 0.99991, 0.99992, 0.9999},
  86. {0.025, 0.015, 0.015, 0.015 },
  87. {0.390625,0.570312,0.078125}},
  88. {{1.0, 4.08, 6.669, -3725.0}, // Agogo
  89. {0.999, 0.999, 0.999, 0.999},
  90. {0.06, 0.05, 0.03, 0.02},
  91. {0.609375,0.359375,0.140625}},
  92. {{1.0, 2.777, 7.378, 15.377}, // Wood1
  93. {0.996, 0.994, 0.994, 0.99},
  94. {0.04, 0.01, 0.01, 0.008},
  95. {0.460938,0.375000,0.046875}},
  96. {{1.0, 2.777, 7.378, 15.377}, // Reso
  97. {0.99996, 0.99994, 0.99994, 0.9999},
  98. {0.02, 0.005, 0.005, 0.004},
  99. {0.453125,0.250000,0.101562}},
  100. {{1.0, 1.777, 2.378, 3.377}, // Wood2
  101. {0.996, 0.994, 0.994, 0.99},
  102. {0.04, 0.01, 0.01, 0.008},
  103. {0.312500,0.445312,0.109375}},
  104. {{1.0, 1.004, 1.013, 2.377}, // Beats
  105. {0.9999, 0.9999, 0.9999, 0.999},
  106. {0.02, 0.005, 0.005, 0.004},
  107. {0.398438,0.296875,0.070312}},
  108. {{1.0, 4.0, -1320.0, -3960.0}, // 2Fix
  109. {0.9996, 0.999, 0.9994, 0.999},
  110. {0.04, 0.01, 0.01, 0.008},
  111. {0.453125,0.453125,0.070312}},
  112. {{1.0, 1.217, 1.475, 1.729}, // Clump
  113. {0.999, 0.999, 0.999, 0.999},
  114. {0.03, 0.03, 0.03, 0.03 },
  115. {0.390625,0.570312,0.078125}},
  116. };
  117. int temp = (preset % 9);
  118. for (unsigned int i=0; i<nModes_; i++) {
  119. this->setRatioAndRadius(i, presets[temp][0][i], presets[temp][1][i]);
  120. this->setModeGain(i, presets[temp][2][i]);
  121. }
  122. this->setStickHardness(presets[temp][3][0]);
  123. this->setStrikePosition(presets[temp][3][1]);
  124. directGain_ = presets[temp][3][2];
  125. if (temp == 1) // vibraphone
  126. vibratoGain_ = 0.2;
  127. else
  128. vibratoGain_ = 0.0;
  129. }
  130. void ModalBar :: controlChange( int number, StkFloat value )
  131. {
  132. #if defined(_STK_DEBUG_)
  133. if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
  134. oStream_ << "ModalBar::controlChange: value (" << value << ") is out of range!";
  135. handleError( StkError::WARNING ); return;
  136. }
  137. #endif
  138. StkFloat normalizedValue = value * ONE_OVER_128;
  139. if (number == __SK_StickHardness_) // 2
  140. this->setStickHardness( normalizedValue );
  141. else if (number == __SK_StrikePosition_) // 4
  142. this->setStrikePosition( normalizedValue );
  143. else if (number == __SK_ProphesyRibbon_) // 16
  144. this->setPreset((int) value);
  145. else if (number == __SK_Balance_) // 8
  146. vibratoGain_ = normalizedValue * 0.3;
  147. else if (number == __SK_ModWheel_) // 1
  148. directGain_ = normalizedValue;
  149. else if (number == __SK_ModFrequency_) // 11
  150. vibrato_.setFrequency( normalizedValue * 12.0 );
  151. else if (number == __SK_AfterTouch_Cont_) // 128
  152. envelope_.setTarget( normalizedValue );
  153. #if defined(_STK_DEBUG_)
  154. else {
  155. oStream_ << "ModalBar::controlChange: undefined control number (" << number << ")!";
  156. handleError( StkError::WARNING );
  157. }
  158. #endif
  159. }
  160. } // stk namespace