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