⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmvoices.cpp

📁 Mobile STK for Symbian OS V0.1
💻 CPP
字号:
/***************************************************//*! \class FMVoices    \brief STK singing FM synthesis instrument.    This class implements 3 carriers and a common    modulator, also referred to as algorithm 6 of    the TX81Z.    \code    Algorithm 6 is :                        /->1 -\                     4-|-->2 - +-> Out                        \->3 -/    \endcode    Control Change Numbers:        - Vowel = 2       - Spectral Tilt = 4       - LFO Speed = 11       - LFO Depth = 1       - ADSR 2 & 4 Target = 128    The basic Chowning/Stanford FM patent expired    in 1995, but there exist follow-on patents,    mostly assigned to Yamaha.  If you are of the    type who should worry about this (making    money) worry away.    by Perry R. Cook and Gary P. Scavone, 1995 - 2005.*//***************************************************/#include "FMVoices.h"//#if !defined(SYMBIAN)#include "SKINI.msg"#include "Phonemes.h"FMVoices :: FMVoices()  : FM(){  // Concatenate the STK rawwave path to the rawwave files  for ( unsigned int i=0; i<3; i++ )#if !defined(SYMBIAN)    waves_[i] = new WaveLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );  waves_[3] = new WaveLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );#else	  waves_[i] = new WaveLoop( "c:\\STK\\rawwaves\\sinewave.raw", true );  waves_[3] = new WaveLoop( "c:\\STK\\rawwaves\\fwavblnk.raw", true );#endif  this->setRatio(0, 2.00);  this->setRatio(1, 4.00);  this->setRatio(2, 12.0);  this->setRatio(3, 1.00);  gains_[3] = fmGains_[80];  adsr_[0]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);  adsr_[1]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);  adsr_[2]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);  adsr_[3]->setAllTimes( 0.01, 0.01, fmSusLevels_[15], 0.5);  twozero_.setGain( 0.0 );  modDepth_ = (StkFloat) 0.005;  currentVowel_ = 0;  tilt_[0] = 1.0;  tilt_[1] = 0.5;  tilt_[2] = 0.2;      mods_[0] = 1.0;  mods_[1] = 1.1;  mods_[2] = 1.1;  baseFrequency_ = 110.0;  this->setFrequency( 110.0 );    }  FMVoices :: ~FMVoices(){}void FMVoices :: setFrequency(StkFloat frequency){  StkFloat temp, temp2 = 0.0;  int tempi = 0;  unsigned int i = 0;  if (currentVowel_ < 32)	{    i = currentVowel_;    temp2 = 0.9;  }  else if (currentVowel_ < 64)	{    i = currentVowel_ - 32;    temp2 = 1.0;  }  else if (currentVowel_ < 96)	{    i = currentVowel_ - 64;    temp2 = 1.1;  }  else if (currentVowel_ <= 128)	{    i = currentVowel_ - 96;    temp2 = 1.2;  }  baseFrequency_ = frequency;  temp = (temp2 * Phonemes::formantFrequency(i, 0) / baseFrequency_) + 0.5;  tempi = (int) temp;  this->setRatio( 0, (StkFloat) tempi );  temp = (temp2 * Phonemes::formantFrequency(i, 1) / baseFrequency_) + 0.5;  tempi = (int) temp;  this->setRatio( 1, (StkFloat) tempi );  temp = (temp2 * Phonemes::formantFrequency(i, 2) / baseFrequency_) + 0.5;  tempi = (int) temp;  this->setRatio( 2, (StkFloat) tempi );      gains_[0] = 1.0;  gains_[1] = 1.0;  gains_[2] = 1.0;}void FMVoices :: noteOn(StkFloat frequency, StkFloat amplitude){  this->setFrequency( frequency );  tilt_[0] = amplitude;  tilt_[1] = amplitude * amplitude;  tilt_[2] = tilt_[1] * amplitude;  this->keyOn();#if defined(_STK_DEBUG_)  errorString_ << "FMVoices::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';  handleError( StkError::DEBUG_WARNING );#endif}StkFloat FMVoices :: computeSample(){  register StkFloat temp, temp2;  temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();  temp2 = vibrato_.tick() * modDepth_ * 0.1;  waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[0]);  waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[1]);  waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[2]);  waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[3]);  waves_[0]->addPhaseOffset(temp * mods_[0]);  waves_[1]->addPhaseOffset(temp * mods_[1]);  waves_[2]->addPhaseOffset(temp * mods_[2]);  waves_[3]->addPhaseOffset( twozero_.lastOut() );  twozero_.tick( temp );  temp =  gains_[0] * tilt_[0] * adsr_[0]->tick() * waves_[0]->tick();  temp += gains_[1] * tilt_[1] * adsr_[1]->tick() * waves_[1]->tick();  temp += gains_[2] * tilt_[2] * adsr_[2]->tick() * waves_[2]->tick();  lastOutput_ = temp * 0.33;  return lastOutput_;}void FMVoices :: controlChange(int number, StkFloat value){  StkFloat norm = value * ONE_OVER_128;  if ( norm < 0 ) {    norm = 0.0;#if !defined(SYMBIAN)    errorString_ << "FMVoices::controlChange: control value less than zero ... setting to zero!";    handleError( StkError::WARNING );#endif  }  else if ( norm > 1.0 ) {    norm = 1.0;#if !defined(SYMBIAN)    errorString_ << "FMVoices::controlChange: control value greater than 128.0 ... setting to 128.0!";    handleError( StkError::WARNING );#endif  }  if (number == __SK_Breath_) // 2    gains_[3] = fmGains_[(int) ( norm * 99.9 )];  else if (number == __SK_FootControl_)	{ // 4    currentVowel_ = (int) (norm * 128.0);    this->setFrequency(baseFrequency_);  }  else if (number == __SK_ModFrequency_) // 11    this->setModulationSpeed( norm * 12.0);  else if (number == __SK_ModWheel_) // 1    this->setModulationDepth( norm );  else if (number == __SK_AfterTouch_Cont_)	{ // 128    tilt_[0] = norm;    tilt_[1] = norm * norm;    tilt_[2] = tilt_[1] * norm;  }  else {#if !defined(SYMBIAN)    errorString_ << "FMVoices::controlChange: undefined control number (" << number << ")!";    handleError( StkError::WARNING );#endif  }#if defined(_STK_DEBUG_)    errorString_ << "FMVoices::controlChange: number = " << number << ", value = " << value << '.';    handleError( StkError::DEBUG_WARNING );#endif}//#endif // SYMBIAN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -