creating a seamless signal / loop using interpolation

I'm trying to create a seamless loop using a "non-periodic" signal using interpolation to smooth out the beginning and the end but I'm still getting a click at the beginning when it loops and I listen to it. Can interpolation do this?

Please Note that the equation is done this way to create a "non-periodic" signal to test when a signal does not start and end at the zero crossings.

I used audacity to zoom in and play the loops. I've included images along with the matlab/octave code.

% combines sig to create seamless loop
clear all,clc,tic;
fs=44100;
dirpathtmp=strcat('/tmp/'); %/home/rat/Documents/octave/eq_research/main/transform/voice
fn=strcat('atest1',sprintf('%02d',fs),'.wav');

t1=linspace(0,2*pi,fs); %need to round off no decimals
t2=linspace(0,2*pi,fs); %need to round off no decimals
t3=linspace(0,2*pi,fs); %need to round off no decimals

%Create signal in different arrays
y1=sin(7*t1);
y2=sin(12*t2);
y3=cos(2.2*t3);
yt=y1+y2+y3;

ytnorm=(yt/max(abs(yt))*.8); %normalize signal

%change end points to stddev number
ytnorm_std=std(ytnorm);

%for loop to replace points to create seamless loop
ytnorm(1)=0; %set first point to 0
ytnorm(fs)=0; %set last point to zero

for kk=2:1:15;
kk
ytnorm(kk)=interp1(t1,ytnorm,kk,'spline');
ytnorm((fs+1)-kk)=interp1(t1,ytnorm,((fs+1)-kk),'spline');
end;

wavwrite([ytnorm'] ,fs,16,strcat(dirpathtmp,fn));

plot(ytnorm)

fprintf('\nfinally Done-elapsed time -%4.4fsec- or -%4.4fmins- or -%4.4fhours-\n',toc,toc/60,toc/3600);

-
I have updated my answer to show how you could make the start and end point match without an abrupt change. –  Dennis Jaheruddin Jan 31 '13 at 14:46
Why not just window the signal so that the beginning and end are at zero? –  Peter K. Jan 31 '13 at 15:15

Not sure if I understand it correctly, but assuming this is your problem: I have a signal that i want to repeat, but the beginning is not at the same level as the end

The solution can be quite straightforward:

Calculate the trend (end-begin)/length of interval and correct the sound value at each point in the interval for this trend.

If you already tried this, please plot the entire signal played twice and look whether you still see something strange in the middle.

Here is an example of what you can do to correct for the trend instead of interpolation:

ydiff = ytnorm(end) - ytnorm(1);
ymean = mean(ytnorm);
ytnorm = ytnorm - (1:length(ytnorm)).*(ydiff /length(ytnorm)) ;
ytnorm = ytnorm - mean(ytnorm) + ymean;

-
this is what interpolation is suppose to do (see the interp1 command in the for loop) but as you can see it doesn't do a gradual spline –  Rick T Jan 31 '13 at 11:29
@RickT I am saying that you may not want to interpolate between points, but rather correct for the trend in the signal. –  Dennis Jaheruddin Jan 31 '13 at 13:21
Thanks I know this is an old question but does the code you used for your answer have a technical name for it? Or is it just call trend correction? –  Rick T Sep 27 '14 at 11:15
@RickT I am not aware of a better description, but if you are looking for a single term you would probably be ok with 'detrending'.-- In general the removal of properties of a dataset could be called normalization so it's good to know the term, but if you say you will normalize the signal that could basically mean anything so I would not recommend it. –  Dennis Jaheruddin Sep 29 '14 at 8:05

An alternate method is to create an array of two copies of your input signal

y = [ x , x ]         % MATLAB
y = hstack(( x , x )) # NUMPY


Run $x[k]$ through a LPF. Then slice $N$ samples from the "middle" of $y[k]$ where $N$ is the length of $x[k]$.

xsmooth = y( o : o + N - 1) % MATLAB
xsmooth = y[ o : o + N ]    # NUMPY


Where $o$ is an appropriately chosen offset. Be mindful of filter "tails" if you carry out the LPF through conventional convolution.

-

You're still getting clicks because you're forcing your signal to zero abprubtly. (Abrupt changes in time correspond to wide-band signals in frequency domain which account for the click-like sound). I think interpolation is not the suitable approach here as it involves the insertion of additional data points, what you probably don't want.

Fading the signal in/out can solve the problem. This can be a linear rise/decay or some spline curve. I'm quite sure Audacity can do this. Of course, you can also do it in Matlab by multiplying the beginning/end of your signal with some fading curve like this:

% Fade In
L = 1000; % length of fade in
y_start = 0; % start value
y_stop = 1; % stop value

plot(t1,ytnorm);
hold on;