public void Release(GeneratorParameters generatorParams) { if (LoopMode == LoopMode.LoopUntilNoteOff) { generatorParams.CurrentState = GeneratorState.PostLoop; generatorParams.CurrentStart = StartPhase; generatorParams.CurrentEnd = EndPhase; } }
public virtual void GetValues(GeneratorParameters generatorParams, SampleArray blockBuffer, double increment) { var proccessed = 0; do { var samplesAvailable = (int)(Math.Ceiling((generatorParams.CurrentEnd - generatorParams.Phase) / increment)); if (samplesAvailable > blockBuffer.Length - proccessed) { while (proccessed < blockBuffer.Length) { blockBuffer[proccessed++] = GetValue(generatorParams.Phase); generatorParams.Phase += increment; } } else { var endProccessed = proccessed + samplesAvailable; while (proccessed < endProccessed) { blockBuffer[proccessed++] = GetValue(generatorParams.Phase); generatorParams.Phase += increment; } switch (generatorParams.CurrentState) { case GeneratorState.PreLoop: generatorParams.CurrentStart = LoopStartPhase; generatorParams.CurrentEnd = LoopEndPhase; generatorParams.CurrentState = GeneratorState.Loop; break; case GeneratorState.Loop: generatorParams.Phase += generatorParams.CurrentStart - generatorParams.CurrentEnd; break; case GeneratorState.PostLoop: generatorParams.CurrentState = GeneratorState.Finished; while (proccessed < blockBuffer.Length) { blockBuffer[proccessed++] = 0; } break; } } } while (proccessed < blockBuffer.Length); }
public VoiceParameters() { BlockBuffer = new SampleArray(SynthConstants.DefaultBlockSize); //create default number of each component PData = new UnionData[SynthConstants.MaxVoiceComponents]; GeneratorParams = new GeneratorParameters[SynthConstants.MaxVoiceComponents]; Envelopes = new Envelope[SynthConstants.MaxVoiceComponents]; Filters = new Filter[SynthConstants.MaxVoiceComponents]; Lfos = new Lfo[SynthConstants.MaxVoiceComponents]; //initialize each component for (int x = 0; x < SynthConstants.MaxVoiceComponents; x++) { GeneratorParams[x] = new GeneratorParameters(); Envelopes[x] = new Envelope(); Filters[x] = new Filter(); Lfos[x] = new Lfo(); } }
public virtual void GetValues(GeneratorParameters generatorParams, SampleArray blockBuffer, double increment) { var proccessed = 0; do { var samplesAvailable = (int)(Math.Ceiling((generatorParams.CurrentEnd - generatorParams.Phase) / increment)); if (samplesAvailable > blockBuffer.Length - proccessed) { while (proccessed < blockBuffer.Length) { blockBuffer[proccessed++] = GetValue(generatorParams.Phase); generatorParams.Phase += increment; } } else { var endProccessed = proccessed + samplesAvailable; while (proccessed < endProccessed) { blockBuffer[proccessed++] = GetValue(generatorParams.Phase); generatorParams.Phase += increment; } switch (generatorParams.CurrentState) { case GeneratorState.PreLoop: generatorParams.CurrentStart = LoopStartPhase; generatorParams.CurrentEnd = LoopEndPhase; generatorParams.CurrentState = GeneratorState.Loop; break; case GeneratorState.Loop: generatorParams.Phase += generatorParams.CurrentStart - generatorParams.CurrentEnd; break; case GeneratorState.PostLoop: generatorParams.CurrentState = GeneratorState.Finished; while (proccessed < blockBuffer.Length) blockBuffer[proccessed++] = 0; break; } } } while (proccessed < blockBuffer.Length); }
public override void GetValues(GeneratorParameters generatorParams, SampleArray blockBuffer, double increment) { int proccessed = 0; do { int samplesAvailable = (int)Math.Ceiling((generatorParams.CurrentEnd - generatorParams.Phase) / increment); if (samplesAvailable > blockBuffer.Length - proccessed) { Interpolate(generatorParams, blockBuffer, increment, proccessed, blockBuffer.Length); return; //proccessed = blockBuffer.Length; } else { int endProccessed = proccessed + samplesAvailable; Interpolate(generatorParams, blockBuffer, increment, proccessed, endProccessed); proccessed = endProccessed; switch (generatorParams.CurrentState) { case GeneratorState.PreLoop: generatorParams.CurrentStart = LoopStartPhase; generatorParams.CurrentEnd = LoopEndPhase; generatorParams.CurrentState = GeneratorState.Loop; break; case GeneratorState.Loop: generatorParams.Phase += generatorParams.CurrentStart - generatorParams.CurrentEnd; break; case GeneratorState.PostLoop: generatorParams.CurrentState = GeneratorState.Finished; while (proccessed < blockBuffer.Length) { blockBuffer[proccessed++] = 0f; } break; } } }while (proccessed < blockBuffer.Length); }
public override void GetValues(GeneratorParameters generatorParams, SampleArray blockBuffer, double increment) { int proccessed = 0; do { int samplesAvailable = (int)Math.Ceiling((generatorParams.CurrentEnd - generatorParams.Phase) / increment); if (samplesAvailable > blockBuffer.Length - proccessed) { Interpolate(generatorParams, blockBuffer, increment, proccessed, blockBuffer.Length); return; //proccessed = blockBuffer.Length; } else { int endProccessed = proccessed + samplesAvailable; Interpolate(generatorParams, blockBuffer, increment, proccessed, endProccessed); proccessed = endProccessed; switch (generatorParams.CurrentState) { case GeneratorState.PreLoop: generatorParams.CurrentStart = LoopStartPhase; generatorParams.CurrentEnd = LoopEndPhase; generatorParams.CurrentState = GeneratorState.Loop; break; case GeneratorState.Loop: generatorParams.Phase += generatorParams.CurrentStart - generatorParams.CurrentEnd; break; case GeneratorState.PostLoop: generatorParams.CurrentState = GeneratorState.Finished; while (proccessed < blockBuffer.Length) blockBuffer[proccessed++] = 0f; break; } } } while (proccessed < blockBuffer.Length); }
private void Interpolate(GeneratorParameters generatorParams, SampleArray blockBuffer, double increment, int start, int end) { switch (SynthConstants.InterpolationMode) { case Interpolation.Linear: #region Linear { double _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopEndPhase - 1 : this.EndPhase - 1; int index; float s1, s2, mu; while (start < end && generatorParams.Phase < _end)//do this until we reach an edge case or fill the buffer { index = (int)generatorParams.Phase; s1 = Samples[index]; s2 = Samples[index + 1]; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = s1 + mu * (s2 - s1); generatorParams.Phase += increment; } while (start < end)//edge case, if in loop wrap to loop start else use duplicate sample { index = (int)generatorParams.Phase; s1 = Samples[index]; if (generatorParams.CurrentState == GeneratorState.Loop) s2 = Samples[(int)generatorParams.CurrentStart]; else s2 = s1; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = s1 + mu * (s2 - s1); generatorParams.Phase += increment; } } #endregion break; case Interpolation.Cosine: #region Cosine { double _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopEndPhase - 1 : this.EndPhase - 1; int index; float s1, s2, mu; while (start < end && generatorParams.Phase < _end)//do this until we reach an edge case or fill the buffer { index = (int)generatorParams.Phase; s1 = Samples[index]; s2 = Samples[index + 1]; mu = (1f - (float)Math.Cos((generatorParams.Phase - index) * Math.PI)) * 0.5f; blockBuffer[start++] = s1 * (1f - mu) + s2 * mu; generatorParams.Phase += increment; } while (start < end)//edge case, if in loop wrap to loop start else use duplicate sample { index = (int)generatorParams.Phase; s1 = Samples[index]; if (generatorParams.CurrentState == GeneratorState.Loop) s2 = Samples[(int)generatorParams.CurrentStart]; else s2 = s1; mu = (1f - (float)Math.Cos((generatorParams.Phase - index) * Math.PI)) * 0.5f; blockBuffer[start++] = s1 * (1f - mu) + s2 * mu; generatorParams.Phase += increment; } } #endregion break; case Interpolation.CubicSpline: #region CubicSpline { double _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopStartPhase + 1 : this.StartPhase + 1; int index; float s0, s1, s2, s3, mu; while (start < end && generatorParams.Phase < _end)//edge case, wrap to endpoint or duplicate sample { index = (int)generatorParams.Phase; if (generatorParams.CurrentState == GeneratorState.Loop) s0 = Samples[(int)generatorParams.CurrentEnd - 1]; else s0 = Samples[index]; s1 = Samples[index]; s2 = Samples[index + 1]; s3 = Samples[index + 2]; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = ((-0.5f * s0 + 1.5f * s1 - 1.5f * s2 + 0.5f * s3) * mu * mu * mu + (s0 - 2.5f * s1 + 2f * s2 - 0.5f * s3) * mu * mu + (-0.5f * s0 + 0.5f * s2) * mu + (s1)); generatorParams.Phase += increment; } _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopEndPhase - 2 : this.EndPhase - 2; while (start < end && generatorParams.Phase < _end) { index = (int)generatorParams.Phase; s0 = Samples[index - 1]; s1 = Samples[index]; s2 = Samples[index + 1]; s3 = Samples[index + 2]; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = ((-0.5f * s0 + 1.5f * s1 - 1.5f * s2 + 0.5f * s3) * mu * mu * mu + (s0 - 2.5f * s1 + 2f * s2 - 0.5f * s3) * mu * mu + (-0.5f * s0 + 0.5f * s2) * mu + (s1)); generatorParams.Phase += increment; } _end += 1; while (start < end)//edge case, wrap to startpoint or duplicate sample { index = (int)generatorParams.Phase; s0 = Samples[index - 1]; s1 = Samples[index]; if (generatorParams.Phase < _end) { s2 = Samples[index + 1]; if (generatorParams.CurrentState == GeneratorState.Loop) s3 = Samples[(int)generatorParams.CurrentStart]; else s3 = s2; } else { if (generatorParams.CurrentState == GeneratorState.Loop) { s2 = Samples[(int)generatorParams.CurrentStart]; s3 = Samples[(int)generatorParams.CurrentStart + 1]; } else { s2 = s1; s3 = s1; } } mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = ((-0.5f * s0 + 1.5f * s1 - 1.5f * s2 + 0.5f * s3) * mu * mu * mu + (s0 - 2.5f * s1 + 2f * s2 - 0.5f * s3) * mu * mu + (-0.5f * s0 + 0.5f * s2) * mu + (s1)); generatorParams.Phase += increment; } } #endregion break; default: #region None { while (start < end) { blockBuffer[start++] = Samples[(int)generatorParams.Phase]; generatorParams.Phase += increment; } } #endregion break; } }
private void Interpolate(GeneratorParameters generatorParams, SampleArray blockBuffer, double increment, int start, int end) { switch (SynthConstants.InterpolationMode) { case Interpolation.Linear: #region Linear { double _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopEndPhase - 1 : this.EndPhase - 1; int index; float s1, s2, mu; while (start < end && generatorParams.Phase < _end) //do this until we reach an edge case or fill the buffer { index = (int)generatorParams.Phase; s1 = Samples[index]; s2 = Samples[index + 1]; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = s1 + mu * (s2 - s1); generatorParams.Phase += increment; } while (start < end) //edge case, if in loop wrap to loop start else use duplicate sample { index = (int)generatorParams.Phase; s1 = Samples[index]; if (generatorParams.CurrentState == GeneratorState.Loop) { s2 = Samples[(int)generatorParams.CurrentStart]; } else { s2 = s1; } mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = s1 + mu * (s2 - s1); generatorParams.Phase += increment; } } #endregion break; case Interpolation.Cosine: #region Cosine { double _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopEndPhase - 1 : this.EndPhase - 1; int index; float s1, s2, mu; while (start < end && generatorParams.Phase < _end) //do this until we reach an edge case or fill the buffer { index = (int)generatorParams.Phase; s1 = Samples[index]; s2 = Samples[index + 1]; mu = (1f - (float)Math.Cos((generatorParams.Phase - index) * Math.PI)) * 0.5f; blockBuffer[start++] = s1 * (1f - mu) + s2 * mu; generatorParams.Phase += increment; } while (start < end) //edge case, if in loop wrap to loop start else use duplicate sample { index = (int)generatorParams.Phase; s1 = Samples[index]; if (generatorParams.CurrentState == GeneratorState.Loop) { s2 = Samples[(int)generatorParams.CurrentStart]; } else { s2 = s1; } mu = (1f - (float)Math.Cos((generatorParams.Phase - index) * Math.PI)) * 0.5f; blockBuffer[start++] = s1 * (1f - mu) + s2 * mu; generatorParams.Phase += increment; } } #endregion break; case Interpolation.CubicSpline: #region CubicSpline { double _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopStartPhase + 1 : this.StartPhase + 1; int index; float s0, s1, s2, s3, mu; while (start < end && generatorParams.Phase < _end) //edge case, wrap to endpoint or duplicate sample { index = (int)generatorParams.Phase; if (generatorParams.CurrentState == GeneratorState.Loop) { s0 = Samples[(int)generatorParams.CurrentEnd - 1]; } else { s0 = Samples[index]; } s1 = Samples[index]; s2 = Samples[index + 1]; s3 = Samples[index + 2]; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = ((-0.5f * s0 + 1.5f * s1 - 1.5f * s2 + 0.5f * s3) * mu * mu * mu + (s0 - 2.5f * s1 + 2f * s2 - 0.5f * s3) * mu * mu + (-0.5f * s0 + 0.5f * s2) * mu + (s1)); generatorParams.Phase += increment; } _end = generatorParams.CurrentState == GeneratorState.Loop ? this.LoopEndPhase - 2 : this.EndPhase - 2; while (start < end && generatorParams.Phase < _end) { index = (int)generatorParams.Phase; s0 = Samples[index - 1]; s1 = Samples[index]; s2 = Samples[index + 1]; s3 = Samples[index + 2]; mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = ((-0.5f * s0 + 1.5f * s1 - 1.5f * s2 + 0.5f * s3) * mu * mu * mu + (s0 - 2.5f * s1 + 2f * s2 - 0.5f * s3) * mu * mu + (-0.5f * s0 + 0.5f * s2) * mu + (s1)); generatorParams.Phase += increment; } _end += 1; while (start < end) //edge case, wrap to startpoint or duplicate sample { index = (int)generatorParams.Phase; s0 = Samples[index - 1]; s1 = Samples[index]; if (generatorParams.Phase < _end) { s2 = Samples[index + 1]; if (generatorParams.CurrentState == GeneratorState.Loop) { s3 = Samples[(int)generatorParams.CurrentStart]; } else { s3 = s2; } } else { if (generatorParams.CurrentState == GeneratorState.Loop) { s2 = Samples[(int)generatorParams.CurrentStart]; s3 = Samples[(int)generatorParams.CurrentStart + 1]; } else { s2 = s1; s3 = s1; } } mu = (float)(generatorParams.Phase - index); blockBuffer[start++] = ((-0.5f * s0 + 1.5f * s1 - 1.5f * s2 + 0.5f * s3) * mu * mu * mu + (s0 - 2.5f * s1 + 2f * s2 - 0.5f * s3) * mu * mu + (-0.5f * s0 + 0.5f * s2) * mu + (s1)); generatorParams.Phase += increment; } } #endregion break; default: #region None { while (start < end) { blockBuffer[start++] = Samples[(int)generatorParams.Phase]; generatorParams.Phase += increment; } } #endregion break; } }