mirror of
https://github.com/thestk/stk
synced 2026-01-16 06:21:51 +00:00
Version 4.2.0
This commit is contained in:
committed by
Stephen Sinclair
parent
cf06b7598b
commit
a6381b9d38
179
src/FMVoices.cpp
179
src/FMVoices.cpp
@@ -26,7 +26,7 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -38,146 +38,163 @@ FMVoices :: FMVoices()
|
||||
: FM()
|
||||
{
|
||||
// Concatenate the STK rawwave path to the rawwave files
|
||||
for ( int i=0; i<3; i++ )
|
||||
waves[i] = new WaveLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), TRUE );
|
||||
waves[3] = new WaveLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), TRUE );
|
||||
for ( unsigned int i=0; i<3; i++ )
|
||||
waves_[i] = new WaveLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
|
||||
waves_[3] = new WaveLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
|
||||
|
||||
this->setRatio(0, 2.00);
|
||||
this->setRatio(1, 4.00);
|
||||
this->setRatio(2, 12.0);
|
||||
this->setRatio(3, 1.00);
|
||||
|
||||
gains[3] = __FM_gains[80];
|
||||
gains_[3] = fmGains_[80];
|
||||
|
||||
adsr[0]->setAllTimes( 0.05, 0.05, __FM_susLevels[15], 0.05);
|
||||
adsr[1]->setAllTimes( 0.05, 0.05, __FM_susLevels[15], 0.05);
|
||||
adsr[2]->setAllTimes( 0.05, 0.05, __FM_susLevels[15], 0.05);
|
||||
adsr[3]->setAllTimes( 0.01, 0.01, __FM_susLevels[15], 0.5);
|
||||
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 = (MY_FLOAT) 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;
|
||||
setFrequency( 110.0 );
|
||||
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(MY_FLOAT frequency)
|
||||
void FMVoices :: setFrequency(StkFloat frequency)
|
||||
{
|
||||
MY_FLOAT temp, temp2 = 0.0;
|
||||
StkFloat temp, temp2 = 0.0;
|
||||
int tempi = 0;
|
||||
unsigned int i = 0;
|
||||
|
||||
if (currentVowel < 32) {
|
||||
i = currentVowel;
|
||||
temp2 = (MY_FLOAT) 0.9;
|
||||
if (currentVowel_ < 32) {
|
||||
i = currentVowel_;
|
||||
temp2 = 0.9;
|
||||
}
|
||||
else if (currentVowel < 64) {
|
||||
i = currentVowel - 32;
|
||||
temp2 = (MY_FLOAT) 1.0;
|
||||
else if (currentVowel_ < 64) {
|
||||
i = currentVowel_ - 32;
|
||||
temp2 = 1.0;
|
||||
}
|
||||
else if (currentVowel < 96) {
|
||||
i = currentVowel - 64;
|
||||
temp2 = (MY_FLOAT) 1.1;
|
||||
else if (currentVowel_ < 96) {
|
||||
i = currentVowel_ - 64;
|
||||
temp2 = 1.1;
|
||||
}
|
||||
else if (currentVowel <= 128) {
|
||||
i = currentVowel - 96;
|
||||
temp2 = (MY_FLOAT) 1.2;
|
||||
else if (currentVowel_ <= 128) {
|
||||
i = currentVowel_ - 96;
|
||||
temp2 = 1.2;
|
||||
}
|
||||
|
||||
baseFrequency = frequency;
|
||||
temp = (temp2 * Phonemes::formantFrequency(i, 0) / baseFrequency) + 0.5;
|
||||
baseFrequency_ = frequency;
|
||||
temp = (temp2 * Phonemes::formantFrequency(i, 0) / baseFrequency_) + 0.5;
|
||||
tempi = (int) temp;
|
||||
this->setRatio(0,(MY_FLOAT) tempi);
|
||||
temp = (temp2 * Phonemes::formantFrequency(i, 1) / baseFrequency) + 0.5;
|
||||
this->setRatio( 0, (StkFloat) tempi );
|
||||
temp = (temp2 * Phonemes::formantFrequency(i, 1) / baseFrequency_) + 0.5;
|
||||
tempi = (int) temp;
|
||||
this->setRatio(1,(MY_FLOAT) tempi);
|
||||
temp = (temp2 * Phonemes::formantFrequency(i, 2) / baseFrequency) + 0.5;
|
||||
this->setRatio( 1, (StkFloat) tempi );
|
||||
temp = (temp2 * Phonemes::formantFrequency(i, 2) / baseFrequency_) + 0.5;
|
||||
tempi = (int) temp;
|
||||
this->setRatio(2, (MY_FLOAT) tempi);
|
||||
gains[0] = 1.0;
|
||||
gains[1] = 1.0;
|
||||
gains[2] = 1.0;
|
||||
this->setRatio( 2, (StkFloat) tempi );
|
||||
gains_[0] = 1.0;
|
||||
gains_[1] = 1.0;
|
||||
gains_[2] = 1.0;
|
||||
}
|
||||
|
||||
void FMVoices :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude)
|
||||
void FMVoices :: noteOn(StkFloat frequency, StkFloat amplitude)
|
||||
{
|
||||
this->setFrequency(frequency);
|
||||
tilt[0] = amplitude;
|
||||
tilt[1] = amplitude * amplitude;
|
||||
tilt[2] = tilt[1] * amplitude;
|
||||
this->setFrequency( frequency );
|
||||
tilt_[0] = amplitude;
|
||||
tilt_[1] = amplitude * amplitude;
|
||||
tilt_[2] = tilt_[1] * amplitude;
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "FMVoices: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << std::endl;
|
||||
errorString_ << "FMVoices::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
MY_FLOAT FMVoices :: tick()
|
||||
StkFloat FMVoices :: tick()
|
||||
{
|
||||
register MY_FLOAT temp, temp2;
|
||||
register StkFloat temp, temp2;
|
||||
|
||||
temp = gains[3] * adsr[3]->tick() * waves[3]->tick();
|
||||
temp2 = vibrato->tick() * modDepth * (MY_FLOAT) 0.1;
|
||||
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]->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();
|
||||
|
||||
return temp * 0.33;
|
||||
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, MY_FLOAT value)
|
||||
StkFloat *FMVoices :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
MY_FLOAT norm = value * ONE_OVER_128;
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& FMVoices :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
void FMVoices :: controlChange(int number, StkFloat value)
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
std::cerr << "FMVoices: Control value less than zero!" << std::endl;
|
||||
errorString_ << "FMVoices::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
std::cerr << "FMVoices: Control value greater than 128.0!" << std::endl;
|
||||
errorString_ << "FMVoices::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
|
||||
if (number == __SK_Breath_) // 2
|
||||
gains[3] = __FM_gains[(int) ( norm * 99.9 )];
|
||||
gains_[3] = fmGains_[(int) ( norm * 99.9 )];
|
||||
else if (number == __SK_FootControl_) { // 4
|
||||
currentVowel = (int) (norm * 128.0);
|
||||
this->setFrequency(baseFrequency);
|
||||
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;
|
||||
tilt_[0] = norm;
|
||||
tilt_[1] = norm * norm;
|
||||
tilt_[2] = tilt_[1] * norm;
|
||||
}
|
||||
else {
|
||||
errorString_ << "FMVoices::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else
|
||||
std::cerr << "FMVoices: Undefined Control Number (" << number << ")!!" << std::endl;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "FMVoices: controlChange number = " << number << ", value = " << value << std::endl;
|
||||
errorString_ << "FMVoices::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user