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