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.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.synth.totalPitch[voiceparams.channel]) * voiceparams.generators[0].Period * voiceparams.generators[0].Frequency / voiceparams.synth.SampleRate; //--Main Loop for (int x = startIndex; x < endIndex; x += Synthesizer.DefaultBlockSize * voiceparams.synth.AudioChannels) { //--Volume Envelope voiceparams.envelopes[0].Increment(Synthesizer.DefaultBlockSize); //--Lfo pitch modulation 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 next block of samples voiceparams.generators[0].GetValues(voiceparams.generatorParams[0], voiceparams.blockBuffer, basePitch * pitchMod); //--Mix block based on number of channels float volume = voiceparams.volOffset * voiceparams.synth.totalVolume[voiceparams.channel] * voiceparams.envelopes[0].Value; if (voiceparams.synth.AudioChannels == 2) { SynthHelper.MixMonoToStereoInterpolation(x, volume * voiceparams.synth.panPositions[voiceparams.channel].Left, volume * voiceparams.synth.panPositions[voiceparams.channel].Right, voiceparams); } else { SynthHelper.MixMonoToMonoInterpolation(x, volume, voiceparams); } //--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 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; } } }
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; } } }