MATLAB flanger...zipper noise, crackling, help with interpolation values? i'm writing a batch script in MATLAB to flange. 

i'm getting some periodic noise, and i'm having trouble tracking down the source. it's definitely in the algorithm, because soundsc() will scale values larger than 1. and theres no memory or computing time issue, because it's running as a batch process.

any mp3 or wave file should do the trick

current script, with interpolation (sounds worse so far than non-interpolating, because i am probably using the wrong X for the interpolation.)



function result = dLinTerp(x1,x2,y1,y2,x)

% calculate decimal position of x
dx = (x - x1)/(x2 - x1);

% use weighted sum method of interpolating
result = dx*y2 + (1-dx)*y1;



and 


    cur_frac=cur_sin*max_samp_delay;

    if (readIdx + cur_frac >= (max_samp_delay)) 
        fetchIdx = cur_frac - (max_samp_delay - readIdx) + 1;
    else
        fetchIdx = readIdx + cur_frac;       
    end

    if (floor(fetchIdx) = max_samp_delay)
        fetchNext = 1;
    else
        fetchNext = ceil(fetchIdx);
    end
     integ = fix(cur_frac); 
     frac = abs(cur_frac - integ);
    interp = dLinTerp(0.0, 1.0, delayBuff(fetchPrev), delayBuff(fetchNext),frac);
    out(i) = (amp*input(i)) + (amp*interp);




here is the original script, no interpolation


%flanger

[input,fs] = audioread('pianoriff_s.mp3');
input = input(:,1);
len = length(input);
out = zeros(len,1);

max_time_delay=0.007; % 7ms max delay in seconds
rate=0.2; %rate of flange in Hz
max_samp_delay= floor(max_time_delay*fs);
delayBuff = zeros(max_samp_delay,1);
amp=0.7;
readIdx = 1;

for i = 1:len,
    delayBuff(readIdx) = input(i);

    sin_ref = sin(2*pi*i*(rate/fs));
    cur_sin=abs(sin_ref); %abs of current sin val 0-1
    cur_delay=ceil(cur_sin*max_samp_delay);

    if (readIdx + cur_delay >= max_samp_delay)
        fetchIdx = cur_delay - (max_samp_delay - readIdx) + 1;
    else
        fetchIdx = readIdx + cur_delay;
    end

    out(i) = (amp*input(i)) + (amp*(delayBuff(fetchIdx)));


    if (readIdx+1 >= max_samp_delay)
        readIdx = 1;
    else
        readIdx = readIdx + 1;
    end
end

soundsc(out,fs);
ok so it turns out setting indices is tricky in MATLAB (who knew :p)

first, a less needlessly complicated interpolator:


function result = dLinTerp(y1,y2,x)

% use weighted sum method of interpolating
result = x*y2 + (1-x)*y1;


and the flanger


% flanger
clear all;
% Creates a single FIR delay with the delay time oscillating from
% Either 0-3 ms or 0-15 ms at 0.1 - 5 Hz
[input,fs] = audioread('pianoriff_s.mp3');
input = input(:,1);
len = length(input);
out = zeros(len,1);

% parameters to vary the effect %
max_time_delay=0.005; % 7ms max delay in seconds
rate=0.3; %rate of flange in Hz

% convert delay in ms to max delay in samples
max_samp_delay= floor(max_time_delay*fs);
delayBuff = zeros(max_samp_delay,1);
amp=0.7;
readIdx = 1;

fetchPrev = 1;

% delaybase = .010;
% new_d_base = delaybase*fs;
% d_base = LIN_INTERP(0,1,0, new_d_base,frac);
%
% dp = (float)(delay_pos - d_base) - (delay_depth * law);
% %     // Get the integer part
% dp_idx = f_round(dp - 0.5f);
% %     // Get the fractional part
% dp_frac = dp - dp_idx;

% for each sample
for i = 1:len,
    delayBuff(readIdx) = input(i);
    sin_ref = 0.97*sin(2*pi*i*(rate/fs));
    sin_next = 0.97*sin(2*pi*(i+1)*(rate/fs));
    cur_sin=abs(sin_ref); %abs of current sin val 0-1
    cur_delay=ceil(cur_sin*max_samp_delay);

    cur_frac=cur_sin*max_samp_delay;

    if (readIdx + cur_frac >= (max_samp_delay))
        fetchIdx = cur_frac - (max_samp_delay - readIdx) + 1;
    else
        fetchIdx = readIdx + cur_frac;
    end

    if (floor(fetchIdx) = max_samp_delay)
        fetchNext = 1;
    else
        fetchNext = ceil(fetchIdx);
    end

    integ = fix(cur_frac);
    frac = abs(cur_frac - integ);
    interp = dLinTerp(delayBuff(fetchPrev), delayBuff(fetchNext),frac);
    out(i) = (amp*input(i)) + (amp*interp);

    if (readIdx+1 >= max_samp_delay)
        readIdx = 1;
    else
        readIdx = readIdx + 1;
    end


end
% write output

soundsc(out,fs);