process method
Implementation
bool process()
{
if (_noteGain < SoundFontMath.nonAudible)
{
return false;
}
Channel channelInfo = synthesizer.channels[_channel];
_releaseIfNecessary(channelInfo);
if (!_volEnv.process())
{
return false;
}
_modEnv.process();
_vibLfo.process();
_modLfo.process();
var vibPitchChange = (0.01 * channelInfo.modulation + _vibLfoToPitch) * _vibLfo.value();
var modPitchChange = _modLfoToPitch * _modLfo.value() + _modEnvToPitch * _modEnv.value();
var channelPitchChange = channelInfo.tune + channelInfo.pitchBend;
var pitch = _key + vibPitchChange + modPitchChange + channelPitchChange;
if (!_oscillator.process(_block, pitch))
{
return false;
}
if (_dynamicCutoff)
{
var cents = _modLfoToCutoff * _modLfo.value() + _modEnvToCutoff * _modEnv.value();
var factor = SoundFontMath.centsToMultiplyingFactor(cents);
var newCutoff = factor * _cutoff;
// The cutoff change is limited within x0.5 and x2 to reduce pop noise.
var lowerLimit = 0.5 * _smoothedCutoff;
var upperLimit = 2.0 * _smoothedCutoff;
if (newCutoff < lowerLimit)
{
_smoothedCutoff = lowerLimit;
}
else if (newCutoff > upperLimit)
{
_smoothedCutoff = upperLimit;
}
else
{
_smoothedCutoff = newCutoff;
}
_filter.setLowPassFilter(_smoothedCutoff, _resonance);
}
_filter.process(_block);
_previousMixGainLeft = _currentMixGainLeft;
_previousMixGainRight = _currentMixGainRight;
_previousReverbSend = _currentReverbSend;
_previousChorusSend = _currentChorusSend;
// According to the GM spec, the following value should be squared.
var ve = channelInfo.volume * channelInfo.expression;
var channelGain = ve * ve;
double mixGain = _noteGain * channelGain * _volEnv.value();
if (_dynamicVolume)
{
var decibels = _modLfoToVolume * _modLfo.value();
mixGain *= SoundFontMath.decibelsToLinear(decibels);
}
double angle = (pi / 200.0) * (channelInfo.pan + _instrumentPan + 50.0);
if (angle <= 0.0)
{
_currentMixGainLeft = mixGain;
_currentMixGainRight = 0.0;
}
else if (angle >= SoundFontMath.halfPi)
{
_currentMixGainLeft = 0.0;
_currentMixGainRight = mixGain;
}
else
{
_currentMixGainLeft = mixGain * cos(angle);
_currentMixGainRight = mixGain * sin(angle);
}
_currentReverbSend = (channelInfo.reverbSend + _instrumentReverb).clamp(0, 1);
_currentChorusSend = (channelInfo.chorusSend + _instrumentChorus).clamp(0, 1);
if (_voiceLength == 0)
{
_previousMixGainLeft = _currentMixGainLeft;
_previousMixGainRight = _currentMixGainRight;
_previousReverbSend = _currentReverbSend;
_previousChorusSend = _currentChorusSend;
}
_voiceLength += synthesizer.blockSize;
return true;
}