/// <summary> /// Creates thread-safe copy of the extractor for parallel computations. /// </summary> public override FeatureExtractor ParallelCopy() { var options = new MultiFeatureOptions { SamplingRate = SamplingRate, FrameDuration = FrameDuration, HopDuration = HopDuration, FeatureList = string.Join(",", FeatureDescriptions), Parameters = _parameters }; return(new TimeDomainFeaturesExtractor(options) { _extractors = _extractors }); }
/// <summary> /// Constructs extractor from configuration <paramref name="options"/>. /// </summary> public TimeDomainFeaturesExtractor(MultiFeatureOptions options) : base(options) { var featureList = options.FeatureList; if (featureList == "all" || featureList == "full") { featureList = FeatureSet; } var features = featureList.Split(',', '+', '-', ';', ':') .Select(f => f.Trim().ToLower()) .ToList(); _parameters = options.Parameters; _extractors = features.Select <string, Func <DiscreteSignal, int, int, float> >(feature => { switch (feature) { case "e": case "en": case "energy": return((signal, start, end) => signal.Energy(start, end)); case "rms": return((signal, start, end) => signal.Rms(start, end)); case "zcr": case "zero-crossing-rate": return((signal, start, end) => signal.ZeroCrossingRate(start, end)); case "entropy": return((signal, start, end) => signal.Entropy(start, end)); default: return((signal, start, end) => 0); } }).ToList(); FeatureCount = features.Count; FeatureDescriptions = features; }
/// <summary> /// Copy of current extractor that can work in parallel /// </summary> /// <returns></returns> public override FeatureExtractor ParallelCopy() { var spectralFeatureSet = string.Join(",", FeatureDescriptions.Take(_extractors.Count)); var options = new MultiFeatureOptions { SamplingRate = SamplingRate, FeatureList = spectralFeatureSet, FrameDuration = FrameDuration, HopDuration = HopDuration, FftSize = _blockSize, Frequencies = _frequencies, PreEmphasis = _preEmphasis, Window = _window, Parameters = _parameters }; return(new SpectralFeaturesExtractor(options) { _extractors = _extractors }); }
/// <summary> /// Constructor /// </summary> /// <param name="options">Options</param> public SpectralFeaturesExtractor(MultiFeatureOptions options) : base(options) { var featureList = options.FeatureList; if (featureList == "all" || featureList == "full") { featureList = FeatureSet; } var features = featureList.Split(',', '+', '-', ';', ':') .Select(f => f.Trim().ToLower()) .ToList(); _parameters = options.Parameters; _extractors = features.Select <string, Func <float[], float[], float> >(feature => { switch (feature) { case "sc": case "centroid": return(Spectral.Centroid); case "ss": case "spread": return(Spectral.Spread); case "sfm": case "flatness": if (_parameters?.ContainsKey("minLevel") ?? false) { var minLevel = (float)_parameters["minLevel"]; return((spectrum, freqs) => Spectral.Flatness(spectrum, minLevel)); } else { return((spectrum, freqs) => Spectral.Flatness(spectrum)); } case "sn": case "noiseness": if (_parameters?.ContainsKey("noiseFrequency") ?? false) { var noiseFrequency = (float)_parameters["noiseFrequency"]; return((spectrum, freqs) => Spectral.Noiseness(spectrum, freqs, noiseFrequency)); } else { return((spectrum, freqs) => Spectral.Noiseness(spectrum, freqs)); } case "rolloff": if (_parameters?.ContainsKey("rolloffPercent") ?? false) { var rolloffPercent = (float)_parameters["rolloffPercent"]; return((spectrum, freqs) => Spectral.Rolloff(spectrum, freqs, rolloffPercent)); } else { return((spectrum, freqs) => Spectral.Rolloff(spectrum, freqs)); } case "crest": return((spectrum, freqs) => Spectral.Crest(spectrum)); case "entropy": case "ent": return((spectrum, freqs) => Spectral.Entropy(spectrum)); case "sd": case "decrease": return((spectrum, freqs) => Spectral.Decrease(spectrum)); case "c1": case "c2": case "c3": case "c4": case "c5": case "c6": return((spectrum, freqs) => Spectral.Contrast(spectrum, freqs, int.Parse(feature.Substring(1)))); default: return((spectrum, freqs) => 0); } }).ToList(); FeatureCount = features.Count; FeatureDescriptions = features; _blockSize = options.FftSize > FrameSize ? options.FftSize : MathUtils.NextPowerOfTwo(FrameSize); _fft = new RealFft(_blockSize); var frequencies = options.Frequencies; var resolution = (float)SamplingRate / _blockSize; if (frequencies == null) { _frequencies = Enumerable.Range(0, _blockSize / 2 + 1) .Select(f => f * resolution) .ToArray(); } else if (frequencies.Length == _blockSize / 2 + 1) { _frequencies = frequencies; } else { _frequencies = new float[frequencies.Length + 1]; frequencies.FastCopyTo(_frequencies, frequencies.Length, 0, 1); _mappedSpectrum = new float[_frequencies.Length]; _frequencyPositions = new int[_frequencies.Length]; for (var i = 1; i < _frequencies.Length; i++) { _frequencyPositions[i] = (int)(_frequencies[i] / resolution) + 1; } } _spectrum = new float[_blockSize / 2 + 1]; // buffer for magnitude spectrum }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { var ofd = new OpenFileDialog(); if (ofd.ShowDialog() != DialogResult.OK) { return; } using (var stream = new FileStream(ofd.FileName, FileMode.Open)) { var waveFile = new WaveFile(stream); _signal = waveFile[Channels.Left]; } _stft = new Stft(_frameSize, _hopSize); var frameDuration = (double)_frameSize / _signal.SamplingRate; var hopDuration = (double)_hopSize / _signal.SamplingRate; var freqs = new[] { 300f, 600, 1000, 2000, 4000, 7000 }; var pitchOptions = new PitchOptions { SamplingRate = _signal.SamplingRate, FrameDuration = frameDuration, HopDuration = hopDuration, HighFrequency = 900/*Hz*/ }; var pitchExtractor = new PitchExtractor(pitchOptions); var pitchTrack = pitchExtractor.ParallelComputeFrom(_signal) .Select(p => p[0]) .ToArray(); var options = new MultiFeatureOptions { SamplingRate = _signal.SamplingRate, FrameDuration = frameDuration, HopDuration = hopDuration }; var tdExtractor = new TimeDomainFeaturesExtractor(options); tdExtractor.AddFeature("pitch_zcr", (signal, start, end) => Pitch.FromZeroCrossingsSchmitt(signal, start, end)); var mpeg7Extractor = new Mpeg7SpectralFeaturesExtractor(options); mpeg7Extractor.IncludeHarmonicFeatures("all"); mpeg7Extractor.SetPitchTrack(pitchTrack); options.FeatureList = "sc+sn"; options.Frequencies = freqs; var spectralExtractor = new SpectralFeaturesExtractor(options); //spectralExtractor.AddFeature("pitch_hss", (spectrum, fs) => Pitch.FromHss(spectrum, _signal.SamplingRate)); var tdVectors = tdExtractor.ParallelComputeFrom(_signal); var spectralVectors = spectralExtractor.ParallelComputeFrom(_signal); var mpeg7Vectors = mpeg7Extractor.ComputeFrom(_signal); _vectors = FeaturePostProcessing.Join(tdVectors, spectralVectors, mpeg7Vectors); //FeaturePostProcessing.NormalizeMean(_vectors); //FeaturePostProcessing.AddDeltas(_vectors); var descriptions = tdExtractor.FeatureDescriptions .Concat(spectralExtractor.FeatureDescriptions) .Concat(mpeg7Extractor.FeatureDescriptions) .ToList(); FillFeaturesList(_vectors, descriptions, tdExtractor.TimeMarkers(_vectors.Length)); spectrogramPlot.ColorMapName = "afmhot"; spectrogramPlot.MarklineThickness = 2; spectrogramPlot.Spectrogram = _stft.Spectrogram(_signal); }
public void extractFeatures() { //NWaves //Initial setup if (_filePath != null) { DiscreteSignal signal; // load var mfcc_no = 24; var samplingRate = 44100; var mfccOptions = new MfccOptions { SamplingRate = samplingRate, FeatureCount = mfcc_no, FrameDuration = 0.025 /*sec*/, HopDuration = 0.010 /*sec*/, PreEmphasis = 0.97, Window = WindowTypes.Hamming }; var opts = new MultiFeatureOptions { SamplingRate = samplingRate, FrameDuration = 0.025, HopDuration = 0.010 }; var tdExtractor = new TimeDomainFeaturesExtractor(opts); var mfccExtractor = new MfccExtractor(mfccOptions); // Read from file. featureString = String.Empty; featureString = $"green,"; //MFCC var avg_vec_mfcc = new List <float>(mfcc_no + 1); //TD Features var avg_vec_td = new List <float>(4); //Spectral features var avg_vec_spect = new List <float>(10); for (var i = 0; i < mfcc_no; i++) { avg_vec_mfcc.Add(0f); } for (var i = 0; i < 4; i++) { avg_vec_td.Add(0f); } for (var i = 0; i < 10; i++) { avg_vec_spect.Add(0f); } string specFeatures = String.Empty; Console.WriteLine($"{tag} Reading from file"); using (var stream = new FileStream(_filePath, FileMode.Open)) { var waveFile = new WaveFile(stream); signal = waveFile[channel : Channels.Left]; ////Compute MFCC float[] mfvfuck = new float[25]; var sig_sam = signal.Samples; mfccVectors = mfccExtractor.ComputeFrom(sig_sam); var fftSize = 1024; tdVectors = tdExtractor.ComputeFrom(signal.Samples); var fft = new Fft(fftSize); var resolution = (float)samplingRate / fftSize; var frequencies = Enumerable.Range(0, fftSize / 2 + 1) .Select(f => f * resolution) .ToArray(); var spectrum = new Fft(fftSize).MagnitudeSpectrum(signal).Samples; var centroid = Spectral.Centroid(spectrum, frequencies); var spread = Spectral.Spread(spectrum, frequencies); var flatness = Spectral.Flatness(spectrum, 0); var noiseness = Spectral.Noiseness(spectrum, frequencies, 3000); var rolloff = Spectral.Rolloff(spectrum, frequencies, 0.85f); var crest = Spectral.Crest(spectrum); var decrease = Spectral.Decrease(spectrum); var entropy = Spectral.Entropy(spectrum); specFeatures = $"{centroid},{spread},{flatness},{noiseness},{rolloff},{crest},{decrease},{entropy}"; //} Console.WriteLine($"{tag} All features ready"); for (int calibC = 0; calibC < mfccVectors.Count; calibC += (mfccVectors.Count / duration) - 1) { featureString = String.Empty; var tmp = new ModelInput(); for (var i = 0; i < mfcc_no; i++) { avg_vec_mfcc[i] = mfccVectors[calibC][i]; } for (var i = 0; i < 4; i++) { avg_vec_td[i] = tdVectors[calibC][i]; } featureString += String.Join(",", avg_vec_mfcc); featureString += ","; featureString += String.Join(",", avg_vec_td); featureString += ","; featureString += specFeatures; Console.WriteLine($"{tag} Feature String ready {featureString}"); if (File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"))) { File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp")); File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"), featureString); } else { File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"), featureString); } MLContext mLContext = new MLContext(); string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"); IDataView dataView = mLContext.Data.LoadFromTextFile <ModelInput>( path: fileName, hasHeader: false, separatorChar: ',', allowQuoting: true, allowSparse: false); // Use first line of dataset as model input // You can replace this with new test data (hardcoded or from end-user application) ModelInput sampleForPrediction = mLContext.Data.CreateEnumerable <ModelInput>(dataView, false) .First(); ModelOutput opm = ConsumeModel.Predict(sampleForPrediction); featureTimeList.Add(opm.Score); Console.WriteLine($"{tag} Feature vs time list ready"); } //Console.WriteLine($"{tag} MFCC: {mfccVectors.Count}"); //Console.WriteLine($"{tag} TD: {tdVectors.Count}"); //Console.WriteLine($"{tag} featureTimeArray: {featureTimeList.Count} {featureString}"); } } }
async public void extractFeatures(string _filepath, StorageFile sf) { op = new float[10]; tdVectors = new List <float[]>(); mfccVectors = new List <float[]>(); featureTimeList = new List <float[]>(); //NWaves FilePath = _filepath; PredictedLabel = "Ready!."; //player.Load(GetStreamFromFile(FilePath)); //player.Play(); mMedia.Source = MediaSource.CreateFromStorageFile(sf); bool test = player.IsPlaying; mMedia.AutoPlay = true; MusicProperties properties = await sf.Properties.GetMusicPropertiesAsync(); TimeSpan myTrackDuration = properties.Duration; duration = Convert.ToInt32(myTrackDuration.TotalSeconds); if (FilePath != null) { DiscreteSignal signal; // load var mfcc_no = 24; var samplingRate = 44100; var mfccOptions = new MfccOptions { SamplingRate = samplingRate, FeatureCount = mfcc_no, FrameDuration = 0.025 /*sec*/, HopDuration = 0.010 /*sec*/, PreEmphasis = 0.97, Window = WindowTypes.Hamming }; var opts = new MultiFeatureOptions { SamplingRate = samplingRate, FrameDuration = 0.025, HopDuration = 0.010 }; var tdExtractor = new TimeDomainFeaturesExtractor(opts); var mfccExtractor = new MfccExtractor(mfccOptions); // Read from file. featureString = String.Empty; featureString = $"green,"; //MFCC var mfccList = new List <List <double> >(); var tdList = new List <List <double> >(); //MFCC //TD Features //Spectral features for (var i = 0; i < mfcc_no; i++) { mfccList.Add(new List <double>()); } for (var i = 0; i < 4; i++) { tdList.Add(new List <double>()); } string specFeatures = String.Empty; Console.WriteLine($"{tag} Reading from file"); using (var stream = new FileStream(FilePath, FileMode.Open)) { var waveFile = new WaveFile(stream); signal = waveFile[channel : Channels.Left]; ////Compute MFCC float[] mfvfuck = new float[25]; var sig_sam = signal.Samples; mfccVectors = mfccExtractor.ComputeFrom(sig_sam); var fftSize = 1024; tdVectors = tdExtractor.ComputeFrom(signal.Samples); var fft = new Fft(fftSize); var resolution = (float)samplingRate / fftSize; var frequencies = Enumerable.Range(0, fftSize / 2 + 1) .Select(f => f * resolution) .ToArray(); var spectrum = new Fft(fftSize).MagnitudeSpectrum(signal).Samples; var centroid = Spectral.Centroid(spectrum, frequencies); var spread = Spectral.Spread(spectrum, frequencies); var flatness = Spectral.Flatness(spectrum, 0); var noiseness = Spectral.Noiseness(spectrum, frequencies, 3000); var rolloff = Spectral.Rolloff(spectrum, frequencies, 0.85f); var crest = Spectral.Crest(spectrum); var decrease = Spectral.Decrease(spectrum); var entropy = Spectral.Entropy(spectrum); specFeatures = $"{centroid},{spread},{flatness},{noiseness},{rolloff},{crest},{decrease},{entropy}"; //} Console.WriteLine($"{tag} All features ready"); for (int calibC = 0; calibC < mfccVectors.Count;) { featureString = String.Empty; var tmp = new ModelInput(); for (var j = 0; j < (mfccVectors.Count / duration) - 1 && calibC < mfccVectors.Count; j++) { for (var i = 0; i < mfcc_no; i++) { mfccList[i].Add(mfccVectors[calibC][i]); } for (var i = 0; i < 4; i++) { tdList[i].Add(tdVectors[calibC][i]); } calibC += 1; } var mfcc_statistics = new List <double>(); for (var i = 0; i < mfcc_no; i++) { //preheader += m + "_mean"; //preheader += m + "_min"; //preheader += m + "_var"; //preheader += m + "_sd"; //preheader += m + "_med"; //preheader += m + "_lq"; //preheader += m + "_uq"; //preheader += m + "_skew"; //preheader += m + "_kurt"; mfcc_statistics.Add(Statistics.Mean(mfccList[i])); mfcc_statistics.Add(Statistics.Minimum(mfccList[i])); mfcc_statistics.Add(Statistics.Variance(mfccList[i])); mfcc_statistics.Add(Statistics.StandardDeviation(mfccList[i])); mfcc_statistics.Add(Statistics.Median(mfccList[i])); mfcc_statistics.Add(Statistics.LowerQuartile(mfccList[i])); mfcc_statistics.Add(Statistics.UpperQuartile(mfccList[i])); mfcc_statistics.Add(Statistics.Skewness(mfccList[i])); mfcc_statistics.Add(Statistics.Kurtosis(mfccList[i])); } var td_statistics = new List <double>(); for (var i = 0; i < 4; i++) { td_statistics.Add(Statistics.Mean(tdList[i])); td_statistics.Add(Statistics.Minimum(tdList[i])); td_statistics.Add(Statistics.Variance(tdList[i])); td_statistics.Add(Statistics.StandardDeviation(tdList[i])); td_statistics.Add(Statistics.Median(tdList[i])); td_statistics.Add(Statistics.LowerQuartile(tdList[i])); td_statistics.Add(Statistics.UpperQuartile(tdList[i])); td_statistics.Add(Statistics.Skewness(tdList[i])); td_statistics.Add(Statistics.Kurtosis(tdList[i])); } // Write MFCCs featureString += String.Join(",", mfcc_statistics); featureString += ","; featureString += String.Join(",", td_statistics); //Write Spectral features as well featureString += ","; featureString += specFeatures; Console.WriteLine($"{tag} Feature String ready {featureString}"); if (File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"))) { File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp")); File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"), featureString); } else { File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"), featureString); } MLContext mLContext = new MLContext(); string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp"); IDataView dataView = mLContext.Data.LoadFromTextFile <ModelInput>( path: fileName, hasHeader: false, separatorChar: ',', allowQuoting: true, allowSparse: false); // Use first line of dataset as model input // You can replace this with new test data (hardcoded or from end-user application) ModelInput sampleForPrediction = mLContext.Data.CreateEnumerable <ModelInput>(dataView, false) .First(); ModelOutput opm = ConsumeModel.Predict(sampleForPrediction); featureTimeList.Add(opm.Score); Console.WriteLine($"{tag} Feature vs time list ready"); } //Console.WriteLine($"{tag} MFCC: {mfccVectors.Count}"); //Console.WriteLine($"{tag} TD: {tdVectors.Count}"); //Console.WriteLine($"{tag} featureTimeArray: {featureTimeList.Count} {featureString}"); } } playAudio(); }
static void Main(string[] args) { DiscreteSignal signal; // load var mfcc_no = 24; var samplingRate = 16000; var mfccOptions = new MfccOptions { SamplingRate = samplingRate, FeatureCount = mfcc_no, FrameDuration = 0.025 /*sec*/, HopDuration = 0.010 /*sec*/, PreEmphasis = 0.97, Window = WindowTypes.Hamming }; var opts = new MultiFeatureOptions { SamplingRate = samplingRate, FrameDuration = 0.025, HopDuration = 0.010 }; var tdExtractor = new TimeDomainFeaturesExtractor(opts); var mfccExtractor = new MfccExtractor(mfccOptions); var folders = Directory.GetDirectories(Path.Combine(Environment.CurrentDirectory, "Dataset")); Console.WriteLine($"Started!"); using (var writer = File.CreateText(Path.Combine(Environment.CurrentDirectory, "Data.csv"))) { //Write header var main_header = "genre,"; main_header += String.Join(",", mfccExtractor.FeatureDescriptions); main_header += ","; main_header += String.Join(",", tdExtractor.FeatureDescriptions); main_header += ",centroid,spread,flatness,noiseness,roloff,crest,decrease,spectral_entropy"; writer.WriteLine(main_header); string feature_string = String.Empty; foreach (var folder in folders) { var f_name = new DirectoryInfo(folder).Name; var files = Directory.GetFiles(Path.Combine(Environment.CurrentDirectory, "Dataset", folder)); //Write the genre label here Console.WriteLine($"{f_name}"); foreach (var filename in files) { feature_string = String.Empty; feature_string = $"{f_name},"; //MFCC var avg_vec_mfcc = new List <float>(mfcc_no + 1); //TD Features var avg_vec_td = new List <float>(4); //Spectral features var avg_vec_spect = new List <float>(10); for (var i = 0; i < mfcc_no; i++) { avg_vec_mfcc.Add(0f); } for (var i = 0; i < 4; i++) { avg_vec_td.Add(0f); } for (var i = 0; i < 10; i++) { avg_vec_spect.Add(0f); } string specFeatures = String.Empty; using (var stream = new FileStream(Path.Combine(Environment.CurrentDirectory, "Dataset", filename), FileMode.Open)) { var waveFile = new WaveFile(stream); signal = waveFile[Channels.Average]; //Compute MFCC tdVectors = tdExtractor.ComputeFrom(signal); mfccVectors = mfccExtractor.ComputeFrom(signal); var fftSize = 1024; var fft = new Fft(fftSize); var resolution = (float)samplingRate / fftSize; var frequencies = Enumerable.Range(0, fftSize / 2 + 1) .Select(f => f * resolution) .ToArray(); var spectrum = new Fft(fftSize).MagnitudeSpectrum(signal).Samples; var centroid = Spectral.Centroid(spectrum, frequencies); var spread = Spectral.Spread(spectrum, frequencies); var flatness = Spectral.Flatness(spectrum, 0); var noiseness = Spectral.Noiseness(spectrum, frequencies, 3000); var rolloff = Spectral.Rolloff(spectrum, frequencies, 0.85f); var crest = Spectral.Crest(spectrum); var decrease = Spectral.Decrease(spectrum); var entropy = Spectral.Entropy(spectrum); specFeatures = $"{centroid},{spread},{flatness},{noiseness},{rolloff},{crest},{decrease},{entropy}"; } //Write label here TODO foreach (var inst in mfccVectors) { for (var i = 0; i < mfcc_no; i++) { avg_vec_mfcc[i] += inst[i]; } } foreach (var inst in tdVectors) { for (var i = 0; i < 4; i++) { avg_vec_td[i] += inst[i]; } } for (var i = 0; i < mfcc_no; i++) { avg_vec_mfcc[i] /= mfccVectors.Count; } for (var i = 0; i < 4; i++) { avg_vec_td[i] /= tdVectors.Count; } // Write MFCCs feature_string += String.Join(",", avg_vec_mfcc); feature_string += ","; feature_string += String.Join(",", avg_vec_td); //Write Spectral features as well feature_string += ","; feature_string += specFeatures; writer.WriteLine(feature_string); var file_name = new DirectoryInfo(filename).Name; Console.WriteLine($"{file_name}"); } } } Console.WriteLine($"DONE"); Console.ReadLine(); }