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(gen); //setup envelopes voiceparams.envelopes[0].QuickSetupSf2(voiceparams.synthParams.synth.SampleRate, note, keynumToModEnvHold, keynumToModEnvDecay, false, mod_env); voiceparams.envelopes[1].QuickSetupSf2(voiceparams.synthParams.synth.SampleRate, note, keynumToVolEnvHold, keynumToVolEnvDecay, true, vel_env); //setup filter //voiceparams.pData[0].int1 = iniFilterFc - (int)(2400 * CalculateModulator(SourceTypeEnum.Linear, TransformEnum.Linear, DirectionEnum.MaxToMin, PolarityEnum.Unipolar, voiceparams.velocity, 0, 127)); //if (iniFilterFc >= 13500 && fltr.Resonance <= 1) voiceparams.filters[0].Disable(); //else // voiceparams.filters[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, note, 1f, fltr); //setup lfos voiceparams.lfos[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, mod_lfo); voiceparams.lfos[1].QuickSetup(voiceparams.synthParams.synth.SampleRate, vib_lfo); //calculate initial pitch voiceparams.pitchOffset = (note - gen.RootKey) * gen.KeyTrack + gen.Tune; voiceparams.pitchOffset += (int)(100.0 * (voiceparams.synthParams.masterCoarseTune + (voiceparams.synthParams.masterFineTune.Combined - 8192.0) / 8192.0)); //calculate initial volume voiceparams.volOffset = initialAttn; voiceparams.volOffset -= 96.0f * (float)CalculateModulator(SourceTypeEnum.Concave, TransformEnum.Linear, DirectionEnum.MaxToMin, PolarityEnum.Unipolar, voiceparams.velocity, 0, 127); voiceparams.volOffset -= 96.0f * (float)CalculateModulator(SourceTypeEnum.Concave, TransformEnum.Linear, DirectionEnum.MaxToMin, PolarityEnum.Unipolar, voiceparams.synthParams.volume.Coarse, 0, 127); //check if we have finished before we have begun return voiceparams.generatorParams[0].currentState != GeneratorStateEnum.Finished && voiceparams.envelopes[1].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; }
public override void Stop(VoiceParameters voiceparams) { gen.Release(voiceparams.generatorParams[0]); if (gen.LoopMode != LoopModeEnum.OneShot) { voiceparams.envelopes[0].Release(Synthesis.Synthesizer.DenormLimit); voiceparams.envelopes[1].ReleaseSf2VolumeEnvelope(); } }
public static void MixMonoToMonoInterpolation(int startIndex, float volume, VoiceParameters voiceParams) { float inc = (volume - voiceParams.mixing[0]) / Synthesizer.DefaultBlockSize; for (int i = 0; i < voiceParams.blockBuffer.Length; i++) { voiceParams.mixing[0] += inc; voiceParams.synth.sampleBuffer[startIndex + i] += voiceParams.blockBuffer[i] * voiceParams.mixing[0]; } voiceParams.mixing[0] = volume; }
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 bool Start(VoiceParameters voiceparams) { //calculate velocity float fVel = voiceparams.velocity / 127f; //reset generator voiceparams.generatorParams[0].QuickSetup(gen); //reset envelope voiceparams.envelopes[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, fVel, env); //reset lfo (vibra) voiceparams.lfos[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, lfo); //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 volume voiceparams.volOffset = voiceparams.synthParams.volume.Combined / 16383f; voiceparams.volOffset *= voiceparams.volOffset * fVel * voiceparams.synthParams.synth.MixGain; //check if we have finished before we have begun return voiceparams.generatorParams[0].currentState != GeneratorStateEnum.Finished && voiceparams.envelopes[0].CurrentState != EnvelopeStateEnum.None; }
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 bool Start(VoiceParameters voiceparams) { //calculate velocity float fVel = voiceparams.velocity / 127f; //reset counters voiceparams.pData[0].double1 = cGen.LoopStartPhase; voiceparams.pData[1].double1 = mGen.LoopStartPhase; voiceparams.pData[2].double1 = 0.0; //reset envelopes voiceparams.envelopes[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, fVel, cEnv); voiceparams.envelopes[1].QuickSetup(voiceparams.synthParams.synth.SampleRate, fVel, mEnv); //reset lfo (vibra) voiceparams.lfos[0].QuickSetup(voiceparams.synthParams.synth.SampleRate, lfo); //calculate initial pitch voiceparams.pitchOffset = (int)(100.0 * (voiceparams.synthParams.masterCoarseTune + (voiceparams.synthParams.masterFineTune.Combined - 8192.0) / 8192.0)); //calc initial volume voiceparams.volOffset = voiceparams.synthParams.volume.Combined / 16383f; voiceparams.volOffset *= voiceparams.volOffset * fVel * voiceparams.synthParams.synth.MixGain; //check if we have finished before we have begun return voiceparams.envelopes[0].CurrentState != EnvelopeStateEnum.None; }
/// <summary> /// Stops all voices. /// </summary> /// <param name="immediate">If true all voices will stop immediately regardless of their release phase.</param> public void NoteOffAll(bool immediate) { LinkedListNode <Voice> node = voiceManager.activeVoices.First; if (immediate) {//if immediate ignore hold pedals and clear the entire registry voiceManager.ClearRegistry(); while (node != null) { node.Value.StopImmediately(); LinkedListNode <Voice> delnode = node; node = node.Next; voiceManager.activeVoices.Remove(delnode); voiceManager.freeVoices.AddFirst(delnode); } } else {//otherwise we have to check for hold pedals and double check the registry before removing the voice while (node != null) { VoiceParameters voiceParams = node.Value.VoiceParams; if (voiceParams.state == VoiceStateEnum.Playing) { //if hold pedal is enabled do not stop the voice if (synthChannels[voiceParams.channel].holdPedal) { voiceParams.noteOffPending = true; } else { node.Value.Stop(); voiceManager.RemoveFromRegistry(node.Value); } } node = node.Next; } } }
public abstract void Process(VoiceParameters voiceparams, int startIndex, int endIndex);
public override void Stop(VoiceParameters voiceparams) { gen.Release(voiceparams.generatorParams[0]); if (gen.LoopMode != LoopModeEnum.OneShot) voiceparams.envelopes[0].Release(Synthesis.Synthesizer.NonAudible); }
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; } } }
// Public public Voice() { voiceparams = new VoiceParameters(); }
public override bool Start(VoiceParameters voiceparams) { throw new NotImplementedException(); }
public override void Process(VoiceParameters voiceparams, int startIndex, int endIndex) { throw new NotImplementedException(); }
public override void Stop(VoiceParameters voiceparams) { throw new NotImplementedException(); }
public abstract void Stop(VoiceParameters voiceparams);
public abstract bool Start(VoiceParameters voiceparams);
public override void Stop(VoiceParameters voiceparams) { voiceparams.envelopes[0].Release(Synthesis.Synthesizer.NonAudible); voiceparams.envelopes[1].Release(Synthesis.Synthesizer.DenormLimit); }
public static void MixMonoToStereoInterpolation(int startIndex, float leftVol, float rightVol, VoiceParameters voiceParams) { float inc_l = (leftVol - voiceParams.mixing[0]) / Synthesizer.DefaultBlockSize; float inc_r = (rightVol - voiceParams.mixing[1]) / Synthesizer.DefaultBlockSize; for (int i = 0; i < voiceParams.blockBuffer.Length; i++) { voiceParams.mixing[0] += inc_l; voiceParams.mixing[1] += inc_r; voiceParams.synth.sampleBuffer[startIndex] += voiceParams.blockBuffer[i] * voiceParams.mixing[0]; voiceParams.synth.sampleBuffer[startIndex + 1] += voiceParams.blockBuffer[i] * voiceParams.mixing[1]; startIndex += 2; } voiceParams.mixing[0] = leftVol; voiceParams.mixing[1] = rightVol; }
// Public public Voice(Synthesizer synth) { voiceparams = new VoiceParameters(synth); }