Cross Correlation and FFT in C# for Voice Authentication

依然范特西╮ 提交于 2019-12-02 21:21:04

问题


This is similar question to the other questions but not a duplicate one. However, I am still not able to get the correct result.

I am basically trying to record two Wav files (1 - Base File 2 -Temp File) and then convert that to byte and pass to Aforge FFT and then the Correlation.

There are few confusion. When I record the file I am ussing 44100 Khz with 16 bit. Therefore I believe it will return 44100 bytes per second. FFT accepts bytes in power of 2, So I am passing 16384 bytes at a time and storing that to the parent array and then I am using the Cross Corelation Alogorithm to view the similarity and it only returns around 0.30 all the time. I am again not too sure whether I have followed the right way.

I am attaching the sample code and relative references.

        static void Start()
        {

            waveSource = new WaveInEvent();
            //waveSource.WaveFormat = new WaveFormat(44100, 1);//44khz rate
            waveSource.WaveFormat = new WaveFormat(44100, 16, 1);


            waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
            waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);
            Random rnd = new Random();

            int card = rnd.Next(52);
            waveFile = new WaveFileWriter(@Environment.CurrentDirectory.ToString() + @"\Recording" + card.ToString() + "0001.wav", waveSource.WaveFormat);

            waveSource.StartRecording();
        }

        private static void FileCompare(string file1, string file2)
        {
            double[] r1;


             // readWav(file1, out permanent, out r);
              //readWav(file2, out temp, out l);
               openWav(file1, out permanent, out r1);
               openWav(file2, out temp, out r1);

              double[] odoubledata = new double[163840];
              double[] odoubledata1 = new double[163840];
              int n = 0;
              int k = 0;
            for (int lk = 0; lk <10; lk++)
            {

             //   if (lk != 0   || lk != 9)
                {
                    AForge.Math.Complex[] c = new AForge.Math.Complex[16384];
                    for (int i = 0; i < 16384; i++)
                    {


                        c[i].Re = permanent[i];
                        c[i].Im = 0;

                    }

                    AForge.Math.Complex[] c1 = new AForge.Math.Complex[16384];
                    for (int i = 0; i < 16384; i++)
                    {

                        c1[i].Re = temp[i];
                        c1[i].Im = 0;

                    }

                  FourierTransform.FFT(c, FourierTransform.Direction.Forward);
                    FourierTransform.FFT(c1, FourierTransform.Direction.Forward);
                    //   FourierTransform.DFT(c1, FourierTransform.Direction.Forward);
                    double[] doubledata = new double[c.Length];
                    double[] doubledata1 = new double[c1.Length];
                    for (int i = 0; i < c.Length; i++)
                    {
                        doubledata[i] = c[i].Re;
                        odoubledata[k] = c[i].Re;
                        k = k + 1;
                    }

                    for (int i = 0; i < c1.Length; i++)
                    {
                        doubledata1[i] = c1[i].Re ;
                        odoubledata1[n] = c1[i].Re;
                        n = n + 1;
                    }

                }


            }


            double temq2;
            int off;
            CalcCrossCorrelation(odoubledata, odoubledata1, out off, out temq2);
            Console.WriteLine("Similarity  " + temq2);

        }

References - Storing Wav File https://stackoverflow.com/a/17983876/4124478

Reading Wav File https://stackoverflow.com/a/11162668/4124478

Cross Correlation https://stackoverflow.com/a/27277120/4124478

FFT Code https://stackoverflow.com/a/170413/4124478

Update

I am storing the sample files with same bytes as it will be easy to compare. The recording will stop itself after 4 seconds.

static void Start()
        {

            waveSource = new WaveInEvent();
            //waveSource.WaveFormat = new WaveFormat(44100, 1);//44khz rate

            waveSource.WaveFormat = new WaveFormat(8192, 16, 1);

            waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
            waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);
            Random rnd = new Random();

            int card = rnd.Next(52);
            waveFile = new WaveFileWriter(@Environment.CurrentDirectory.ToString() + @"\Recording" + card.ToString() + "0001.wav", waveSource.WaveFormat);

            waveSource.StartRecording();
        }

static void waveSource_DataAvailable(object sender, WaveInEventArgs e)
        {
            if (waveFile != null)
            {
                waveFile.Write(e.Buffer, 0, e.BytesRecorded);
                int seconds = (int)(waveFile.Length / waveFile.WaveFormat.AverageBytesPerSecond);
                if (seconds > 4)
                {
                    waveFile.Flush();
                    Stop();

                }

            }
        }

Also, I was not able to send all bytes as the total length was not in power of 2. Therefore, I only send 2 bytes at a time and normally I get 0.60 similarity.

private static void FileCompare(string file1, string file2)
        {
            double[] l;
            double[] r;
            double[] r1;


            // readWav(file1, out permanent, out r);
            //  readWav(file2, out temp, out l);

            openWav(file1, out permanent, out r1);
            openWav(file2, out temp, out r1);

            double[] odoubledata = new double[41769];
            double[] odoubledata1 = new double[41769];

            Console.WriteLine("-------cross correlation--------");

            int n = 0;
            int k = 0;
            for (int i = 0; i < permanent.Length; i = i + 2)
            {

                Complex[] test1 = new Complex[2];
                test1[0].Re = permanent[n];
                test1[0].Im = 0;
                test1[1].Re = permanent[n + 1];
                test1[1].Im = 0;
                FourierTransform.FFT(test1, FourierTransform.Direction.Forward);
                odoubledata[n] = test1[0].Magnitude + test1[0].SquaredMagnitude;
                odoubledata[n + 1] = test1[1].Magnitude + test1[1].SquaredMagnitude;
                n = n + 1;
            }
            for (int i = 0; i < temp.Length; i = i + 2)
            {

                Complex[] test1 = new Complex[2];
                test1[0].Re = temp[k];
                test1[0].Im = 0;
                test1[1].Re = temp[k + 1];
                test1[1].Im = 0;
                FourierTransform.FFT(test1, FourierTransform.Direction.Forward);
                odoubledata1[k] = test1[0].Magnitude + test1[0].SquaredMagnitude;
                odoubledata1[k + 1] = test1[1].Magnitude + test1[1].SquaredMagnitude;
                k = k + 1;
            }
            double temwe2;
            int offs;
            CalcCrossCorrelation(odoubledata, odoubledata1, out offs, out temwe2);
            Console.WriteLine("Similarity Total together " + temwe2);
}

I am not sure whether I am storing correct output values by summing Magnitude and Squared Magnitude.

来源:https://stackoverflow.com/questions/40143221/cross-correlation-and-fft-in-c-sharp-for-voice-authentication

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!