使用插值和repmat改变八度音阶和matlab中的信号频率
Using interpolation and repmat to change frequency of signal in octave and matlab
我正在使用类似于 matlab 的 Octave 3.8.1,我正在尝试使用插值和 repmat 来改变信号的频率(因为这样做速度很快(.01秒)并且我必须一次创建 28000+)我可以将变量 num_per_sec 更改为任何整数但是如果我尝试将其更改为 2.1 或任何具有里面有小数我得到一个错误 "error: reshape: can't reshape 44100x2 array to 92610x1 array error: called from: line 10 (the repmat line)" 有没有人有解决这个或其他建议的方法?
注意:请注意 ya 是一个简单的测试方程 我没有方程可以只处理要处理的信号,所以只需更改频率变量将不起作用。
查看下面的代码:
clear,clc
fs = 44100; % Sampling frequency
t=linspace(0,2*pi,fs);
freq=1;
ya = sin(freq*t)'; %please note that this is a simple test equation I won't have equations just the signal to work with.
num_per_sec=2 %works
%num_per_sec=2.1 %doesn't work
yb=repmat(ya,num_per_sec,1);%replicate matrix
xxo=linspace(0,1,length(yb))'; %go from 0 to 1 sec can change speed by incr/decr 1
xxi=linspace(0,1,length(ya))'; %go from 0 to 1 sec and get total samplerate from total y value
yi_t=interp1(xxo,yb,xxi,'linear');
plot(yi_t)
您正在尝试使用浮点数调用 repmat
。显然它不会按您预期的方式工作。 repmat
的预期操作是将特定维度复制 整数次 。
因此,我可以建议的一件事是截断不达到 1 的倍数的信号,并将其堆叠在复制信号的末尾。例如,如果您想将一个信号复制 2.4 次,您通常会将整个信号复制两次,然后将信号长度的 40% 堆叠到数组的末尾。因此,您最多采样信号总持续时间的 40%,并将其放在复制信号的末尾。
因为您有采样频率,所以这会告诉您每秒 个样本 信号应该包含多少。因此,计算出您有多少个整数倍,然后通过将该百分比乘以您的采样频率作为底数来确定部分信号包含多少个样本。然后您将从中采样并将其堆叠在信号的末尾。例如,以我们的 2.4 示例为例,我们将执行 floor(0.4*fs)
以确定从信号开头开始的样本总数,我们需要将其提取以将其放置在复制信号的末尾。
像这样:
%// Your code
clear, clc
fs = 44100; %// Define sampling frequency
t=linspace(0,2*pi,fs);
freq=1;
ya = sin(freq*t)'; %// Define signal
num_per_sec=2.1; %// Define total number of times we see the signal
%// New code
%// Get total number of integer times we see the signal
num_whole = floor(num_per_sec);
%// Replicate signal
yb=repmat(ya,num_whole,1);
%// Determine how many samples the partial signal consists of
portion = floor((num_per_sec - num_whole)*fs);
%// Sample from the original signal and stack this on top of replicated signal
yb = [yb; ya(1:portion)];
%// Your code
xxo=linspace(0,1,length(yb))';
xxi=linspace(0,1,length(ya))';
yi_t=interp1(xxo,yb,xxi,'linear');
我正在使用类似于 matlab 的 Octave 3.8.1,我正在尝试使用插值和 repmat 来改变信号的频率(因为这样做速度很快(.01秒)并且我必须一次创建 28000+)我可以将变量 num_per_sec 更改为任何整数但是如果我尝试将其更改为 2.1 或任何具有里面有小数我得到一个错误 "error: reshape: can't reshape 44100x2 array to 92610x1 array error: called from: line 10 (the repmat line)" 有没有人有解决这个或其他建议的方法?
注意:请注意 ya 是一个简单的测试方程 我没有方程可以只处理要处理的信号,所以只需更改频率变量将不起作用。
查看下面的代码:
clear,clc
fs = 44100; % Sampling frequency
t=linspace(0,2*pi,fs);
freq=1;
ya = sin(freq*t)'; %please note that this is a simple test equation I won't have equations just the signal to work with.
num_per_sec=2 %works
%num_per_sec=2.1 %doesn't work
yb=repmat(ya,num_per_sec,1);%replicate matrix
xxo=linspace(0,1,length(yb))'; %go from 0 to 1 sec can change speed by incr/decr 1
xxi=linspace(0,1,length(ya))'; %go from 0 to 1 sec and get total samplerate from total y value
yi_t=interp1(xxo,yb,xxi,'linear');
plot(yi_t)
您正在尝试使用浮点数调用 repmat
。显然它不会按您预期的方式工作。 repmat
的预期操作是将特定维度复制 整数次 。
因此,我可以建议的一件事是截断不达到 1 的倍数的信号,并将其堆叠在复制信号的末尾。例如,如果您想将一个信号复制 2.4 次,您通常会将整个信号复制两次,然后将信号长度的 40% 堆叠到数组的末尾。因此,您最多采样信号总持续时间的 40%,并将其放在复制信号的末尾。
因为您有采样频率,所以这会告诉您每秒 个样本 信号应该包含多少。因此,计算出您有多少个整数倍,然后通过将该百分比乘以您的采样频率作为底数来确定部分信号包含多少个样本。然后您将从中采样并将其堆叠在信号的末尾。例如,以我们的 2.4 示例为例,我们将执行 floor(0.4*fs)
以确定从信号开头开始的样本总数,我们需要将其提取以将其放置在复制信号的末尾。
像这样:
%// Your code
clear, clc
fs = 44100; %// Define sampling frequency
t=linspace(0,2*pi,fs);
freq=1;
ya = sin(freq*t)'; %// Define signal
num_per_sec=2.1; %// Define total number of times we see the signal
%// New code
%// Get total number of integer times we see the signal
num_whole = floor(num_per_sec);
%// Replicate signal
yb=repmat(ya,num_whole,1);
%// Determine how many samples the partial signal consists of
portion = floor((num_per_sec - num_whole)*fs);
%// Sample from the original signal and stack this on top of replicated signal
yb = [yb; ya(1:portion)];
%// Your code
xxo=linspace(0,1,length(yb))';
xxi=linspace(0,1,length(ya))';
yi_t=interp1(xxo,yb,xxi,'linear');