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.

% 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

3 Answers 3

up vote 0 down vote accepted

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

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

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:

share|improve this answer

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.
{"cc_re__cc_re__cc_by_sa_3_0": ["                  <li><a href=\"//area51.stackexchange.com\" title=\"proposing new sites in the Stack Exchange network\">Area 51</a></li>\r\n                        <li><a href=\"//careers.stackoverflow.com\">Stack Overflow Careers</a></li>\r\n                    \r\n                </ol>\r\n            </td>\r\n    </tr>\r\n</table>\r\n                </div>\r\n            </div>\r\n\r\n            <div id=\"copyright\">\r\n                site design / logo &#169; 2015 stack exchange inc; user contributions licensed under <a href=\"http://creativecommons.org/licenses/by-sa/3.0/\" rel=\"license\">cc by-sa 3.0</a>                   with <a href=\"http://blog.stackoverflow.com/2009/06/attribution-required/\" rel=\"license\">attribution required</a>\r\n            </div>\r\n            <div id=\"svnrev\">\r\n                rev 2015.1.30.2262\r\n            </div>\r\n            \r\n        </div>\r\n    </div>\r\n    <noscript>\r\n        <div id=\"noscript-warning\">Signal Processing Stack Exchange works best with JavaScript enabled<img src=\"http://pixel.quantserve.com/pixel/p-c1rF4kxgLUzNc.gif\" alt=\"\" class=\"dno\""], "copyright__copyright__copyright": ["y_cub_fade_in = [ytnorm(1:L) .* cub_fading_curve, ytnorm(L+1:end)];\n\nplot(t1,ytnorm);\nhold on;    \nplot(t1, y_lin_fade_in, 'r');\nplot(t1, y_cub_fade_in, 'g');\nxlim([0 2*pi/fs*1200]);\nlegend('original', 'linear', 'cubic', 'Location', 'SouthEast');\nhold off;\n\nHere's what you get:\n\nshare|improve this answer\n\nYour Answer\n\n\u00a0\ndiscard\n\nBy posting your answer, you agree to the privacy policy and terms of service.\n\nNot the answer you're looking for? Browse other questions tagged or ask your own question."]}