//DTW without pruning public static double DTW_Distance(Sequence sequence1, Sequence sequence2) { int numberOfFrames_Sequence1 = sequence1.Frames.Count(); int numberOfFrames_Sequence2 = sequence2.Frames.Count(); double[,] DTW = new double[3, numberOfFrames_Sequence2 + 1]; for (int i = 0; i <= numberOfFrames_Sequence2; i++) { DTW[0, i] = DTW[1, i] = DTW[2, i] = double.MaxValue; } DTW[0, 0] = 0; //Applying dimension compression to DTW array for (int i = 2; i <= numberOfFrames_Sequence1 + 1; i++) { for (int j = 1; j <= numberOfFrames_Sequence2; j++) { double cost = distance(sequence1.Frames[i - 2], sequence2.Frames[j - 1]); DTW[i % 3, j] = cost + Math.Min(DTW[i % 3, j - 1], //horizontal, stretching Math.Min(DTW[(i + 1) % 3, j - 1], //diagnoal, aligning DTW[(i + 2) % 3, j - 1])); //far diagonal, shrinking } } return DTW[(numberOfFrames_Sequence1 + 1) % 3, numberOfFrames_Sequence2]; }
public MainForm() { InitializeComponent(); // Configure the wavechart chart.SimpleMode = true; chart.AddWaveform("wave", Color.Green, 1, false); updateButtons(); List<User> listOfUsers = TestcaseLoader.LoadTestcase1Testing("E:\\Complete SpeakerID Dataset\\TestingList.txt"); foreach (User user in listOfUsers) { int counter = 0, counter1 = 0; foreach (AudioSignal signal in user.UserTemplates) { AudioSignal signal_ = signal; sequence = AudioOperations.ExtractFeatures(ref signal_); ClosestMatch match = FileOperations.GetUserName(sequence, signal, true); ClosestMatch match1 = FileOperations.GetUserName(sequence, signal, false); Console.WriteLine(user.UserName + " : " + match.Username + ", " + match1.Username); if (user.UserName == match.Username) counter++; if (user.UserName == match1.Username) counter1++; } Console.WriteLine("====== " + counter + " out of " + user.UserTemplates.Count + " with pruning."); Console.WriteLine("====== " + counter1 + " out of " + user.UserTemplates.Count + " without pruning."); } Console.WriteLine("Done"); }
public static Sequence ExtractFeatures(double[] pSignal, int samplingRate) { Sequence sequence = new Sequence(); double[,] mfcc = MATLABMFCCfunction(pSignal, samplingRate); int numOfFrames = mfcc.GetLength(1); int numOfCoefficients = mfcc.GetLength(0); Debug.Assert(numOfCoefficients == 13); sequence.Frames = new MFCCFrame[numOfFrames]; for (int i = 0; i < numOfFrames; i++) { sequence.Frames[i] = new MFCCFrame(); for (int j = 0; j < numOfCoefficients; j++) { sequence.Frames[i].Features[j] = mfcc[j, i]; } } return sequence; }
public static void SaveSequenceInDatabase(Sequence toBeSavedSequence, string username, AudioSignal signal) { //UPDATE //you should save the four values in the last row before the username, with the order (first, last, min, max) respectively FileStream SavingStream = new FileStream("savedSequences.txt", FileMode.Append); StreamWriter Saving = new StreamWriter(SavingStream); double TempFeature = 0f; StringBuilder FramesRow = new StringBuilder(); int size = signal.data.Length; double maxElement = double.MinValue, minElement = double.MaxValue, firstElement, lastElement; for (int i = 0; i < 13; i++) { for (int j = 0; j < toBeSavedSequence.Frames.Length; j++) { TempFeature = toBeSavedSequence.Frames[j].Features[i]; FramesRow.Append(TempFeature.ToString() + "|"); } Saving.WriteLine(FramesRow); FramesRow.Clear(); //clear it to start a new row (VIP) } firstElement = signal.data[0]; lastElement = signal.data[size - 1]; for (int i = 0; i < size; i++) { maxElement = Math.Max(maxElement, signal.data[i]); minElement = Math.Min(minElement, signal.data[i]); } // UPDATE: On 26/12 @ 6:50 - Writing the 4 values into the file Saving.WriteLine(firstElement + " " + lastElement + " " + minElement + " " + maxElement); Saving.WriteLine("Username:" + username); Saving.Close(); }
//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(); }
public void openToolStripMenuItem_Click(object sender, EventArgs e) { 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); updateButtons(); } }
private void saveFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e) { if (this.encoder != null) { Stream fileStream = saveFileDialog1.OpenFile(); this.encoder.Save(fileStream); path = saveFileDialog1.FileName; signal = AudioOperations.OpenAudioFile(path); sequence = AudioOperations.ExtractFeatures(ref signal); } }
//====================================================== /* 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; }
public AddUser(Sequence sequence_, AudioSignal signal_) { sequence = sequence_; signal = signal_; InitializeComponent(); }