以下是我的理解,不保证绝对正确
1、wav出来的数据都是实部的数据,虚部就是0
2、FFT的输入数据一定要是2的N次方,不足的部分用0补足
算法不难
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.Generic;
using System.Threading;
namespace FFT
{
public partial class Form1 : Form
{
const bool leftStatus = false;
const int dataLength = 128; //输入数据量
double[] rDataIn = new double[dataLength]; //输入实部
double[] iDataIn = new double[dataLength]; //输入虚部
double[] rDataOut = new double[dataLength];
double[] iDataOut = new double[dataLength];
public Form1()
{
InitializeComponent();
new Thread(new ThreadStart(() =>
{
this.Invoke(new MethodInvoker(() => { label1.Text = leftStatus ? "左声道" : "右声道"; }));
List<double> list = new List<double>();
StreamReader sr = new StreamReader("data.txt", Encoding.Default);
int m = 0;
while (!sr.EndOfStream)
{
if (leftStatus)
{
if (m % 2 == 0)
list.Add(double.Parse(sr.ReadLine()));
}
else
{
if (m % 2 != 0)
list.Add(double.Parse(sr.ReadLine()));
}
m++;
}
int p = 0;
for (int i = 0; i < list.Count; i++)
{
if (i % (list.Count / dataLength) == 0)
{
rDataIn[p] = list[i];
iDataIn[p] = 0;
p++;
if (p >= dataLength)
{
break;
}
}
}
sr.Close();
FFT(ref rDataIn, ref iDataIn, ref rDataOut, ref iDataOut);
Bitmap bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bitmap);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.DrawLine(new Pen(Color.Black, 5), new Point(20, 20), new Point(20, 540));
g.DrawLine(new Pen(Color.Black, 5), new Point(20, 290), new Point(1600, 290));
int k = 1550 / dataLength;
Point prv = new Point();
Point next = new Point();
for (int i = 0; i < dataLength - 1; i++)
{
if (i == 0)
{
prv = new Point(30 + i * k, 290 + (int)(rDataOut[i] * 100));
}
next = new Point(30 + (i + 1) * k, 290 + (int)(rDataOut[i + 1] * 250));
g.DrawLine(new Pen(Color.Green, 1), prv, next);
prv = next;
}
this.pictureBox1.Image = bitmap;
})).Start();
}
private void FFT(ref double[] rIn, ref double[] iIn, ref double[] rOut, ref double[] iOut)
{
int length = rIn.Length;
if (length == 1)
{
rOut = rIn;
iOut = iIn;
return;
}
length = length / 2;
double[] rEvenIn = new double[length];
double[] iEvenIn = new double[length];
double[] rOddIn = new double[length];
double[] iOddIn = new double[length];
double[] rEvenOut = new double[length];
double[] iEvenOut = new double[length];
double[] rOddOut = new double[length];
double[] iOddOut = new double[length];
for (int i = 0; i < length; i++) //奇偶位分开
{
rEvenIn[i] = rIn[i * 2];
iEvenIn[i] = iIn[i * 2];
rOddIn[i] = rIn[i * 2 + 1];
iOddIn[i] = iIn[i * 2 + 1];
}
FFT(ref rEvenIn, ref iEvenIn, ref rEvenOut, ref iEvenOut); //偶位迭代
FFT(ref rOddIn, ref iOddIn, ref rOddOut, ref iOddOut); //奇位迭代
double rData, iData;
for (int i = 0; i < length; i++)
{
rData = Math.Cos(2 * Math.PI / (length * 2) * i);
iData = -Math.Sin(2 * Math.PI / (length * 2) * i);
rOut[i] = rEvenOut[i] + rOddOut[i] * rData - iOddOut[i] * iData;
iOut[i] = iEvenOut[i] + iOddOut[i] * rData + rOddOut[i] * iData;
rOut[i + length] = rEvenOut[i] - rOddOut[i] * rData + iOddOut[i] * iData;
iOut[i + length] = iEvenOut[i] - iOddOut[i] * rData - rOddOut[i] * iData;
}
rEvenIn = iEvenIn = rOddIn = iOddIn = rEvenOut = iEvenOut = rOddOut = iOddOut = null;
}
private void Form1_Resize(object sender, EventArgs e)
{
this.Width = 1650;
this.Height = 600;
}
}
}