C++ 从fft重构信号
Im从fft得到的幅度、频率和相位重构信号。在我做了fft之后,我从这些fft数据中提取了它的一些频率并重建了时间线信号。我知道IFFT是为了这个,但我不想使用IFFT。 重建看起来不错,但两个信号之间有一定的时间差。此图显示了此问题。黑色是原始信号,红色是重建信号。 如果我知道的正确,频率bin t的振幅是C++ 从fft重构信号,c++,fft,C++,Fft,Im从fft得到的幅度、频率和相位重构信号。在我做了fft之后,我从这些fft数据中提取了它的一些频率并重建了时间线信号。我知道IFFT是为了这个,但我不想使用IFFT。 重建看起来不错,但两个信号之间有一定的时间差。此图显示了此问题。黑色是原始信号,红色是重建信号。 如果我知道的正确,频率bin t的振幅是sqrt(real[t]*real[t]+imag[t]*imag[t],相位是atan2(imag[t],real[t])。 所以,我使用公式振幅*cos(2*π*x/频率+相位)作为频
sqrt(real[t]*real[t]+imag[t]*imag[t]
,相位是atan2(imag[t],real[t])
。
所以,我使用公式振幅*cos(2*π*x/频率+相位)
作为频率单元。我将这些再生波相加。据我所知,这将生成与原始信号匹配的完整信号。但它总是与原始信号有一定的时间延迟。是的,我认为这是关于相位的,但这很容易计算,而且工作正常。如果它有误差,重建的信号在形状上就不适合它的原始信号 这是生成余弦波的代码。我从sin(x+π/2)生成余弦波。
std::矢量编码(
恒倍频,
常数双振幅,
常数(双偏移相位)
{
常数双pi=3.1415926535897932384626;
常数int N=44100;//1秒波长
std::向量s(N);
常数双波长=1.0*N/频率;
常数双单位长度=2*pi/波长;
对于(int i=0;i非常正常。您正在进行逐帧变换。这意味着FFT帧是在一个时间帧后生成的。当进行反向变换时,会产生相反的效果:FFT帧解码后时间帧开始。无需重新发布您的问题,您应该编辑原始问题以保留讨论“我知道IFFT是为了这个”-这是唯一能让你恢复原音的转换。但为什么不合理地不喜欢IFFT?出于测试目的。这是声音信号,我正试图从原始信号的主要频率恢复原音。如果我同时播放每个频率,它必须发出相同的声音吗?对不起,我不明白“频率”与正弦波相关联,正弦波在时间上是不局部化的,所以你不能真正谈论“同一时间”。是的,你说得对。我只是想模拟“同步”声音播放环境。将每个频率转换成声音信号并立即播放。这就是我的意思。这似乎是正确的。重建的信号图符合其原始信号。但这越来越令人困惑(你能解释一下为什么会发生这种情况吗?据我所知,傅里叶级数只是将信号输入到它的频域中。时间框架是如何涉及的?不要混淆了。傅里叶级数是一个相关的东西,而不是FFT。傅里叶级数是在任何时刻定义的周期信号的数学构造。你有一个离散的te signa,FFT在这方面起作用。也就是说,你的输入声音有多大(在样本中),你传递给FFT的样本有多少?它们可能不一样。
std::vector<short> encodeSineWavePCM(
const double frequency,
const double amplitude,
const double offSetPhase)
{
const double pi = 3.1415926535897932384626;
const int N = 44100; // 1 sec length wave
std::vector<short> s(N);
const double wavelength = 1.0 * N / frequency;
const double unitlength = 2 * pi / wavelength;
for (int i = 0; i<N; i ++) {
double val = sin(offSetPhase + i * unitlength);
val *= amplitude;
s[i] = (short)val;
}
return s;
}