使用信号插值来改变频率

时间:2016-01-19 15:16:16

标签: matlab fft octave interpolation ifft

使用信号插值来改变频率。

如果原始信号/样本长度= 200 我知道如果我将样本长度加倍,我得到400并将新的样本长度(400)插值到旧样本长度(200),我将获得原始信号的频率(hz)的两倍。但是,如果我只想在原始信号中添加4.83Hz而不是频率加倍,我怎么能算出最后需要添加多少数组呢?是的,我确实尝试将(*)更改为(+) chop_off_amnt = round(长度(ya)* freq_decimal_portion) chop_off_amnt = round(length(ya)+ freq_decimal_portion)那不起作用。

Steps / logic:
1) sample length = 200
2) double sample length = 400
3) interpolate double sample (400) to original sample length (200) 
I get twice the frequency (hz) of the original sample length.

My question is:
4) If instead of doubling the frequency I just want to add 4.83hz 
to the original signal how can I figure out how much of the array 
I need to add to the end?  At the moment it will give me 4.83 times the 
original signal I'm looking just to add 4.83hz to the original signal.

我不会知道你的原始频率(original_freq)只是一个例子。将导入的音频文件将是人类语音音频文件(因此它们不会仅由一个频率组成,而是由许多不同的频率组成)

下面的测试代码

%Matlab Test code below:
Fs = 200 %Sampling frequency
t=linspace(0,1,Fs);

%1a create signal
original_freq=2
ya = .5*sin(2*pi*original_freq*t);

%2a adjust array
freq_wanted=4.83;
freq_rnd_up=ceil(freq_wanted) %get rounded up value
freq_decimal_portion=freq_rnd_up-freq_wanted %minus this amount from array
new_freq_array_tmp=repmat(ya,[1 freq_rnd_up]); %repmat this amount of array
chop_off_amnt=round(length(ya)*freq_decimal_portion) %amount of cells to delete from end
new_freq=new_freq_array_tmp(1:end-chop_off_amnt); %create new array after deleting values from end
%length(new_freq)

%3a Interpolation 
xxo=linspace(0,1,length(new_freq))(:)'; 
xxi=linspace(0,1,length(ya))(:)'; 
yi_t=interp1(xxo,new_freq,xxi,'linear'); %interpolation 
plot(t,yi_t)

这就是现在的情节。 This is not what I want

这就是我希望情节看起来像 This what I want

Ps这是一个周期性信号,我使用八度音阶3.8.1,就像matlab一样。而且我知道我可以改变方程式,但方程只是一个例子我将导入音频文件,我将没有方程式,我需要以Hz为单位改变给定量的频率。 我不会知道你的原始频率(original_freq)只是一个例子。将导入的音频文件将是人类语音音频文件(因此它们不会仅由一个频率组成,而是由许多不同的频率组成)

1 个答案:

答案 0 :(得分:1)

clear
clc
close all

% You have to know what the sampling frequency is of your new signal
% otherwise you can't know how to add 4.83Hz because if you want to be all
% relative to Nyquist frequency, that 4.83 should be expressed over the
% Nyquist frequency too.

%If it's a regular audio file it will likely be 44100Hz though, so try like
%this and if you happen to know that the sampling frequency is different,
%just change it here:

F_sampling = 44100; %Hz

%supposing you have 10 seconds, let's create an example variable "audio"
%that contains this 10 seconds long signal sampled ad 44100 Hz:
audio = randn(1,441000);

N = numel(audio); % obbiously in this case is 441000

T = N/F_sampling; %this is the length in SECONDS, you want to keep this constant when resampling

F_add = 4.83; %Hz, frequency to add to original sampling frequency

%let's add it to the old and compute the resampling frequency:
F_sampling_new = F_sampling + F_add; %44100 + 4.83 = 44104.83 Hz

% this is the number of samples the new signal will need to have
N_new = T*F_sampling_new;

%but you want to resample it in the "old space" so you need to create a
%resampling vector that goes from 1 to N(old) but made of N_new samples
% otherwise the resampling function won't know which data interpolate
XX = linspace(1,N,N_new);

% and here it is the signal resampled
audio_resampled = interp1(1:N,audio,XX);

% to answer your question this is the number of samples that i needed to
% add
N_added = N_new - N;

%the problem with this is though that you need some simplification because
% N_new is not an integer: 44104.83 and unless the signal is long enough to
% overcome the decimals you won't be precise.
% So in this case, for example, having 4.83 two decimals, the length of the
% original signal must be exactly 100s so that N_new will be integer
% with 44100Hz*100s=>44104.83Hz*100s = 4410483 samples. So you see why this is not feasable, as the number product between the new sampling frequency and the length in seconds of the original signal must be integer, and it is unlikely to ever happen exactly, so you'd have to get as close as you can