process method

bool process()

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;
}