private static void Indexing(DataBase dataBase, byte[] audio)
        {
            Console.WriteLine("Matching the song...");
            dataBase.UseFilter = false;
            TimeInterval timeInterval = new TimeInterval();
            int id = dataBase.GetBestHit(audio, 16);
            double intervalInSecond = timeInterval.GetDurationInSecond();

            Console.WriteLine("--------------------");
            Console.Write("Final Match ({0}s):\t", intervalInSecond);
            if (id < 0)
                Console.WriteLine("No match!");
            else
                Console.WriteLine(dataBase.GetNameByID(id));
            Console.WriteLine("--------------------");
        }
        public void SaveInBinary(string fileName)
        {
            Console.WriteLine("Saving to binary file: {0}", fileName);
            try
            {
                TimeInterval ti = new TimeInterval();
                using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate))
                {
                    BinaryWriter bw = new BinaryWriter(fs);

                    bw.Write(BINARY_HEADER);
                    bw.Write(songNames.Count);
                    foreach (string name in songNames)
                    {
                        bw.Write(name);
                    }

                    bw.Write(hashMap.Count);
                    Dictionary<long, List<DataPoint>>.Enumerator en = hashMap.GetEnumerator();
                    while (en.MoveNext())
                    {
                        KeyValuePair<long, List<DataPoint>> current = en.Current;
                        bw.Write(current.Key);
                        bw.Write(current.Value.Count);
                        foreach (DataPoint dataPoint in current.Value)
                        {
                            bw.Write(dataPoint.Time);
                            bw.Write(dataPoint.SongID);
                        }
                    }
                    bw.Flush();
                }
                Console.WriteLine("Done. {0}s", ti.GetDurationInSecond());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        public void Save(string fileName)
        {
            Console.WriteLine("Saving to text file: {0}", fileName);
            try
            {
                TimeInterval ti = new TimeInterval();
                using (StreamWriter sw = new StreamWriter(fileName, false))
                {
                    sw.WriteLine(songNames.Count);
                    foreach (string name in songNames)
                    {
                        sw.WriteLine(name);
                    }

                    sw.WriteLine(hashMap.Count);
                    Dictionary<long, List<DataPoint>>.Enumerator en = hashMap.GetEnumerator();
                    while (en.MoveNext())
                    {
                        KeyValuePair<long, List<DataPoint>> current = en.Current;
                        sw.Write(current.Key);
                        foreach (DataPoint dataPoint in current.Value)
                        {
                            sw.Write(string.Format("\t{0},{1}", dataPoint.Time, dataPoint.SongID));
                        }
                        sw.WriteLine();
                    }
                    sw.Flush();
                }
                Console.WriteLine("Done. {0}s", ti.GetDurationInSecond());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        public void LoadFromBinary(string fileName)
        {
            Console.WriteLine("Loading data base from binary file: {0} ...", fileName);
            try
            {
                TimeInterval loadTimeInterval = new TimeInterval();
                using (FileStream fr = new FileStream(fileName, FileMode.Open))
                {
                    BinaryReader br = new BinaryReader(fr);
                    songNames.Clear();

                    int header = br.ReadInt32();
                    if (header != BINARY_HEADER)
                    {
                        throw new InvalidDataException("Invalid binary index file!");
                    }

                    int nameCount = br.ReadInt32();
                    for (int i = 0; i < nameCount; i++)
                    {
                        string name = br.ReadString();
                        songNames.Add(name);
                        if (CheckDuplicate)
                            songNameSet.Add(name);
                    }

                    hashMap.Clear();
                    int hashCount = br.ReadInt32();
                    for (int i = 0; i < hashCount; i++)
                    {
                        long key = br.ReadInt64();
                        int count = br.ReadInt32();

                        List<DataPoint> pointList = new List<DataPoint>(count);
                        for (int j = 0; j < count; j++)
                        {
                            short time = br.ReadInt16();
                            short songID = br.ReadInt16();
                            DataPoint dataPoint = new DataPoint(time, songID);
                            pointList.Add(dataPoint);
                        }

                        hashMap.Add(key, pointList);
                    }
                }
                Console.WriteLine("Done! {0}s", loadTimeInterval.GetDurationInSecond());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
        }
        public void Load(string fileName)
        {
            Console.WriteLine("Loading data base from file: {0} ...", fileName);
            try
            {
                TimeInterval loadTimeInterval = new TimeInterval();
                using (StreamReader sr = new StreamReader(fileName))
                {
                    songNames.Clear();
                    int nameCount = int.Parse(sr.ReadLine());
                    for (int i = 0; i < nameCount; i++)
                    {
                        string name = sr.ReadLine();
                        songNames.Add(name);
                        if (CheckDuplicate)
                            songNameSet.Add(name);
                    }

                    hashMap.Clear();
                    int hashCount = int.Parse(sr.ReadLine());
                    for (int i = 0; i < hashCount; i++)
                    {
                        string record = sr.ReadLine();
                        string[] items = record.Split('\t');

                        long hash = long.Parse(items[0]);
                        List<DataPoint> pointList = new List<DataPoint>();
                        for (int j = 1; j < items.Length; j++)
                        {
                            string[] values = items[j].Split(',');
                            short time = short.Parse(values[0]);
                            short songID = short.Parse(values[1]);
                            DataPoint dataPoint = new DataPoint(time, songID);
                            pointList.Add(dataPoint);
                        }

                        hashMap.Add(hash, pointList);
                    }
                }
                Console.WriteLine("Done! {0}s", loadTimeInterval.GetDurationInSecond());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        public static void SimpleTest(string indexFile, IHashMaker hashMaker, bool bQuiet)
        {
            bool bTextFile = IsTextFile(indexFile);
            ImprovedDataBase dataBase = new ImprovedDataBase(hashMaker);
            if (bTextFile)
            {
                //dataBase.Load(indexFile);
            }
            else
                dataBase.LoadFromBinary(indexFile);
            dataBase.Quiet = bQuiet;
            int seconds = 10;

            while (true)
            {
                Console.WriteLine("Press any key to identify a new song, press ESC to exit.\n");
                ConsoleKeyInfo keyInfo = Console.ReadKey();
                if (keyInfo.Key == ConsoleKey.Escape)
                    break;

                byte[] audio = null;
                Console.WriteLine("Start recording audio from mic ...", seconds);
                MicRecorder recorder = new MicRecorder();
                recorder.Seconds = seconds;
                recorder.RequestStop = false;
                recorder.RecStart();

                audio = recorder.GetAudioData();
                Console.WriteLine();
                //Console.WriteLine("Length of audio data is {0}.", audio.Length);

                dataBase.UseFilter = false;
                TimeInterval timeInterval = new TimeInterval();
                int id = dataBase.GetBestHit(audio, 16);
                double intervalInSecond = timeInterval.GetDurationInSecond();

                Console.WriteLine("--------------------");
                Console.Write("Final Match ({0}s):\t", intervalInSecond);
                if (id < 0)
                    Console.WriteLine("No match!");
                else
                    Console.WriteLine(dataBase.GetNameByID(id));
                Console.WriteLine("--------------------");

                //dataBase.UseFilter = true;
                //timeInterval.Reset();
                //id = dataBase.GetBestHit(audio, 16);
                //intervalInSecond = timeInterval.GetDurationInSecond();

                //Console.WriteLine("--------------------");
                //Console.Write("Final Match ({0}s):\t", intervalInSecond);
                //if (id < 0)
                //    Console.WriteLine("No match!");
                //else
                //    Console.WriteLine(dataBase.GetNameByID(id));
                //Console.WriteLine("--------------------");
            }
        }