public void Load(Sf2Region region, AssetManager assets) { this.exGroup = region.Generators[(int)GeneratorEnum.ExclusiveClass]; this.exTarget = exGroup; iniFilterFc = region.Generators[(int)GeneratorEnum.InitialFilterCutoffFrequency]; filterQ = SynthHelper.DBtoLinear(region.Generators[(int)GeneratorEnum.InitialFilterQ] / 10.0); initialAttn = -region.Generators[(int)GeneratorEnum.InitialAttenuation] / 10f; keyOverride = region.Generators[(int)GeneratorEnum.KeyNumber]; velOverride = region.Generators[(int)GeneratorEnum.Velocity]; keynumToModEnvHold = region.Generators[(int)GeneratorEnum.KeyNumberToModulationEnvelopeHold]; keynumToModEnvDecay = region.Generators[(int)GeneratorEnum.KeyNumberToModulationEnvelopeDecay]; keynumToVolEnvHold = region.Generators[(int)GeneratorEnum.KeyNumberToVolumeEnvelopeHold]; keynumToVolEnvDecay = region.Generators[(int)GeneratorEnum.KeyNumberToVolumeEnvelopeDecay]; pan = new PanComponent(region.Generators[(int)GeneratorEnum.Pan] / 500f, PanFormulaEnum.Neg3dBCenter); modLfoToPitch = region.Generators[(int)GeneratorEnum.ModulationLFOToPitch]; vibLfoToPitch = region.Generators[(int)GeneratorEnum.VibratoLFOToPitch]; modEnvToPitch = region.Generators[(int)GeneratorEnum.ModulationEnvelopeToPitch]; modLfoToFilterFc = region.Generators[(int)GeneratorEnum.ModulationLFOToFilterCutoffFrequency]; modEnvToFilterFc = region.Generators[(int)GeneratorEnum.ModulationEnvelopeToFilterCutoffFrequency]; modLfoToVolume = region.Generators[(int)GeneratorEnum.ModulationLFOToVolume] / 10f; LoadGen(region, assets); LoadEnvelopes(region); LoadLfos(region); LoadFilter(region); }
private void LoadFilter(Sf2Region region) { fltr = new FilterDescriptor(); fltr.FilterMethod = FilterTypeEnum.BiquadLowpass; fltr.CutOff = (float)SynthHelper.KeyToFrequency(region.Generators[(int)GeneratorEnum.InitialFilterCutoffFrequency] / 100.0, 69); fltr.Resonance = (float)SynthHelper.DBtoLinear(region.Generators[(int)GeneratorEnum.InitialFilterQ] / 10.0); }
public override bool Start(VoiceParameters voiceparams) { //calculate velocity float fVel = voiceparams.velocity / 127f; //setup generator voiceparams.generatorParams[0].QuickSetup(voiceparams.generators[0]); //setup envelopes voiceparams.envelopes[0].QuickSetup(voiceparams.synth.SampleRate, fVel, this.EnvelopeInfo[0]); voiceparams.envelopes[1].QuickSetup(voiceparams.synth.SampleRate, fVel, this.EnvelopeInfo[1]); voiceparams.envelopes[2].QuickSetup(voiceparams.synth.SampleRate, fVel, this.EnvelopeInfo[2]); //setup lfos voiceparams.lfos[0].QuickSetup(voiceparams.synth.SampleRate, LfoInfo[0]); voiceparams.lfos[1].QuickSetup(voiceparams.synth.SampleRate, LfoInfo[1]); voiceparams.lfos[2].QuickSetup(voiceparams.synth.SampleRate, LfoInfo[2]); //setup filter voiceparams.filters[0].QuickSetup(voiceparams.synth.SampleRate, voiceparams.note, fVel, this.FilterInfo[0]); if (!voiceparams.filters[0].Enabled) {//disable filter components if necessary voiceparams.envelopes[1].Depth = 0f; voiceparams.lfos[1].Depth = 0f; } //setup sfz params voiceparams.pitchOffset = (voiceparams.note - voiceparams.generators[0].RootKey) * voiceparams.generators[0].KeyTrack + (int)(fVel * voiceparams.generators[0].VelocityTrack) + voiceparams.generators[0].Tune; float dBVel = -20.0f * (float)Math.Log10(16129.0 / (voiceparams.velocity * voiceparams.velocity)); voiceparams.volOffset = (float)SynthHelper.DBtoLinear((voiceparams.note - ampRootKey) * ampKeyTrack + dBVel * ampVelTrack + sfzVolume) * voiceparams.synth.MixGain; //check if we have finished before we have begun return(voiceparams.generatorParams[0].currentState != GeneratorStateEnum.Finished && voiceparams.envelopes[2].CurrentState != EnvelopeStateEnum.None); }
public override bool Start(VoiceParameters voiceparams) { int note = keyOverride > -1 ? keyOverride : voiceparams.note; int vel = velOverride > -1 ? velOverride : voiceparams.velocity; //setup generator voiceparams.generatorParams[0].QuickSetup(voiceparams.generators[0]); //setup envelopes voiceparams.envelopes[0].QuickSetup(voiceparams.synth.SampleRate, note, keynumToModEnvHold, keynumToModEnvDecay, 1, this.EnvelopeInfo[0]); float susMod = (float)SynthHelper.DBtoLinear(-sustainVolEnv); if (susMod <= 1e-5f) { susMod = 0; } voiceparams.envelopes[1].QuickSetup(voiceparams.synth.SampleRate, note, keynumToVolEnvHold, keynumToVolEnvDecay, susMod, this.EnvelopeInfo[1]); //setup filter //if (filterQ == 1 && modLfoToFilterFc + modEnvToFilterFc + iniFilterFc > 14000) voiceparams.filters[0].Disable(); //else // voiceparams.filters[0].QuickSetup(44100, note, 1f, this.FilterInfo[0]); //setup lfos voiceparams.lfos[0].QuickSetup(voiceparams.synth.SampleRate, LfoInfo[0]); voiceparams.lfos[1].QuickSetup(voiceparams.synth.SampleRate, LfoInfo[1]); //calculate base volume and pitch voiceparams.pitchOffset = (note - voiceparams.generators[0].RootKey) * voiceparams.generators[0].KeyTrack + voiceparams.generators[0].Tune; voiceparams.volOffset = -20.0f * (float)Math.Log10(16129.0 / (vel * vel)) + -initialAttn; //check if we have finished before we have begun return(voiceparams.generatorParams[0].currentState != GeneratorStateEnum.Finished && voiceparams.envelopes[1].CurrentState != EnvelopeStateEnum.None); }
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; } } }
private void LoadSfzFilters(SfzRegion region) { FilterDescriptions = new FilterDescriptor[1]; FilterDescriptions[0] = new FilterDescriptor(); FilterDescriptions[0].FilterMethod = region.filterType; FilterDescriptions[0].CutOff = region.cutOff; FilterDescriptions[0].KeyTrack = region.filterKeyTrack; FilterDescriptions[0].Resonance = (float)SynthHelper.DBtoLinear(region.resonance); FilterDescriptions[0].RootKey = region.filterKeyCenter; FilterDescriptions[0].VelTrack = region.filterVelTrack; }
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; } } }
private void LoadSfzLfos(SfzRegion region) { LfoDescriptions = new LfoDescriptor[3]; LfoDescriptions[0] = new LfoDescriptor(); LfoDescriptions[0].DelayTime = region.pitchLfoDelay; //make sure pitch lfo is enabled for midi mod event LfoDescriptions[0].Frequency = region.pitchLfoFrequency > 0 ? region.pitchLfoFrequency : (float)Synthesizer.DefaultLfoFrequency; LfoDescriptions[0].Depth = region.pitchLfoDepth; LfoDescriptions[1] = new LfoDescriptor(); LfoDescriptions[1].DelayTime = region.filterLfoDelay; LfoDescriptions[1].Frequency = region.filterLfoFrequency; LfoDescriptions[1].Depth = region.filterLfoDepth; LfoDescriptions[2] = new LfoDescriptor(); LfoDescriptions[2].DelayTime = region.ampLfoDelay; LfoDescriptions[2].Frequency = region.ampLfoFrequency; LfoDescriptions[2].Depth = (float)SynthHelper.DBtoLinear(region.ampLfoDepth); }
public override bool Start(VoiceParameters voiceparams) { //calculate velocity float fVel = voiceparams.velocity / 127f; //reset counters voiceparams.counters[0] = voiceparams.generators[0].LoopStartPhase; voiceparams.counters[1] = voiceparams.generators[1].LoopStartPhase; voiceparams.counters[2] = 0.0; //reset envelopes voiceparams.envelopes[0].QuickSetup(voiceparams.synth.SampleRate, fVel, EnvelopeInfo[0]); voiceparams.envelopes[1].QuickSetup(voiceparams.synth.SampleRate, fVel, EnvelopeInfo[1]); //reset lfo (vibra) voiceparams.lfos[0].QuickSetup(voiceparams.synth.SampleRate, LfoInfo[0]); //calc initial volume float dBVel = -20.0f * (float)Math.Log10(16129.0 / (voiceparams.velocity * voiceparams.velocity)); voiceparams.volOffset = (float)SynthHelper.DBtoLinear(dBVel) * voiceparams.synth.MixGain; //check if we have finished before we have begun return(voiceparams.envelopes[0].CurrentState != EnvelopeStateEnum.None); }
public override bool Start(VoiceParameters voiceparams) { //calculate velocity float fVel = voiceparams.velocity / 127f; //setup generator voiceparams.generatorParams[0].QuickSetup(gen); //setup envelopes voiceparams.envelopes[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, fVel, ptch_env); voiceparams.envelopes[1].QuickSetup(voiceparams.synthParams.synth.SampleRate, fVel, fltr_env); voiceparams.envelopes[2].QuickSetup(voiceparams.synthParams.synth.SampleRate, fVel, amp_env); //setup lfos voiceparams.lfos[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, ptch_lfo); voiceparams.lfos[1].QuickSetup(voiceparams.synthParams.synth.SampleRate, fltr_lfo); voiceparams.lfos[2].QuickSetup(voiceparams.synthParams.synth.SampleRate, amp_lfo); //setup filter voiceparams.filters[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, voiceparams.note, fVel, fltr); voiceparams.pData[0].double1 = voiceparams.filters[0].Cutoff; if (!voiceparams.filters[0].Enabled) {//disable filter components if necessary voiceparams.envelopes[1].Depth = 0f; voiceparams.lfos[1].Depth = 0f; } //setup sfz params //calculate initial pitch voiceparams.pitchOffset = (voiceparams.note - gen.RootKey) * gen.KeyTrack + (int)(fVel * gen.VelocityTrack) + gen.Tune; voiceparams.pitchOffset += (int)(100.0 * (voiceparams.synthParams.masterCoarseTune + (voiceparams.synthParams.masterFineTune.Combined - 8192.0) / 8192.0)); //calculate initial vol voiceparams.volOffset = voiceparams.synthParams.volume.Combined / 16383f; voiceparams.volOffset *= voiceparams.volOffset * voiceparams.synthParams.synth.MixGain; float dBVel = -20.0f * (float)Math.Log10(16129.0 / (voiceparams.velocity * voiceparams.velocity)); voiceparams.volOffset *= (float)SynthHelper.DBtoLinear((voiceparams.note - ampRootKey) * ampKeyTrack + dBVel * ampVelTrack + sfzVolume); //check if we have finished before we have begun return(voiceparams.generatorParams[0].currentState != GeneratorStateEnum.Finished && voiceparams.envelopes[2].CurrentState != EnvelopeStateEnum.None); }