// data为输入和输出的数据,N为长度
bool CFFT::Forward(complex *const Data, const unsigned int N)
{
if (!Data || N < 1 || N & (N - 1))
return false
// 排序
Rearrange(Data, N)
// FFT计算:const bool Inverse = false
Perform(Data, N)
return true
}
2.IFFT:
// Scale 为是否缩放
bool CFFT::Inverse(complex *const Data, const unsigned int N,
const bool Scale /* = true */)
{
if (!Data || N < 1 || N & (N - 1))
return false
// 排序
Rearrange(Data, N)
// FFT计算,ture表示是逆运算
Perform(Data, N, true)
// 对结果进行缩放
if (Scale)
CFFT::Scale(Data, N)
return true
}
3.排序:
void CFFT::Rearrange(complex *const Data, const unsigned int N)
{
// Swap position
unsigned int Target = 0
// Process all positions of input signal
for (unsigned int Position = 0 Position < N ++Position)
{
// Only for not yet swapped entries
if (Target > Position)
{
// Swap entries
const complex Temp(Data[Target])
Data[Target] = Data[Position]
Data[Position] = Temp
}
// Bit mask
unsigned int Mask = N
// While bit is set
while (Target & (Mask >>= 1))
// Drop bit
Target &= ~Mask
// The current bit is 0 - set it
Target |= Mask
}
}
4.FFT计算:
void CFFT::Perform(complex *const Data, const unsigned int N,
const bool Inverse /* = false */)
{
const double pi = Inverse ? 3.14159265358979323846 : -3.14159265358979323846
// Iteration through dyads, quadruples, octads and so on...
for (unsigned int Step = 1 Step < N Step <<= 1)
{
// Jump to the next entry of the same transform factor
const unsigned int Jump = Step << 1
// Angle increment
const double delta = pi / double(Step)
// Auxiliary sin(delta / 2)
const double Sine = sin(delta * .5)
// Multiplier for trigonometric recurrence
const complex Multiplier(-2. * Sine * Sine, sin(delta))
// Start value for transform factor, fi = 0
complex Factor(1.)
// Iteration through groups of different transform factor
for (unsigned int Group = 0 Group < Step ++Group)
{
// Iteration within group
for (unsigned int Pair = Group Pair < N Pair += Jump)
{
// Match position
const unsigned int Match = Pair + Step
// Second term of two-point transform
const complex Product(Factor * Data[Match])
// Transform for fi + pi
Data[Match] = Data[Pair] - Product
// Transform for fi
Data[Pair] += Product
}
// Successive transform factor via trigonometric recurrence
Factor = Multiplier * Factor + Factor
}
}
}
5.缩放:
void CFFT::Scale(complex *const Data, const unsigned int N)
{
const double Factor = 1. / double(N)
// Scale all data entries
for (unsigned int Position = 0 Position < N ++Position)
Data[Position] *= Factor
}
采样不需要dsp去采,外面的时钟会触发AD进行采样,如果采样速度高,则先存储到fifo,fifo半满后,通知dsp读取fifo一半容量的数据,dsp对这些数据处理后再输出的输出fifo。fft变换后的数据是频谱,表示了各个频率分量的大小。如果采样速率不高,没有fifo,则由dma控制器去读取数据到dsp内部ram,通常会采用双缓冲机制,开辟两个输入buffer,两个输出buffer,cpu通常不用自己去读ad转换器采用的数据,这些体力活让dma干就行,cpu只用负责处理数据。