Cross Correlation and FFT in C# for Voice Authentication
Asked Answered
S

0

0

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://mcmap.net/q/637716/-naudio-record-sound-from-microphone-then-save

Reading Wav File https://mcmap.net/q/433764/-how-to-read-the-data-in-a-wav-file-to-an-array

Cross Correlation https://mcmap.net/q/495861/-correlation-of-two-arrays-in-c

FFT Code https://mcmap.net/q/73008/-an-implementation-of-the-fast-fourier-transform-fft-in-c-closed

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.

Sickness answered 19/10, 2016 at 23:39 Comment(5)
44100kHz 16 bit (I assume mono) audio is 88200 bytes per second. I don't think it will really affect your cross correlation, though.Crispi
Yes, you are right. It is 88200 bytes per second. However, the question is still remained. What have I missed ?Sickness
I don't have an answer, hence the comment. I'm hoping someone else will chime inCrispi
Hey, do you have sample code for this?Rinee
can you please paste the body of this function? CalcCrossCorrelation(odoubledata, odoubledata1, out off, out temq2);Infiltrate

© 2022 - 2024 — McMap. All rights reserved.