Take the 2-minute tour ×
Signal Processing Stack Exchange is a question and answer site for practitioners of the art and science of signal, image and video processing. It's 100% free, no registration required.

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.

Entire Signal

Begining of signal

End of signal

% 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);
share|improve this question
    
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
1  
Why not just window the signal so that the beginning and end are at zero? –  Peter K. Jan 31 '13 at 15:15
add comment

3 Answers 3

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.

share|improve this answer
add comment

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
lin_fading_curve = linspace(y_start, y_stop, L); % linear fading curve
cub_fading_curve = 1.5 * lin_fading_curve - 0.5 * lin_fading_curve .^ 3; % cubic fading curve
y_lin_fade_in = [ytnorm(1:L) .* lin_fading_curve, ytnorm(L+1:end)];
y_cub_fade_in = [ytnorm(1:L) .* cub_fading_curve, ytnorm(L+1:end)];

plot(t1,ytnorm);
hold on;    
plot(t1, y_lin_fade_in, 'r');
plot(t1, y_cub_fade_in, 'g');
xlim([0 2*pi/fs*1200]);
legend('original', 'linear', 'cubic', 'Location', 'SouthEast');
hold off;

Here's what you get:

Fade-in of signal

share|improve this answer
    
this is what interpolation is suppose to do (see the interp1 command in the for loop )but as you can see from the two pictures at the beginning and the end it doesn't do a gradual spline –  Rick T Jan 31 '13 at 11:41
    
@RickT: I've changed my answer accordingly. –  Deve Jan 31 '13 at 12:33
add comment

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;
share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.