【发布时间】:2016-04-18 19:46:49
【问题描述】:
我知道我可以通过更改变量 shift 来更改整数频率,但是如何使用带小数位的数字(如 .754 或1.2345 或 67.456。如果我将变量 'shift' 更改为非整数,如 5.1 我得到一个错误下标索引必须是小于 2^31 的正整数或逻辑行 mag2s = [mag2(shift+1:end), zeros(1,shift)];
下面来自问题 increase / decrease the frequency of a signal using fft and ifft in matlab / octave 的示例代码适用于更改变量 shift(但它只适用于整数,我也需要它适用于小数) .
PS:我使用的是 octave 3.8.1,它类似于 matlab,我知道我可以通过调整变量 ya 中的公式来改变频率,但 ya 会是从音频源(人类语音)获取的信号,因此它不是方程式。该等式仅用于使示例保持简单。是的,Fs 很大,因为使用的信号文件大约 45 秒长,这就是为什么我不能使用 resample,因为我在使用时出现内存不足错误。
这是一个 youtube 动画视频示例,展示了我在使用测试方程 ya= .5*sin(2*pi*1*t)+.2*cos(2*pi*3* 时想要得到的结果t) 以及如果我将变量 shift 从 (0:0.1:5) youtu.be/pf25Gw6iS1U 更改为我想要发生的事情,请记住,你将一个导入的音频信号,所以我没有公式可以轻松调整
clear all,clf
Fs = 2000000;% Sampling frequency
t=linspace(0,1,Fs);
%1a create signal
ya = .5*sin(2*pi*2*t);
%2a create frequency domain
ya_fft = fft(ya);
mag = abs(ya_fft);
phase = unwrap(angle(ya_fft));
ya_newifft=ifft(mag.*exp(i*phase));
% ----- changes start here ----- %
shift = 5; % shift amount
N = length(ya_fft); % number of points in the fft
mag1 = mag(2:N/2+1); % get positive freq. magnitude
phase1 = phase(2:N/2+1); % get positive freq. phases
mag2 = mag(N/2+2:end); % get negative freq. magnitude
phase2 = phase(N/2+2:end); % get negative freq. phases
% pad the positive frequency signals with 'shift' zeros on the left
% remove 'shift' components on the right
mag1s = [zeros(1,shift) , mag1(1:end-shift)];
phase1s = [zeros(1,shift) , phase1(1:end-shift)];
% pad the negative frequency signals with 'shift' zeros on the right
% remove 'shift' components on the left
mag2s = [mag2(shift+1:end), zeros(1,shift)];
phase2s = [phase2(shift+1:end), zeros(1,shift) ];
% recreate the frequency spectrum after the shift
% DC +ve freq. -ve freq.
magS = [mag(1) , mag1s , mag2s];
phaseS = [phase(1) , phase1s , phase2s];
x = magS.*cos(phaseS); % change from polar to rectangular
y = magS.*sin(phaseS);
yafft2 = x + i*y; % store signal as complex numbers
yaifft2 = real(ifft(yafft2)); % take inverse fft
plot(t,ya,'-r',t,yaifft2,'-b'); % time signal with increased frequency
legend('Original signal (ya) ','New frequency signal (yaifft2) ')
【问题讨论】:
-
我不确定你在问什么。通过移动这个信号而产生的频移已经(可能)是一个非整数。傅立叶域中样本之间的间距为 2*Nyquist/N(其中 N 是样本总数)。如果您想要更近的间距,您可以对输入信号进行零填充。
-
@efunkh 我知道我可以通过更改变量 'shift' 来更改整数的频率,但是如何使用带小数位的数字(如 0.754 或 1.2345 或 67.456)来更改频率。如果我将变量 'shift' 更改为非整数,如数字 5.1,我得到一个错误下标索引必须是小于 2^31 的正整数或逻辑
-
我还添加了错误来自的行
-
一种通用的频移方式是对信号进行上采样,将其与载波混合,同时抑制一个边带,然后进行下采样。您可以通过这种方式进行完全任意的频移,成本为 O(N),而且您无需处理 FFT :)
-
@RickT 我假设您的目标是特定频率?就像您试图将信号移动 5.245 Hz 一样? FFT 是离散的,因此您只能将信号移动整数样本,但只需更改信号长度(同时保持 Fs 不变)即可轻松获得任意样本间距。为 t=[0:1/(Fs-1):1] 和 t=[0:1/(Fs-1):3] 运行您的程序,您将看到五个样本移位的频率变化量每种情况下的变化。如果这是你想要的,我会在有机会的时候写一个更详细的答案。
标签: matlab signal-processing fft octave ifft