示例#1
0
 public void Release(GeneratorParameters generatorParams)
 {
     if (LoopMode == LoopMode.LoopUntilNoteOff)
     {
         generatorParams.CurrentState = GeneratorState.PostLoop;
         generatorParams.CurrentStart = StartPhase;
         generatorParams.CurrentEnd = EndPhase;
     }
 }
示例#2
0
 public void Release(GeneratorParameters generatorParams)
 {
     if (LoopMode == LoopMode.LoopUntilNoteOff)
     {
         generatorParams.CurrentState = GeneratorState.PostLoop;
         generatorParams.CurrentStart = StartPhase;
         generatorParams.CurrentEnd   = EndPhase;
     }
 }
示例#3
0
        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);
        }
示例#4
0
 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();
     }
 }
示例#5
0
 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);
 }
示例#6
0
        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);
        }
示例#7
0
 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);
 }
示例#8
0
 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;
     }
 }
示例#9
0
        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;
            }
        }