public int Recognize(ISoundSignalReader signal, HiddenMarkovClassifier hmm, out string name,
            SignalVisitor voiceVisitor = null)
        {
            var featureUtility = new FeatureUtility(_engineParameters);
            signal.Reset();
            var features = featureUtility.ExtractFeatures(signal, voiceVisitor).First();
            var observations = _codeBook.Quantize(features.Select(item => new Point(item)).ToArray());

            double[] responsabilities;
            var ret = hmm.Compute(observations, out responsabilities);

            var models = hmm.Models;
            var likelyHoodValue = Double.MinValue;
            name = string.Empty;

            foreach (var model in models)
            {
                var val = model.Evaluate(observations);
                if (val > likelyHoodValue)
                {
                    likelyHoodValue = val;
                    name = model.Tag.ToString();
                }
            }

            return ret;
        }
        public int Recognize(ISoundSignalReader signal, HiddenMarkovModel[] models, out string name,
            SignalVisitor voiceVisitor = null)
        {
            var featureUtility = new FeatureUtility(_engineParameters);
            signal.Reset();
            var features = featureUtility.ExtractFeatures(signal, voiceVisitor).First();
            var observations = _codeBook.Quantize(features.Select(item => new Point(item)).ToArray());

            var likelyHoodValue = Double.MinValue;
            name = string.Empty;
            var index = 0;
            var ret = 0;
            foreach (var model in models)
            {
                var val = model.Evaluate(observations);
                if (val > likelyHoodValue)
                {
                    likelyHoodValue = val;
                    name = model.Tag.ToString();
                    ret = index;
                }
                index++;
            }

            return ret;
        }
        public void ExtractFeaturesAsync(ISoundSignalReader signal, Action<List<double[]>> action,
            SignalVisitor voiceVisitor = null)
        {
            Action<List<double[]>> addfeatures = features =>
            {
                action.BeginInvoke(features, null, null);
            };

            ExtractFeaturesInternalUsingVad(signal, addfeatures, voiceVisitor);
        }
        public IEnumerable<List<double[]>> ExtractFeatures(ISoundSignalReader signal, SignalVisitor voiceVisitor = null)
        {
            List<List<Double[]>> allObservables = new List<List<Double[]>>();
            Action<List<double[]>> addfeatures = features =>
            {
                allObservables.Add(features);
            };

            ExtractFeaturesInternalUsingVad(signal, addfeatures, voiceVisitor);

            return allObservables;
        }
        public HiddenMarkovModel BuildModel(IList<ISoundSignalReader> signalReaders, string tag,
            SignalVisitor visitor = null)
        {
            var signals = signalReaders; // signals
            var signalsCount = signals.Count();
            List<List<double[]>> samples = new List<List<double[]>>();
            var featureUtility = new FeatureUtility(_engineParameters);
            var meanFeaturesLength = 0.0;

            for (var signalIndex = 0; signalIndex < signalsCount; signalIndex++)
            {
                var signal = signals[signalIndex];
                signal.Reset();
                var allSignalfeatures = featureUtility.ExtractFeatures(signal, visitor).ToArray();
                samples.AddRange(allSignalfeatures);
            }

            var featuresInput = new double[samples.Count][][];

            for (var index = 0; index < samples.Count; index++)
            {
                featuresInput[index] = samples[index].ToArray();
                meanFeaturesLength += featuresInput[index].Length;
            }
            meanFeaturesLength = meanFeaturesLength/samples.Count;
            var hmm = new HiddenMarkovModel(_numberOfHiddenStates, _codeBook.Size, false);

            List<int[]> observables = new List<int[]>();
            for (var signalIndex = 0; signalIndex < featuresInput.Length; signalIndex++) // foreach word signal
            {
                var points = featuresInput[signalIndex].Select(item => new Point(item)); // convert feature to points

                var codeItems = _codeBook.Quantize(points.ToArray());
                observables.Add(codeItems);
            }

            const int iterations = 20000;
            const double tolerance = 0.0;
            var viterbiLearning = new ViterbiLearning(hmm) {Iterations = iterations, Tolerance = tolerance};

            viterbiLearning.Run(observables.ToArray());
            var idProp = new IdentificationProperties
            {
                Class = ClassType.Word,
                MeanFeaturesLength = meanFeaturesLength,
                Label = tag
            };
            viterbiLearning.Model.Tag = idProp;

            _models[tag] = viterbiLearning.Model;
            return viterbiLearning.Model;
        }
 protected virtual bool AcceptVisitor(SignalVisitor visitor)
 {
     _visitors.Add(visitor);
     return true;
 }
 public bool Accept(SignalVisitor visitor)
 {
     return AcceptVisitor(visitor);
 }
        public void RecognizeAsync(ISoundSignalReader signal, HiddenMarkovClassifier hmm, Action<string> handleMessage,
            SignalVisitor voiceVisitor = null)
        {
            Action<List<double[]>> action = features =>
            {
                var observations = _codeBook.Quantize(features.Select(item => new Point(item)).ToArray());
                double[] responsabilities;
                var ret = hmm.Compute(observations, out responsabilities);

                var models = hmm.Models;
                var likelyHoodValue = Double.MinValue;

                foreach (var model in models)
                {
                    var val = model.Evaluate(observations);
                    if (val > likelyHoodValue)
                    {
                        likelyHoodValue = val;
                    }
                }

                handleMessage(hmm[ret].Tag.ToString());
            };

            var featureUtility = new FeatureUtility(_engineParameters);
            featureUtility.ExtractFeaturesAsync(signal, action, voiceVisitor);
        }
        public TrainResult TrainAll(Dictionary<string, IList<ISoundSignalReader>> signalsDictionary,
            SignalVisitor voiceVisitor = null)
        {
            var numberOfItems = 0;
            foreach (var item in signalsDictionary)
            {
                numberOfItems += item.Value.Count;
            }

            double[][][][] featuresInput = new Double[signalsDictionary.Count][][][];

            int[] models = new int[numberOfItems];
            var allSignalIndex = 0;
            var modelIndex = 0;

            var featureUtility = new FeatureUtility(_engineParameters);

            foreach (var item in signalsDictionary)
            {
                var signals = item.Value; // signals
                var signalsCount = signals.Count();

                featuresInput[modelIndex] = new double[signalsCount][][];

                for (var signalIndex = 0; signalIndex < signalsCount; signalIndex++)
                {
                    var signal = signals[signalIndex];
                    List<Double[]> features = featureUtility.ExtractFeatures(signal, voiceVisitor).First();

                    featuresInput[modelIndex][signalIndex] = features.ToArray();
                    models[allSignalIndex] = modelIndex;
                    allSignalIndex++;
                }
                modelIndex++;
            }

            List<int[]> observables = new List<int[]>();

            for (int wordIndex = 0; wordIndex < featuresInput.Length; wordIndex++) // foreach word
            {
                for (var signalIndex = 0; signalIndex < featuresInput[wordIndex].Length; signalIndex++)
                    // foreach word signal
                {
                    var points = featuresInput[wordIndex][signalIndex].Select(item => new Point(item));
                        // convert feature to points

                    var codeItems = _codeBook.Quantize(points.ToArray());
                    observables.Add(codeItems);
                }
            }
            //HiddenMarkovModel hmm = new HiddenMarkovModel(5, _codeBook.Size, true);
            //var Bauc

            var hmm = new HiddenMarkovClassifier(signalsDictionary.Count, new Forward(_numberOfHiddenStates),
                _codeBook.Size, signalsDictionary.Keys.ToArray());

            const int iterations = 200;
            const double tolerance = 0;

            var teacher = new HiddenMarkovClassifierLearning(hmm,
                i => new ViterbiLearning(hmm.Models[i]) {Iterations = iterations, Tolerance = tolerance}
                );

            teacher.Run(observables.ToArray(), models);

            return new TrainResult {Catalog = _codeBook, Models = hmm.Models.ToArray()};
        }
        public void RecognizeAsync(ISoundSignalReader signal, Action<string> handleMessage,
            SignalVisitor visitor = null)
        {
            Action<List<double[]>> action = features =>
            {
                var observations = _codeBook.Quantize(features.Select(item => new Point(item)).ToArray());
                var likelyHoodValue = Double.MinValue;
                HiddenMarkovModel bestFit = null;
                var modelsToSearchFor = _models.Values.Where(item =>
                {
                    var idProp = (IdentificationProperties) item.Tag;
                    var rateLength = Math.Abs(idProp.MeanFeaturesLength - observations.Length)/idProp.MeanFeaturesLength;
                    return rateLength < 0.1;
                }).ToArray();

                foreach (var model in modelsToSearchFor)
                {
                    var val = model.Evaluate(observations);
                    if (val > likelyHoodValue)
                    {
                        likelyHoodValue = val;
                        bestFit = model;
                    }
                }

                if (bestFit != null)
                {
                    var idProp = (IdentificationProperties)bestFit.Tag;
                    handleMessage(idProp.Label);
                }
            };

            var featureUtility = new FeatureUtility(_engineParameters);
            featureUtility.ExtractFeaturesAsync(signal, action, visitor);
        }
        public int Recognize(ISoundSignalReader signal, out string name,
            SignalVisitor visitor = null)
        {
            var featureUtility = new FeatureUtility(_engineParameters);
            signal.Reset();
            var features = featureUtility.ExtractFeatures(signal, visitor).First();

            var observations = _codeBook.Quantize(features.Select(item => new Point(item)).ToArray());
            var likelyHoodValue = Double.MinValue;
            HiddenMarkovModel bestFit = null;
            var index = 0;
            var ret = 0;
            foreach (var model in _models.Values)
            {
                var val = model.Evaluate(observations);

                if (val > likelyHoodValue)
                {
                    likelyHoodValue = val;
                    bestFit = model;
                    ret = index;
                }
                index++;
            }

            if (bestFit != null)
            {
                var idProp = (IdentificationProperties) bestFit.Tag;
                name = idProp.Label;
            }
            else
                name = string.Empty;

            return ret;
        }
        private void ExtractFeaturesInternalUsingVad(ISoundSignalReader signal, Action<List<double[]>> featureExtracted,
            SignalVisitor voiceVisitor)
        {
            var featureProvider = FeaturesProviderFactory.GetProvider(ProviderParameters, signal);

            var frameSize = (int) Math.Floor(signal.SampleRate*FrameSizeMiliseconds/1000.0);
            var stepSize = (int) Math.Floor(signal.SampleRate*StepSizeMiliseconds/1000.0);
            var filteredSignal = new PreemphasisFilter(signal, 0.95f);
            float[] frame;

            var voiceStream = new VoiceActivitySignalReader(filteredSignal, frameSize, 8);
            if (voiceVisitor != null)
            {
                voiceStream.Accept(voiceVisitor);
            }

            int index = 0, silentSamples = 0, noOfItems = ProviderParameters.NumberOfCoeff - 1;
            var observables = new List<double[]>();

            bool isVoice;
            while (voiceStream.Read(frameSize, stepSize, out frame, out isVoice))
            {
                if (isVoice)
                {
                    bool isEmpty;
                    var features = featureProvider.Extract(frame, out isEmpty);

                    silentSamples = 0;
                    observables.Add(features);
                    if (featureProvider.ComputeDelta)
                    {
                        ComputeDelta(observables, index - 1, 1, noOfItems);
                        ComputeDelta(observables, index - 2, noOfItems + 1, noOfItems, true);
                    }

                    index++;
                }
                else if (observables.Count > 0 && silentSamples > SilenceThreshHold)
                {
                    if (index >= MinWordLength)
                    {
                        if (featureProvider.ComputeDelta)
                        {
                            ComputeDelta(observables, index - 1, 1, noOfItems);
                            ComputeDelta(observables, index - 2, noOfItems + 1, noOfItems, true);
                            ComputeDelta(observables, index - 1, noOfItems + 1, noOfItems, true);
                        }

                        featureExtracted(observables);
                    }

                    observables = new List<double[]>();
                    index = 0;
                }
                else
                {
                    silentSamples++;
                }
            }
        }