private TestSuite Build(Assembly assembly, string assemblyNameOrPath, IDictionary <string, object> options)
        {
            TestSuite testAssembly = null;

            try
            {
                if (options.ContainsKey(FrameworkPackageSettings.DefaultTestNamePattern))
                {
                    TestNameGenerator.DefaultTestNamePattern = options[FrameworkPackageSettings.DefaultTestNamePattern] as string;
                }

                if (options.ContainsKey(FrameworkPackageSettings.WorkDirectory))
                {
                    TestContext.DefaultWorkDirectory = options[FrameworkPackageSettings.WorkDirectory] as string;
                }
                else
                {
                    TestContext.DefaultWorkDirectory = Directory.GetCurrentDirectory();
                }

                if (options.ContainsKey(FrameworkPackageSettings.TestParametersDictionary))
                {
                    var testParametersDictionary = options[FrameworkPackageSettings.TestParametersDictionary] as IDictionary <string, string>;
                    if (testParametersDictionary != null)
                    {
                        foreach (var parameter in testParametersDictionary)
                        {
                            TestContext.Parameters.Add(parameter.Key, parameter.Value);
                        }
                    }
                }
                else
                {
                    // This cannot be changed without breaking backwards compatibility with old runners.
                    // Deserializes the way old runners understand.

                    if (options.ContainsKey(FrameworkPackageSettings.TestParameters))
                    {
                        string parameters = options[FrameworkPackageSettings.TestParameters] as string;
                        if (!string.IsNullOrEmpty(parameters))
                        {
                            foreach (string param in parameters.Split(new[] { ';' }))
                            {
                                int eq = param.IndexOf('=');

                                if (eq > 0 && eq < param.Length - 1)
                                {
                                    var name = param.Substring(0, eq);
                                    var val  = param.Substring(eq + 1);

                                    TestContext.Parameters.Add(name, val);
                                }
                            }
                        }
                    }
                }

                _filter = new PreFilter();
                if (options.ContainsKey(FrameworkPackageSettings.LOAD))
                {
                    foreach (string filterText in (IList)options[FrameworkPackageSettings.LOAD])
                    {
                        _filter.Add(filterText);
                    }
                }

                var fixtures = GetFixtures(assembly);

                testAssembly = BuildTestAssembly(assembly, assemblyNameOrPath, fixtures);
            }
            catch (Exception ex)
            {
                testAssembly = new TestAssembly(assemblyNameOrPath);
                testAssembly.MakeInvalid(ExceptionHelper.BuildMessage(ex, true));
            }

            return(testAssembly);
        }
        /// <summary>
        /// Process a buffer of sample data
        /// </summary>
        /// <param name="buffer">The samples need to be process</param>
        /// <returns>A array of result with the interval of 100ms</returns>
        public void ProcessBuffer(double[][] buffer, Action <double, double> progressUpdated)
        {
            // Clone the buffer
            double[][] clone = new double[buffer.Length][];
            for (int i = 0; i < buffer.Length; i++)
            {
                clone[i] = (double[])buffer[i].Clone();
            }
            buffer = clone;

            // “K” frequency weighting
            PreFilter.ProcessBuffer(buffer);
            HighPassFilter.ProcessBuffer(buffer);

            // Init the process
            int bufferPosition    = 0;
            int bufferSampleCount = buffer[0].Length;

            while (bufferPosition + (StepSampleCount - StepBufferPosition) < bufferSampleCount)
            {
                progressUpdated?.Invoke(bufferPosition, bufferSampleCount);
                // Enough to fill a step
                for (int channel = 0; channel < NumChannel; channel++)
                {
                    Array.Copy(buffer[channel], bufferPosition, StepBuffer[channel], StepBufferPosition, StepSampleCount - StepBufferPosition);
                }
                bufferPosition += StepSampleCount - StepBufferPosition;

                // Swap buffer
                double[][] temp = BlockBuffer[0];
                for (int i = 1; i < BlockBuffer.Length; i++)
                {
                    BlockBuffer[i - 1] = BlockBuffer[i];
                }
                BlockBuffer[BlockBuffer.Length - 1] = StepBuffer;
                StepBuffer         = temp;
                StepBufferPosition = 0;

                // Calc momentory loudness
                double momentaryMeanSquare = 0;
                if (BlockBuffer[0] != null)
                {
                    for (int channel = 0; channel < NumChannel; channel++)
                    {
                        double channelSquardSum = 0;
                        for (int step = 0; step < BlockStepCount; step++)
                        {
                            double[][] stepBuffer = BlockBuffer[step];
                            for (int sample = 0; sample < StepSampleCount; sample++)
                            {
                                double squared = Math.Pow(stepBuffer[channel][sample], 2);
                                channelSquardSum += squared;
                            }
                        }
                        double channelMeanSquare = channelSquardSum / (BlockStepCount * StepSampleCount);
                        double channelWeight     = GetChannelWeight(channel);
                        momentaryMeanSquare += channelWeight * channelMeanSquare;
                    }
                }
                else
                {
                    momentaryMeanSquare = 0;
                }
                double momentaryLoudness = -0.691 + 10 * Math.Log10(momentaryMeanSquare);
                MomentaryLoudnessUpdated?.Invoke(momentaryLoudness);

                if (ShortTermLoudnessUpdated != null)
                {
                    // Calc short-term loudness
                    ShiftBuffer(ShortTermMeanSquares);
                    ShortTermMeanSquares[ShortTermMeanSquares.Length - 1] = momentaryMeanSquare;

                    double shortTermMeanSquaresSum = 0;
                    for (int i = 0; i < ShortTermMeanSquares.Length; i++)
                    {
                        shortTermMeanSquaresSum += ShortTermMeanSquares[i];
                    }
                    double shortTermMeanSquareMean = shortTermMeanSquaresSum / ShortTermMeanSquares.Length;
                    double shortTermLoudness       = -0.691 + 10 * Math.Log10(shortTermMeanSquareMean);
                    ShortTermLoudnessUpdated?.Invoke(shortTermLoudness);
                }

                // Calc integrated loudness
                if (IsIntegrating)
                {
                    MeanSquareLoudness meanSquareLoudness = new MeanSquareLoudness
                    {
                        MeanSquare = momentaryMeanSquare,
                        Loudness   = momentaryLoudness
                    };
                    PrecedingMeanSquareLoudness.Add(meanSquareLoudness);
                }
            }

            // Process remaining samples
            int remainingLength = buffer[0].Length - bufferPosition;

            for (int channel = 0; channel < NumChannel; channel++)
            {
                Array.Copy(buffer[channel], bufferPosition, StepBuffer[channel], StepBufferPosition, remainingLength);
            }
            StepBufferPosition = remainingLength;
        }