简体   繁体   中英

Using interpolation and repmat to change frequency of signal in octave and matlab

I'm using Octave 3.8.1 which is like matlab, I'm trying to use interpolation and repmat to alter the frequency of signals ( since it's so fast doing it this way (.01 seconds) and I have to create 28000+ at a time ) I can change the variable num_per_sec to any whole number but if I try to change it to 2.1 or anything with a decimal in it I get an error "error: reshape: can't reshape 44100x2 array to 92610x1 array error: called from: line 10 (the repmat line)" does anyone have a work around for this or another suggestion?

Note: please note that ya is a simple test equation I won't have equations to work with just the signal to work with so just changing the freq variable won't work.

see code below:

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)

You are trying to call repmat with a floating point number. Obviously it won't work the way you intended. repmat 's intended operation is to replicate a particular dimension an integer number of times .

Therefore, one thing I can suggest is to perhaps truncate the signal for the multiple which doesn't go up to 1 and stack this at the end of the replicated signal. For example, if you wanted to replicate a signal 2.4 times, you'd replicate the entire signal twice normally, then stack 40% of the length of the signal to the end of the array. Therefore, you'd sample up to 40% of the total duration of the signal and place this at the end of the replicated signal.

Because you have the sampling frequency, this tells you how many samples per second the signal should consist. As such, figure out how many integer multiples you have, then determine how many samples the partial signal consists of by taking the floor of this percentage multiplied by your sampling frequency. You'd then sample from this and stack this at the end of the signal. For example, going with our example of 2.4, we would perform floor(0.4*fs) to determine the total number of samples from the beginning of the signal we would need to extract to place this at the end of the replicated signal.

Something like this:

%// 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');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM