用于语音验证的C#中的互相关和FFT

时间:2016-10-19 23:39:09

标签: c# signal-processing fft naudio cross-correlation

这与其他问题类似,但不是重复问题。但是,我仍然无法得到正确的结果。

我基本上尝试记录两个Wav文件(1 - 基本文件2 -Temp文件),然后将其转换为字节并传递给Aforge FFT,然后传递相关性。

很少有困惑。当我录制文件时,我正在使用16位的44100 Khz。因此我相信它将返回每秒44100字节。 FFT接受2的幂的字节,所以我一次传递16384个字节并将其存储到父数组,然后我使用Cross Corelation Alogorithm来查看相似性,它只返回0.30一直。我再次不确定我是否采取了正确的方式。

我附上了示例代码和相关参考资料。

        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);

        }

参考资料 - 存储Wav文件https://stackoverflow.com/a/17983876/4124478

阅读Wav文件https://stackoverflow.com/a/11162668/4124478

互相关https://stackoverflow.com/a/27277120/4124478

FFT代码https://stackoverflow.com/a/170413/4124478

更新

我正在存储具有相同字节的示例文件,因为它很容易比较。录音将在4秒后自动停止。

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();

                }

            }
        }

另外,我无法发送所有字节,因为总长度不是2的幂。因此,我一次只发送2个字节,通常我得到0.60相似度。

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);
}

我不确定我是否通过将“幅度”和“平方幅度”相加来存储正确的输出值。

0 个答案:

没有答案