Beispiel #1
0
        public void Start(RegionPair region, int channel, int key, int velocity)
        {
            this.exclusiveClass = region.ExclusiveClass;
            this.channel        = channel;
            this.key            = key;
            this.velocity       = velocity;

            if (velocity > 0)
            {
                // According to the Polyphone's implementation, the initial attenuation should be reduced to 40%.
                // I'm not sure why, but this indeed improves the loudness variability.
                var sampleAttenuation = 0.4F * region.InitialAttenuation;
                var filterAttenuation = 0.5F * region.InitialFilterQ;
                var decibels          = 2 * SoundFontMath.LinearToDecibels(velocity / 127F) - sampleAttenuation - filterAttenuation;
                noteGain = SoundFontMath.DecibelsToLinear(decibels);
            }
            else
            {
                noteGain = 0F;
            }

            cutoff    = region.InitialFilterCutoffFrequency;
            resonance = SoundFontMath.DecibelsToLinear(region.InitialFilterQ);

            vibLfoToPitch = 0.01F * region.VibratoLfoToPitch;
            modLfoToPitch = 0.01F * region.ModulationLfoToPitch;
            modEnvToPitch = 0.01F * region.ModulationEnvelopeToPitch;

            modLfoToCutoff = region.ModulationLfoToFilterCutoffFrequency;
            modEnvToCutoff = region.ModulationEnvelopeToFilterCutoffFrequency;
            dynamicCutoff  = modLfoToCutoff != 0 || modEnvToCutoff != 0;

            modLfoToVolume = region.ModulationLfoToVolume;
            dynamicVolume  = modLfoToVolume > 0.05F;

            instrumentPan    = SoundFontMath.Clamp(region.Pan, -50F, 50F);
            instrumentReverb = 0.01F * region.ReverbEffectsSend;
            instrumentChorus = 0.01F * region.ChorusEffectsSend;

            volEnv.Start(region, key, velocity);
            modEnv.Start(region, key, velocity);
            vibLfo.StartVibrato(region, key, velocity);
            modLfo.StartModulation(region, key, velocity);
            oscillator.Start(synthesizer.SoundFont.WaveDataArray, region);
            filter.ClearBuffer();
            filter.SetLowPassFilter(cutoff, resonance);

            smoothedCutoff = cutoff;

            voiceState  = VoiceState.Playing;
            voiceLength = 0;
        }
        public static void Start(this ModulationEnvelope envelope, RegionPair region, int key, int velocity)
        {
            // According to the implementation of TinySoundFont, the attack time should be adjusted by the velocity.

            var delay   = region.DelayModulationEnvelope;
            var attack  = region.AttackModulationEnvelope * ((145 - velocity) / 144F);
            var hold    = region.HoldModulationEnvelope * SoundFontMath.KeyNumberToMultiplyingFactor(region.KeyNumberToModulationEnvelopeHold, key);
            var decay   = region.DecayModulationEnvelope * SoundFontMath.KeyNumberToMultiplyingFactor(region.KeyNumberToModulationEnvelopeDecay, key);
            var sustain = 1F - region.SustainModulationEnvelope / 100F;
            var release = region.ReleaseModulationEnvelope;

            envelope.Start(delay, attack, hold, decay, sustain, release);
        }