# Var delay line pitch shifter

DominikK

Oct 25 2016 | 6:17 pm

Hello!

I'm trying to build an external which allows for variable delay line pitch shifting, basically the functionality of the "transposer" abstraction.
Since it's only meant to be an exercise it's not that critical but I'd still like to get it right.
In general the whole thing works already, but there is still an error somewhere I can't find, which creates a noisy sound as well as making the original material sound somehow distant. Also as the amount of pitch shift gets bigger some skewed (modulation?) frequencies are audible. At first I thought that linear interpolation is not precise enough, so I tried implementing Lagrange interpolation but that didn't solve the issue (unless my interpolation function is flawed of course).
I've been spending a lot of time trying to fix this but I think I need some help. I'll post the main part of the perform routine as well as the interpolation function.

thank you for your time!

pitch_factor = pow(2, cents/100/12);
phasorfreq = (1 - pitch_factor) * samplerate / windowsizesamps;

si = phasorfreq * siFactor; // siFactor = windowsize in samples / sample rate
iphase = trunc(phase);
phasorValue1 = phasorWavetable[iphase];
phasorValue2 = phasorWavetable[(iphase+halfwindowsizesamps)%windowsizesamps]; // 180° phase shifted
phase += si;

if (phase >= windowsizesamps) {
phase -= windowsizesamps;
}

if (phase < 0) {
phase += windowsizesamps;
}

delay_line[write_index++] = *input++;

if (write_index >= delay_length) {
write_index -= delay_length;
}

//delay line 1

ddelay1 = phasorValue1 * windowsizesamps;
idelay1 = trunc(ddelay1);
read_index1 = write_index - idelay1;

if(ddelay1 < 0) {
ddelay1 = 0;
} else if(ddelay1 > delay_length) {
ddelay1 = delay_length - 1;
}

while (read_index1 < 0) {
read_index1 += delay_length;
}
delay_line1 = lagrangeInterp(x, delay_line, delay_length, read_index1, ddelay1) * linInterp(x, windowWavetable, x->windowsizesamps, ddelay1);
//windowWavetable is half a sinewave period

//delay line 2
//same code as delay_line1 using different indices

*output++ = delay_line1 + delay_line2;

if(write_index >= delay_length) {
write_index -= delay_length;
}

the Lagrange interpolation:

```
double* delay_line = Array;
int delay_length = ArraySize;
double interpSample = 0;
double p = 0;
double fraction = ddelay - trunc(ddelay);
for (int i = -1; i
```