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; } } }
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; } } }
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; float baseVolume = voiceparams.synthParams.currentVolume * voiceparams.synthParams.synth.MixGain; //--Main Loop for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synthParams.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 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 (voiceparams.synthParams.synth.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].CurrentState > EnvelopeStateEnum.Hold && volume <= Synthesizer.NonAudible) || voiceparams.generatorParams[0].currentState == GeneratorStateEnum.Finished) { voiceparams.state = VoiceStateEnum.Stopped; return; } } }
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; } } }