/// <summary> /// Add set of harmonic features to calculation list /// </summary> /// <param name="featureList"></param> /// <param name="peakCount"></param> /// <param name="pitchEstimator"></param> /// <param name="lowPitch"></param> /// <param name="highPitch"></param> public void IncludeHarmonicFeatures(string featureList, int peakCount = 10, Func <float[], float> pitchEstimator = null, Action <float[], int[], float[], int, float> peaksDetector = null, float lowPitch = 80, float highPitch = 400) { if (featureList == "all" || featureList == "full") { featureList = HarmonicSet; } var features = featureList.Split(',', '+', '-', ';', ':') .Select(f => f.Trim().ToLower()); _harmonicExtractors = features.Select <string, Func <float[], int[], float[], float> >(feature => { switch (feature) { case "hc": case "hcentroid": return(Harmonic.Centroid); case "hs": case "hspread": return(Harmonic.Spread); case "inh": case "inharmonicity": return(Harmonic.Inharmonicity); case "oer": case "oddevenratio": return((spectrum, peaks, freqs) => Harmonic.OddToEvenRatio(spectrum, peaks)); case "t1": case "t2": case "t3": return((spectrum, peaks, freqs) => Harmonic.Tristimulus(spectrum, peaks, int.Parse(feature.Substring(1)))); default: return((spectrum, peaks, freqs) => 0); } }).ToList(); FeatureDescriptions.AddRange(features); if (pitchEstimator == null) { _pitchEstimator = spectrum => Pitch.FromSpectralPeaks(spectrum, SamplingRate, lowPitch, highPitch); } else { _pitchEstimator = pitchEstimator; } if (peaksDetector == null) { _peaksDetector = Harmonic.Peaks; } else { _peaksDetector = peaksDetector; } _peaks = new int[peakCount]; _peakFrequencies = new float[peakCount]; }