Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 将快速傅里叶逆变换(ifft)更改为使用任意波形而不是正弦波来创建新信号_Matlab_Fft_Octave_Ifft - Fatal编程技术网

Matlab 将快速傅里叶逆变换(ifft)更改为使用任意波形而不是正弦波来创建新信号

Matlab 将快速傅里叶逆变换(ifft)更改为使用任意波形而不是正弦波来创建新信号,matlab,fft,octave,ifft,Matlab,Fft,Octave,Ifft,我知道,快速傅里叶逆变换(ifft)将从对信号进行fft获得的数据中得到的多个正弦波相加有没有一种方法可以使用一种新型的快速傅立叶逆变换(ifft)来创建一个信号,该逆变换使用任意波形,而不仅仅是正弦波? 我没有试图重新创建原始信号。我正在尝试使用一种新型的快速傅里叶逆变换(ifft)来创建一个新信号,该逆变换使用基于源信号fft计算的(频率、振幅、相位)数据的给定任意波形。 任意波形是一个采样信号,将取代fft中使用的正弦波的一个周期。也就是说,信号将根据fft给出的值进行缩放、重复和移位 请

我知道,快速傅里叶逆变换(ifft)将从对信号进行fft获得的数据中得到的多个正弦波相加有没有一种方法可以使用一种新型的快速傅立叶逆变换(ifft)来创建一个信号,该逆变换使用任意波形,而不仅仅是正弦波?

我没有试图重新创建原始信号。我正在尝试使用一种新型的快速傅里叶逆变换(ifft)来创建一个新信号,该逆变换使用基于源信号fft计算的(频率、振幅、相位)数据的给定任意波形。

任意波形是一个采样信号,将取代fft中使用的正弦波的一个周期。也就是说,信号将根据fft给出的值进行缩放、重复和移位

请参阅下面的简单示例:我将应用FFT的信号是人类音频信号,大约60秒长,采样数为44100个(大型阵列),因此我试图看看是否可以以某种方式使用/更改ifft命令,使用/基于任意波形创建新信号。

PS:我正在使用Octave 4.0,它类似于Matlab,用于创建新信号的任意波形信号将被更改以创建不同的信号

clear all,clf reset, clc,tic

fs=44100 % Sampling frequency
len_of_sig=2; %length of signal in seconds
t=linspace(0,2*pi*len_of_sig,fs*len_of_sig);
afp=[.5,2.43,pi/9;.3,3,pi/2;.3,4.3,pi/3];  %represents Amplitude,frequency,phase data array

%1 create source signal
ya=0;
for zz=1:size(afp,1)
  ya = ya+afp(zz,1)*sin(afp(zz,2)*t+afp(zz,3));
end

%2 create source frequency domain data
ya_fft = fft(ya);

%3 rebuild original source signal
mag = abs(ya_fft);
phase = unwrap(angle(ya_fft));
ya_newifft=ifft(mag.*exp(i*phase));
ifft_sig_combined_L1=ifft(mag.*exp(i*phase),length(ya_newifft)); 

%4 %%%-----begin create arbitrary waveform to use ---- 
gauss = @(t, t0, g) exp(-((t-t0)/g).^2); % a simple gaussian

t_arbitrary=0:1:44100; % sampling
t_arbitrary_1 = 10000; % pulses peak positions (s)
t_arbitrary_2 = 30000; % pulses peak positions (s)

g = 2000; % pulses width (at 1/e^2) (s)

lilly = gauss(t_arbitrary, t_arbitrary_1, g) - (.57*gauss(t_arbitrary, t_arbitrary_2, g)); %different amplitude peaks
%%%%-----End arbitrary waveform to use---- 

%5 plot
t_sec=t./(2*pi); %converts time in radians to seconds
t_arbitrary_sec=t_arbitrary./length(lilly); %converts time in radians to seconds

subplot(4,1,1);
plot(t_sec,ya,'r')
title('1) source signal')

subplot(4,1,2);
plot(t_sec,ifft_sig_combined_L1)
title('2) rebuilt source signal using ifft')

subplot(4,1,3);
plot(t_arbitrary_sec,lilly,'r')
title('3) arbitrary waveform used to create new signal')

下面添加了一个带有简单信号的工作流程图,看看这是否能更好地解释问题:

Section 1) The audio signal is read into an array
Section 2) FFT is done on the signal
Section 3 Red) Normally Inverse FFT uses sin waves to rebuild the signal see signal in red
Section 3 Blue) I want to use an arbitrary signal wave instead to rebuild the signal using the FFT data calculated in (Section 2)
Section 4) New signals created using a new type of Inverse FFT (Section 3).
Please note the new type of Inverse FFT final signal (in blue ) must use the FFT data taken from the original signal.
The signal Sample rate tested should be 44100 and the length of the signal in seconds should be 57.3 seconds long.  I use these numbers to test that the array can handle large amounts and that the code can handle non even numbers in seconds.

IFFT只是实现IDFT的一种方式。IDFT只是孔径中整数周期正弦波形的加权和

如果需要,可以采用几乎任何DFT或IDFT算法或源代码,并使用波形合成所需的任何其他函数替换sin()函数。您甚至可以对不同的频率使用不同的波形,或者根据需要将合成频率更改为孔径中的非整数周期。

快速傅里叶变换依赖于正弦函数的特殊性质,它允许人们在时域和频域之间移动,计算成本(O(n.log(n)))比任意波形(O(n^2))低得多。如果将基波从正弦波更改为其他波形,通常情况下,无法再获得FFT的计算优势

在您的情况下,听起来您可能希望生成与原始信号具有相同频谱的信号,但不一定在时域中具有相同的包络。正如我认为您已经在代码中实现的那样,最简单的方法是改变FFT输出中每个频率单元的相位,然后进行逆FFT。这将生成一个时域信号,该信号与您的输入信号具有完全不同的外观,但在每个频率单元中具有相同的功率


您可能需要记住的一个微妙之处是如何改变相位,使输出信号保持实值,而不是涉及复数。你可以把傅里叶变换看作是产生一组正负频率。对于实值信号,相应的正频率和负频率必须具有彼此复共轭的振幅。假设您的输入信号是实值的,您的FFT将已经具有此属性,但是您需要安排应用的随机相位仍然保持正频率和负频率之间的这种关系。在实践中,这将意味着您只有大约一半的随机相位可供选择-零频率单元无随机相位,FFT的所有正频率(前n/2个条目)各有一个随机相位,其他相位是条目k处相位的-1倍(n-k).

让我们从一个函数
lilly
开始,该函数取一个频率、一个振幅和一个相位(所有标量)以及一个信号长度
N
,并按照逆DFT的预期计算正弦波(见下面的注2):

我编写了这个函数,它使用了一个采样信号来表示波形的一个周期

以下函数使用
lilly
函数计算逆DFT(见下面的注释1):

现在,我测试以验证它是否实际计算逆DFT:

>> a=randn(1,256);
>> b=fft(a);
>> c=pseudoifft(b);
recomputung "oneperiod"
>> max(abs(a-c))
ans =  0.059656
>> subplot(2,1,1);plot(a)
>> subplot(2,1,2);plot(c)

由于
round
函数,误差相对较大:我们对信号进行二次采样,而不是插值。如果您需要更高的精度(我认为不太可能),您应该使用
interp1
,而不是使用
round(p)

接下来,我们用示例信号替换
lilly
函数中的正弦:

function out = lilly(N,periods,amp,phase)
persistent t
persistent oneperiod
if numel(t)~=N
   disp('recomputung "oneperiod"');
   t = 0:N-1;
   %oneperiod = cos(t * 2 * pi / N);
   gauss = @(t,t0,g) exp(-((t-t0)/g).^2); % a simple gaussian
   t1 = N/4;   % pulses peak positions (s)
   t2 = 3*N/4; % pulses peak positions (s)
   g = N/20;   % pulses width (at 1/e^2) (s)
   oneperiod = gauss(t,t1,g) - (.57*gauss(t,t2,g)); %different amplitude peaks
   oneperiod = circshift(oneperiod,[1,-round(N/4)]); % this will make it look more like cos
end
p = round(t * periods + phase/(2*pi)*N);
p = mod(p,N) + 1;
out = amp * oneperiod(p);
函数
pseudoifft
现在创建一个函数,该函数由您的基组成:

>> c=pseudoifft(b);
recomputung "oneperiod"
>> subplot(2,1,2);plot(c)

让我们看一个更简单的输入:

>> z=zeros(size(a));
>> z(10)=1;
>> subplot(2,1,1);plot(pseudoifft(z))
>> z(19)=0.2;
>> subplot(2,1,2);plot(pseudoifft(z))


注1:在您的问题中,您特别要求使用FFT。FFT是计算正向和反向DFT的一种非常有效的方法。上面的代码计算O(n^2)中的逆DFT,FFT将计算O(n logn)中的相同结果。不幸的是,FFT是一种基于DFT中使用的复指数特性的算法,如果用任何其他函数替换该复指数,则不可能使用相同的算法


注2:我在逆DFT中使用余弦函数。它当然应该是一个复杂的指数。但我只是走了一条捷径,假设被反变换的数据是共轭对称的。如果前向变换的输入是实的(逆变换的输出也必须是实的,因为共轭对称性,两个频率的复分量相互抵消)。

您可能在考虑小波。傅里叶变换不仅仅是“正弦”。它是关于将数据重新投影到不同的正交ba上
>> c=pseudoifft(b);
recomputung "oneperiod"
>> subplot(2,1,2);plot(c)
>> z=zeros(size(a));
>> z(10)=1;
>> subplot(2,1,1);plot(pseudoifft(z))
>> z(19)=0.2;
>> subplot(2,1,2);plot(pseudoifft(z))