//Identify button opens the file explorer to choose a pre existing audio file or recorded sound to be identified private void btnIdentify_Click(object sender, EventArgs e) { ClosestMatch User = new ClosestMatch(); if (sequence != null && RecordRadio.Checked == false) { var watch = Stopwatch.StartNew(); User = FileOperations.GetUserName(sequence, signal, WithPruningRadioBTN.Checked); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Console.WriteLine("Elapsed Milliseconds = " + elapsedMs); MessageBox.Show("Username: "******"\nWith Minimum Difference: " + User.MinimumDistance.ToString()); } else if (SavedRadio.Checked) { OpenFileDialog open = new OpenFileDialog(); if (open.ShowDialog() == DialogResult.OK) { isRecorded = false; path = open.FileName; //Open the selected audio file signal = AudioOperations.OpenAudioFile(path); sequence = AudioOperations.ExtractFeatures(ref signal); var watch = Stopwatch.StartNew(); User = FileOperations.GetUserName(sequence, signal, WithPruningRadioBTN.Checked); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Console.WriteLine("Elapsed Milliseconds = " + elapsedMs); MessageBox.Show("Username: "******"\nWith Minimum Difference: " + User.MinimumDistance.ToString()); } } //Dev: Omar Moataz Abdel-Wahed Attia else { if (isRecorded) { InitializeDecoder(); //Initializes a decoder to get the value of the recorded stream. AudioSignal signal = new AudioSignal(); //Signal sent to Feature extraction function. signal.data = new double[this.decoder.frames]; //Reserve space for double array that will be filled later. signal.sampleRate = this.decoder.GetTempSignal().SampleRate; //TempSignal has the double array I need to extract features, Check function Decoder::getWholeSignal() for more explanation. this.decoder.GetTempSignal().CopyTo(signal.data); //Copies the values of the signal to an object "signal" of type AudioSignal which is sent to feature extraction. sequence = AudioOperations.ExtractFeatures(ref signal); //Get name of user that has the closest match. var watch = Stopwatch.StartNew(); User = FileOperations.GetUserName(sequence, signal, WithPruningRadioBTN.Checked); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Console.WriteLine("Elapsed Milliseconds = " + elapsedMs); MessageBox.Show("Username: "******"\nWith Minimum Difference: " + User.MinimumDistance.ToString()); } else { MessageBox.Show("Please record your voice first!"); //In case the user tries to identify without recording any sound. } } sequence = null; updateButtons(); }
//====================================================== /* Dev: Omar Moataz Abdel-Wahed Attia Last Edit: 12/8/2015 To understand the code in function GetUserName, you need to understand the file structure I'm looping over. The file will contain 13 lines which represent a Frame (0-12) (Each Column is a frame) on the 14th line, it will contain the name of the person that's tied to the previous sequence. */ //====================================================== public static ClosestMatch GetUserName(Sequence sequence, AudioSignal signal, bool pruned) { ClosestMatch User = new ClosestMatch(); //Opening the file. using (StreamReader Reader = new StreamReader("savedSequences.txt")) { //Initializing a new sequence. Sequence ToBeCompared = new Sequence(); //This line string contains every line I go through in the file string Line; //Holds the value of the current frame int Index = 0; bool flag = true, Updated = false; //Variables used in lowerbounding double FirstElement = 0, LastElement = 0, MaxElement = 0, MinElement = 0; while ((Line = Reader.ReadLine()) != null) { if (Index == 13) { double TrueDistance; string[] Temp = Line.Split(' '); /*Just a string array that holds the values I'll take into FirstElement, LastElement, MinElement and MaxElement.*/ FirstElement = double.Parse(Temp[0]); LastElement = double.Parse(Temp[1]); MinElement = double.Parse(Temp[2]); MaxElement = double.Parse(Temp[3]); if (pruned) { double LowerBoundDistance = DynamicTimeWarpingOperations.LowerBound_Kim(signal, FirstElement, LastElement, MinElement, MaxElement); if (LowerBoundDistance > User.MinimumDistance) goto skip; TrueDistance = DynamicTimeWarpingOperations.Pruned_DTW_Distance(ToBeCompared, sequence); } else { TrueDistance = DynamicTimeWarpingOperations.DTW_Distance(ToBeCompared, sequence); } //Here I compare the two Distances together to see if I need to update the minimum or not. if (TrueDistance < User.MinimumDistance) { //Here I update the minimum distance between two values. User.MinimumDistance = TrueDistance; Updated = true; } skip: //This is a reinitialization just to clear out old values from the previous iteration flag = true; ToBeCompared = new Sequence(); } else if(Index == 14) { if (Updated) { //I update the name of the person to line because on the 13th index line, it'll have the name of the person. User.Username = Line.Substring(9, Line.Length - 9); } Updated = false; //resetting the update value. Index = -1; //So, it goes back to 0 when the loop continues. } else { string[] ExtractedStringsFromLine = Line.Split('|'); if (flag == true) { ToBeCompared.Frames = new MFCCFrame[ExtractedStringsFromLine.Length - 1]; } //Here I split all the values from every line to an array of Strings. for (int i = 0; i < ExtractedStringsFromLine.Length - 1; i++) { if (flag == true) { ToBeCompared.Frames[i] = new MFCCFrame(); } ToBeCompared.Frames[i].Features[Index] = double.Parse(ExtractedStringsFromLine[i]); } flag = false; } //I increment the index of the 2D array for the next iteration through the file. ++Index; } } //I return type ClosestMatch. return User; }