예제 #1
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex, bool isMuted)
        {
            //--Base pitch calculation
            var basePitchFrequency = SynthHelper.CentsToPitch(voiceparams.SynthParams.CurrentPitch) * gen.Frequency;
            var pitchWithBend      = basePitchFrequency * SynthHelper.CentsToPitch(voiceparams.PitchOffset);
            var basePitch          = pitchWithBend / voiceparams.SynthParams.Synth.SampleRate;

            float baseVolume = isMuted ? 0 : voiceparams.SynthParams.Synth.MasterVolume * voiceparams.SynthParams.CurrentVolume * SynthConstants.DefaultMixGain * voiceparams.SynthParams.MixVolume;

            //--Main Loop
            for (int x = startIndex; x < endIndex; x += SynthConstants.DefaultBlockSize * SynthConstants.AudioChannels)
            {
                voiceparams.Envelopes[0].Increment(SynthConstants.DefaultBlockSize);
                voiceparams.Envelopes[1].Increment(SynthConstants.DefaultBlockSize);
                voiceparams.Lfos[0].Increment(SynthConstants.DefaultBlockSize);
                voiceparams.Lfos[1].Increment(SynthConstants.DefaultBlockSize);
                //--Calculate pitch and get next block of samples
                gen.GetValues(voiceparams.GeneratorParams[0], voiceparams.BlockBuffer, basePitch *
                              SynthHelper.CentsToPitch((int)(voiceparams.Envelopes[0].Value * modEnvToPitch +
                                                             voiceparams.Lfos[0].Value * modLfoToPitch + voiceparams.Lfos[1].Value * vibLfoToPitch)));
                //--Filter
                if (voiceparams.Filters[0].Enabled)
                {
                    double centsFc = voiceparams.PData[0].Int1 + voiceparams.Lfos[0].Value * modLfoToFilterFc + voiceparams.Envelopes[0].Value * modEnvToFilterFc;
                    if (centsFc > 13500)
                    {
                        centsFc = 13500;
                    }
                    voiceparams.Filters[0].CutOff = SynthHelper.KeyToFrequency(centsFc / 100.0, 69);
                    if (voiceparams.Filters[0].CoeffNeedsUpdating)
                    {
                        voiceparams.Filters[0].ApplyFilterInterp(voiceparams.BlockBuffer, voiceparams.SynthParams.Synth.SampleRate);
                    }
                    else
                    {
                        voiceparams.Filters[0].ApplyFilter(voiceparams.BlockBuffer);
                    }
                }
                //--Volume calculation
                float volume = (float)SynthHelper.DBtoLinear(voiceparams.VolOffset + voiceparams.Envelopes[1].Value + voiceparams.Lfos[0].Value * modLfoToVolume) * baseVolume;

                //--Mix block based on number of channels
                if (SynthConstants.AudioChannels == 2)
                {
                    voiceparams.MixMonoToStereoInterp(x, volume * pan.Left * voiceparams.SynthParams.CurrentPan.Left, volume * pan.Right * voiceparams.SynthParams.CurrentPan.Right);
                }
                else
                {
                    voiceparams.MixMonoToMonoInterp(x, volume);
                }
                //--Check and end early if necessary
                if ((voiceparams.Envelopes[1].CurrentStage > EnvelopeState.Hold && volume <= SynthConstants.NonAudible) || voiceparams.GeneratorParams[0].CurrentState == GeneratorState.Finished)
                {
                    voiceparams.State = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }
예제 #2
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex)
        {
            //--Base pitch calculation
            double basePitch = SynthHelper.CentsToPitch(voiceparams.pitchOffset + voiceparams.synth.totalPitch[voiceparams.channel])
                               * voiceparams.generators[0].Frequency / voiceparams.synth.SampleRate;

            //--Base volume calculation
            //float baseVolume = voiceparams.volOffset * voiceparams.synth.totalVolume[voiceparams.channel];
            //--Main Loop
            for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synth.AudioChannels)
            {
                voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize);
                voiceparams.envelopes[1].Increment(Synthesizer.DefaultBlockSize);
                voiceparams.lfos[0].Increment(Synthesizer.DefaultBlockSize);
                voiceparams.lfos[1].Increment(Synthesizer.DefaultBlockSize);

                //--Calculate pitch and get next block of samples
                voiceparams.generators[0].GetValues(voiceparams.generatorParams[0], voiceparams.blockBuffer, basePitch *
                                                    SynthHelper.CentsToPitch((int)(voiceparams.envelopes[0].Value * modEnvToPitch +
                                                                                   voiceparams.lfos[0].Value * modLfoToPitch + voiceparams.lfos[1].Value * vibLfoToPitch)));
                //--Filter
                if (voiceparams.filters[0].Enabled)
                {
                    double centsFc = iniFilterFc + voiceparams.lfos[0].Value * modLfoToFilterFc + voiceparams.envelopes[0].Value * modEnvToFilterFc;
                    if (centsFc > 13500)
                    {
                        centsFc = 13500;
                    }
                    voiceparams.filters[0].UpdateCoefficients(SynthHelper.KeyToFrequency(centsFc / 100.0, 69) / voiceparams.synth.SampleRate, filterQ);
                    voiceparams.filters[0].ApplyFilter(voiceparams.blockBuffer);
                }
                //--Volume calculation
                float volume = (float)SynthHelper.DBtoLinear(voiceparams.volOffset + voiceparams.lfos[0].Value * modLfoToVolume) * voiceparams.envelopes[1].Value * voiceparams.synth.totalVolume[voiceparams.channel] * voiceparams.synth.MixGain;
                //--Mix block based on number of channels
                if (voiceparams.synth.AudioChannels == 2)
                {
                    SynthHelper.MixMonoToStereoInterpolation(x,
                                                             volume * pan.Left * voiceparams.synth.panPositions[voiceparams.channel].Left,
                                                             volume * pan.Right * voiceparams.synth.panPositions[voiceparams.channel].Right,
                                                             voiceparams);
                }
                else
                {
                    SynthHelper.MixMonoToMonoInterpolation(x, volume, voiceparams);
                }
                //--Check and end early if necessary
                if ((voiceparams.envelopes[1].CurrentState > EnvelopeStateEnum.Hold && volume <= Synthesizer.NonAudible) || voiceparams.generatorParams[0].currentState == GeneratorStateEnum.Finished)
                {
                    voiceparams.state = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }
예제 #3
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex)
        {
            //--Base pitch calculation
            double basePitch = SynthHelper.CentsToPitch(voiceparams.pitchOffset + voiceparams.synthParams.currentPitch)
                               * gen.Period * gen.Frequency / voiceparams.synthParams.synth.SampleRate;
            //--Base volume calculation
            float baseVolume = voiceparams.volOffset * voiceparams.synthParams.currentVolume;

            //--Main Loop
            for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synthParams.synth.AudioChannels)
            {
                //--Volume Envelope
                voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize);
                //--Lfo pitch modulation
                double pitchMod;
                if (voiceparams.synthParams.modRange.Combined != 0)
                {
                    voiceparams.lfos[0].Increment(Synthesizer.DefaultBlockSize);
                    pitchMod = SynthHelper.CentsToPitch((int)(voiceparams.lfos[0].Value * voiceparams.synthParams.currentMod));
                }
                else
                {
                    pitchMod = 1;
                }
                //--Get next block of samples
                gen.GetValues(voiceparams.generatorParams[0], voiceparams.blockBuffer, basePitch * pitchMod);
                //--Mix block based on number of channels
                float volume = baseVolume * voiceparams.envelopes[0].Value;
                if (voiceparams.synthParams.synth.AudioChannels == 2)
                {
                    voiceparams.MixMonoToStereoInterp(x,
                                                      volume * voiceparams.synthParams.currentPan.Left,
                                                      volume * voiceparams.synthParams.currentPan.Right);
                }
                else
                {
                    voiceparams.MixMonoToMonoInterp(x, volume);
                }
                //--Check and end early if necessary
                if (voiceparams.envelopes[0].CurrentState == EnvelopeStateEnum.None || voiceparams.generatorParams[0].currentState == GeneratorStateEnum.Finished)
                {
                    voiceparams.state = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }
예제 #4
0
 public void QuickSetup(int sampleRate, int note, float velocity, FilterDescriptor filterInfo)
 {
     coeffUpdateRequired = false;
     cutOff     = filterInfo.CutOff;
     resonance  = filterInfo.Resonance;
     filterType = filterInfo.FilterMethod;
     a1         = 0; a2 = 0; b1 = 0; b2 = 0;
     m1         = 0f; m2 = 0f; m3 = 0f;
     if (cutOff <= 0 || resonance <= 0)
     {
         filterType = FilterTypeEnum.None;
     }
     if (filterType != FilterTypeEnum.None)
     {
         cutOff *= SynthHelper.CentsToPitch((note - filterInfo.RootKey) * filterInfo.KeyTrack + (int)(velocity * filterInfo.VelTrack));
         UpdateCoeff(sampleRate);
     }
 }
예제 #5
0
 public void QuickSetup(int sampleRate, int note, float velocity, FilterDescriptor filterInfo)
 {
     cutOff     = filterInfo.CutOff;
     resonance  = filterInfo.Resonance;
     filterType = filterInfo.FilterMethod;
     lastFc     = -1000;
     m1         = 0f;
     m2         = 0f;
     m3         = 0f;
     if (filterType == FilterTypeEnum.None || cutOff <= 0.0 || resonance <= 0.0)
     {
         filterType = FilterTypeEnum.None;
     }
     else
     {
         double fc = cutOff * SynthHelper.CentsToPitch((note - filterInfo.RootKey) * filterInfo.KeyTrack + (int)(velocity * filterInfo.VelTrack));
         UpdateCoefficients(SynthHelper.Clamp(fc / sampleRate, 0, .5), resonance);
     }
 }
예제 #6
0
 public void QuickSetup(int sampleRate, int note, float velocity, FilterDescriptor filterInfo)
 {
     CoeffNeedsUpdating = false;
     CutOff             = filterInfo.CutOff;
     Resonance          = filterInfo.Resonance;
     FilterMethod       = filterInfo.FilterMethod;
     _a1 = 0;
     _a2 = 0;
     _b1 = 0;
     _b2 = 0;
     _m1 = 0;
     _m2 = 0;
     _m3 = 0;
     if (CutOff <= 0 || Resonance <= 0)
     {
         FilterMethod = FilterType.None;
     }
     if (FilterMethod != FilterType.None)
     {
         CutOff *= SynthHelper.CentsToPitch((note - filterInfo.RootKey) * filterInfo.KeyTrack + (int)(velocity * filterInfo.VelTrack));
         UpdateCoefficients(sampleRate);
     }
 }
예제 #7
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex)
        {
            //--Base pitch calculation
            double carrierPitch = SynthHelper.CentsToPitch((voiceparams.note - voiceparams.generators[0].RootKey) * voiceparams.generators[0].KeyTrack + voiceparams.generators[0].Tune + voiceparams.synth.totalPitch[voiceparams.channel])
                                  * voiceparams.generators[0].Period * voiceparams.generators[0].Frequency * cIndex / voiceparams.synth.SampleRate;
            double modulatorPitch = SynthHelper.CentsToPitch((voiceparams.note - voiceparams.generators[1].RootKey) * voiceparams.generators[1].KeyTrack + voiceparams.generators[1].Tune + voiceparams.synth.totalPitch[voiceparams.channel])
                                    * voiceparams.generators[1].Period * voiceparams.generators[1].Frequency * mIndex / voiceparams.synth.SampleRate;
            //--Base volume calculation
            float baseVolume = voiceparams.volOffset * voiceparams.synth.totalVolume[voiceparams.channel];

            //--Main Loop
            for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synth.AudioChannels)
            {
                //--Calculate pitch modifications
                double pitchMod;
                if (voiceparams.synth.modWheel[voiceparams.channel] != 0.0)
                {
                    voiceparams.lfos[0].Increment(Synthesizer.DefaultBlockSize);
                    pitchMod = SynthHelper.CentsToPitch((int)(voiceparams.lfos[0].Value * voiceparams.synth.modWheel[voiceparams.channel]));
                }
                else
                {
                    pitchMod = 1;
                }
                //--Get amplitude values for carrier and modulator
                voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize);
                voiceparams.envelopes[1].Increment(Synthesizer.DefaultBlockSize);
                float c_amp = baseVolume * voiceparams.envelopes[0].Value;
                float m_amp = voiceparams.envelopes[1].Value;
                //--Interpolator for modulator amplitude
                float linear_m_amp = (m_amp - voiceparams.mixing[2]) / Synthesizer.DefaultBlockSize;
                //--Process block
                for (int i = 0; i < voiceparams.blockBuffer.Length; i++)
                {
                    //calculate current modulator amplitude
                    voiceparams.mixing[2] += linear_m_amp;
                    //calculate sample
                    voiceparams.blockBuffer[i] = voiceparams.generators[0].GetValue(voiceparams.counters[0] + voiceparams.mixing[2] * voiceparams.generators[1].GetValue(voiceparams.counters[1] + voiceparams.counters[2] * feedBack));
                    //store sample for feedback calculation
                    voiceparams.counters[2] = voiceparams.blockBuffer[i];
                    //increment phase counters
                    voiceparams.counters[0] += carrierPitch * pitchMod;
                    voiceparams.counters[1] += modulatorPitch * pitchMod;
                }
                voiceparams.mixing[2] = m_amp;
                //--Mix block based on number of channels
                if (voiceparams.synth.AudioChannels == 2)
                {
                    SynthHelper.MixMonoToStereoInterpolation(x,
                                                             c_amp * voiceparams.synth.panPositions[voiceparams.channel].Left,
                                                             c_amp * voiceparams.synth.panPositions[voiceparams.channel].Right,
                                                             voiceparams);
                }
                else
                {
                    SynthHelper.MixMonoToMonoInterpolation(x, c_amp, voiceparams);
                }
                //--Bounds check
                if (sync == SyncMode.Soft)
                {
                    if (voiceparams.counters[0] >= voiceparams.generators[0].LoopEndPhase)
                    {
                        voiceparams.counters[0] = voiceparams.generators[0].LoopStartPhase + (voiceparams.counters[0] - voiceparams.generators[0].LoopEndPhase) % (voiceparams.generators[0].LoopEndPhase - voiceparams.generators[0].LoopStartPhase);
                    }
                    if (voiceparams.counters[1] >= voiceparams.generators[1].LoopEndPhase)
                    {
                        voiceparams.counters[1] = voiceparams.generators[1].LoopStartPhase + (voiceparams.counters[1] - voiceparams.generators[1].LoopEndPhase) % (voiceparams.generators[1].LoopEndPhase - voiceparams.generators[1].LoopStartPhase);
                    }
                }
                else
                {
                    if (voiceparams.counters[0] >= voiceparams.generators[0].LoopEndPhase)
                    {
                        voiceparams.counters[0] = voiceparams.generators[0].LoopStartPhase;
                        voiceparams.counters[1] = voiceparams.generators[1].LoopStartPhase;
                    }
                }
                //--Check and end early if necessary
                if (voiceparams.envelopes[0].CurrentState == EnvelopeStateEnum.None)
                {
                    voiceparams.state = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }
예제 #8
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex)
        {
            //--Base pitch calculation
            double basePitch = SynthHelper.CentsToPitch(voiceparams.pitchOffset + voiceparams.synth.totalPitch[voiceparams.channel])
                               * voiceparams.generators[0].Frequency / voiceparams.synth.SampleRate;
            //--Base volume calculation
            float baseVolume = voiceparams.volOffset * voiceparams.synth.totalVolume[voiceparams.channel];

            //--Main Loop
            for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synth.AudioChannels)
            {
                //--Envelope Calculations
                if (voiceparams.envelopes[0].Depth != 0)
                {
                    voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize); //pitch envelope
                }
                if (voiceparams.envelopes[1].Depth != 0)
                {
                    voiceparams.envelopes[1].Increment(Synthesizer.DefaultBlockSize); //filter envelope
                }
                voiceparams.envelopes[2].Increment(Synthesizer.DefaultBlockSize);     //amp envelope (do not skip)
                //--LFO Calculations
                if (voiceparams.lfos[0].Depth + voiceparams.synth.modWheel[voiceparams.channel] != 0)
                {
                    voiceparams.lfos[0].Increment(Synthesizer.DefaultBlockSize); //pitch lfo
                }
                if (voiceparams.lfos[1].Depth != 0)
                {
                    voiceparams.lfos[1].Increment(Synthesizer.DefaultBlockSize); //filter lfo
                }
                if (voiceparams.lfos[2].Depth != 1.0)                            //linear scale 1.0 = 0dB
                {
                    voiceparams.lfos[2].Increment(Synthesizer.DefaultBlockSize); //amp lfo
                }
                //--Calculate pitch and get next block of samples
                voiceparams.generators[0].GetValues(voiceparams.generatorParams[0], voiceparams.blockBuffer, basePitch *
                                                    SynthHelper.CentsToPitch((int)(voiceparams.envelopes[0].Value * voiceparams.envelopes[0].Depth +
                                                                                   voiceparams.lfos[0].Value * (voiceparams.lfos[0].Depth + voiceparams.synth.modWheel[voiceparams.channel]))));
                //--Filter if enabled
                //...
                //--Volume calculation
                float volume = baseVolume * voiceparams.envelopes[2].Value * (float)(Math.Pow(voiceparams.lfos[2].Depth, voiceparams.lfos[2].Value));
                //--Mix block based on number of channels
                if (voiceparams.synth.AudioChannels == 2)
                {
                    SynthHelper.MixMonoToStereoInterpolation(x,
                                                             volume * sfzPan.Left * voiceparams.synth.panPositions[voiceparams.channel].Left,
                                                             volume * sfzPan.Right * voiceparams.synth.panPositions[voiceparams.channel].Right,
                                                             voiceparams);
                }
                else
                {
                    SynthHelper.MixMonoToMonoInterpolation(x, volume, voiceparams);
                }
                //--Check and end early if necessary
                if (voiceparams.envelopes[2].CurrentState == EnvelopeStateEnum.None || voiceparams.generatorParams[0].currentState == GeneratorStateEnum.Finished)
                {
                    voiceparams.state = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }
예제 #9
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex)
        {
            //--Base pitch calculation
            double basePitch = SynthHelper.CentsToPitch(voiceparams.pitchOffset + voiceparams.synthParams.currentPitch)
                               * gen.Frequency / voiceparams.synthParams.synth.SampleRate;
            //--Base volume calculation
            float baseVolume = voiceparams.volOffset * voiceparams.synthParams.currentVolume;

            //--Main Loop
            for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synthParams.synth.AudioChannels)
            {
                //--Envelope Calculations
                if (voiceparams.envelopes[0].Depth != 0)
                {
                    voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize); //pitch envelope
                }
                if (voiceparams.envelopes[1].Depth != 0)
                {
                    voiceparams.envelopes[1].Increment(Synthesizer.DefaultBlockSize); //filter envelope
                }
                voiceparams.envelopes[2].Increment(Synthesizer.DefaultBlockSize);     //amp envelope (do not skip)
                //--LFO Calculations
                if (voiceparams.lfos[0].Depth + voiceparams.synthParams.currentMod != 0)
                {
                    voiceparams.lfos[0].Increment(Synthesizer.DefaultBlockSize); //pitch lfo
                }
                if (voiceparams.lfos[1].Depth != 0)
                {
                    voiceparams.lfos[1].Increment(Synthesizer.DefaultBlockSize); //filter lfo
                }
                if (voiceparams.lfos[2].Depth != 1.0)                            //linear scale 1.0 = 0dB
                {
                    voiceparams.lfos[2].Increment(Synthesizer.DefaultBlockSize); //amp lfo
                }
                //--Calculate pitch and get next block of samples
                gen.GetValues(voiceparams.generatorParams[0], voiceparams.blockBuffer, basePitch *
                              SynthHelper.CentsToPitch((int)(voiceparams.envelopes[0].Value * voiceparams.envelopes[0].Depth +
                                                             voiceparams.lfos[0].Value * (voiceparams.lfos[0].Depth + voiceparams.synthParams.currentMod))));
                //--Filter if enabled
                if (voiceparams.filters[0].Enabled)
                {
                    int cents = (int)(voiceparams.envelopes[1].Value * voiceparams.envelopes[1].Depth) + (int)(voiceparams.lfos[1].Value * voiceparams.lfos[1].Depth);
                    voiceparams.filters[0].Cutoff = voiceparams.pData[0].double1 * SynthHelper.CentsToPitch(cents);
                    if (voiceparams.filters[0].CoeffNeedsUpdating)
                    {
                        voiceparams.filters[0].ApplyFilterInterp(voiceparams.blockBuffer, voiceparams.synthParams.synth.SampleRate);
                    }
                    else
                    {
                        voiceparams.filters[0].ApplyFilter(voiceparams.blockBuffer);
                    }
                }
                //--Volume calculation
                float volume = baseVolume * voiceparams.envelopes[2].Value * (float)(Math.Pow(voiceparams.lfos[2].Depth, voiceparams.lfos[2].Value));
                //--Mix block based on number of channels
                if (voiceparams.synthParams.synth.AudioChannels == 2)
                {
                    voiceparams.MixMonoToStereoInterp(x,
                                                      volume * sfzPan.Left * voiceparams.synthParams.currentPan.Left,
                                                      volume * sfzPan.Right * voiceparams.synthParams.currentPan.Right);
                }
                else
                {
                    voiceparams.MixMonoToMonoInterp(x, volume);
                }
                //--Check and end early if necessary
                if (voiceparams.envelopes[2].CurrentState == EnvelopeStateEnum.None || voiceparams.generatorParams[0].currentState == GeneratorStateEnum.Finished)
                {
                    voiceparams.state = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }
예제 #10
0
        public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex)
        {
            //--Base pitch calculation
            double carrierPitch = SynthHelper.CentsToPitch((voiceparams.note - cGen.RootKey) * cGen.KeyTrack + cGen.Tune + voiceparams.pitchOffset + voiceparams.synthParams.currentPitch)
                                  * cGen.Period * cGen.Frequency * cIndex / voiceparams.synthParams.synth.SampleRate;
            double modulatorPitch = SynthHelper.CentsToPitch((voiceparams.note - mGen.RootKey) * mGen.KeyTrack + mGen.Tune + voiceparams.pitchOffset + voiceparams.synthParams.currentPitch)
                                    * mGen.Period * mGen.Frequency * mIndex / voiceparams.synthParams.synth.SampleRate;
            //--Base volume calculation
            float baseVolume = voiceparams.volOffset * voiceparams.synthParams.currentVolume;

            //--Main Loop
            for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synthParams.synth.AudioChannels)
            {
                //--Calculate pitch modifications
                double pitchMod;
                if (voiceparams.synthParams.modRange.Combined != 0)
                {
                    voiceparams.lfos[0].Increment(Synthesizer.DefaultBlockSize);
                    pitchMod = SynthHelper.CentsToPitch((int)(voiceparams.lfos[0].Value * voiceparams.synthParams.currentMod));
                }
                else
                {
                    pitchMod = 1;
                }
                //--Get amplitude values for carrier and modulator
                voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize);
                voiceparams.envelopes[1].Increment(Synthesizer.DefaultBlockSize);
                float c_amp = baseVolume * voiceparams.envelopes[0].Value;
                float m_amp = voiceparams.envelopes[1].Value;
                //--Interpolator for modulator amplitude
                float linear_m_amp = (m_amp - voiceparams.pData[3].float1) / Synthesizer.DefaultBlockSize;
                //--Process block
                for (int i = 0; i < voiceparams.blockBuffer.Length; i++)
                {
                    //calculate current modulator amplitude
                    voiceparams.pData[3].float1 += linear_m_amp;
                    //calculate sample
                    voiceparams.blockBuffer[i] = cGen.GetValue(voiceparams.pData[0].double1 + voiceparams.pData[3].float1 * mGen.GetValue(voiceparams.pData[1].double1 + voiceparams.pData[2].double1 * feedBack));
                    //store sample for feedback calculation
                    voiceparams.pData[2].double1 = voiceparams.blockBuffer[i];
                    //increment phase counters
                    voiceparams.pData[0].double1 += carrierPitch * pitchMod;
                    voiceparams.pData[1].double1 += modulatorPitch * pitchMod;
                }
                voiceparams.pData[3].float1 = m_amp;
                //--Mix block based on number of channels
                if (voiceparams.synthParams.synth.AudioChannels == 2)
                {
                    voiceparams.MixMonoToStereoInterp(x,
                                                      c_amp * voiceparams.synthParams.currentPan.Left,
                                                      c_amp * voiceparams.synthParams.currentPan.Right);
                }
                else
                {
                    voiceparams.MixMonoToMonoInterp(x, c_amp);
                }
                //--Bounds check
                if (sync == SyncMode.Soft)
                {
                    if (voiceparams.pData[0].double1 >= cGen.LoopEndPhase)
                    {
                        voiceparams.pData[0].double1 = cGen.LoopStartPhase + (voiceparams.pData[0].double1 - cGen.LoopEndPhase) % (cGen.LoopEndPhase - cGen.LoopStartPhase);
                    }
                    if (voiceparams.pData[1].double1 >= mGen.LoopEndPhase)
                    {
                        voiceparams.pData[1].double1 = mGen.LoopStartPhase + (voiceparams.pData[1].double1 - mGen.LoopEndPhase) % (mGen.LoopEndPhase - mGen.LoopStartPhase);
                    }
                }
                else
                {
                    if (voiceparams.pData[0].double1 >= cGen.LoopEndPhase)
                    {
                        voiceparams.pData[0].double1 = cGen.LoopStartPhase;
                        voiceparams.pData[1].double1 = mGen.LoopStartPhase;
                    }
                }
                //--Check and end early if necessary
                if (voiceparams.envelopes[0].CurrentState == EnvelopeStateEnum.None)
                {
                    voiceparams.state = VoiceStateEnum.Stopped;
                    return;
                }
            }
        }