Making a Delay into a Multitap delay in C++ problems.

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hi
I am a beginner so forgive me if this is a little jumbled up.
I would like some guidance on creating a multitap delay in C++.

I have created a simple delay with feedback like this

Code: Select all

gwsNewDelay::gwsNewDelay() {
	memset( memory, 0, 88200*sizeof (double) );
}

double gwsNewDelay::gwsNdl(double input, int size, double feedback)  {
	output=input*0.5 - (feedback* memory[phase]);
	memory[phase]=output;
	phase=(phase+1)%size;
	return(output);
}
I have also used Mick Grierson delay

Code: Select all

double maxiDelayline::dl(double input, int size, double feedback)  {
	if ( phase >=size ) {
		phase = 0;
	}
	output=memory[phase];
	memory[phase]=(memory[phase]*feedback)+(input*feedback)*0.5;
	phase+=1;
	return(output);
	
}
These make sense and both work for me.

WHen I was messing around in reaper's JS language I found it easy to create a mulitap delay by just reading the ring buffer from different points.

Code: Select all

slider1:30000<0,88200,100> delay 1 

@slider
echolength = slider1 ;
tapone = floor (echolength*0.333); // attempt at delay tap 1 1/3 echolength
taptwo = floor (echolength*0.666); // attempt at delay tap 2 2/3 echolength
tapthree = floor (echolength*0.25); // attempt at delay tap 3 1/4 echolength
tapfour = floor (echolength*0.5); 
 
@sample
bufpos[0] = spl0 ;
bufpos = bufpos + 1 ;
bufpos > echolength ? bufpos = 0;



spl0 = bufpos[0] + bufpos[tapone] + bufpos[taptwo] ;  // put delay taps 1 and 2 on the left
spl1 = bufpos[0] + bufpos[tapthree] + bufpos[tapfour] ; // put delay taps 3 and 4 on the right

This worked fine.


However I am struggling to do a similar thing in C++
I cannot seem to read a ring buffer from multiple points in C++ I keep getting a tickig sound which means I have done it wrong.

e.g.
This does not work

Code: Select all

gwsPointerDelay::gwsPointerDelay() {
	memset( memory, 0, 88200*sizeof (double) );
}

double gwsPointerDelay::gwsPdl(double input, int size, double feedback)  {
    int size2 = (int) size/2;
    int size3 = (int) size/3;

    
    //cout<<"size2 is" <<size2 <<endl;
    
    output=input*0.5 - (feedback* memory[phase]);
	memory[phase]=output;
	phase=(phase+1)%size; 
    return(output + memory[size2] + memory[size3]);
}
I think it doesn't work because memory[size2] is static and isn't being increment.

I have been experimenting with pointers but get a similar result.

Does anyone have a good example of a multitap delay in C++?

I seem to be making myself more confused rather than less confused.

I can make a delay with multi time like this


Code: Select all

gwsPointerDelay::gwsPointerDelay() {
	memset( memory, 0, 88200*sizeof (double) );
}

double gwsPointerDelay::gwsPdl(double input, int size, double feedback)  {
    int size2 = (int) size/2;
    int size3 = (int) size/3;

    
    //cout<<"size2 is" <<size2 <<endl;
    
    output=input*0.5 - (feedback* memory[phase]);
	memory[phase]=output;
	phase=(phase+1)%size;
    
    output2=memory[phase];
    memory[phase]=input*0.5;
	phase=(phase+1)%size2;
    
    output3=memory[phase];
    memory[phase]=input*0.5;
	phase=(phase+1)%size3;
    
    return(output + output2 + output3 );
}
But I don't think this is the correct way of doing a multitap delay.

Any guidance appreciated.
GEoff

Post

if we put the feedback aside for a moment, multiple taps means reading at different locations

int t2 = (phase+tap2_offset) % size;
int t3 = (phase+tap3_offset) % size;

now simply access from these locations
... memory[t2] * coeff + memory[t3] * coeff
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

Thanks that was really helpful :)
At bit messy but this sort of thing.
Need to tidy it up to be more like what you have written.

Code: Select all

 double gwsNewDelay::gwsNdl(double input, int size, double feedback)  {
        output=input*0.5;// - (memory[phase]);
        phaseIndex2 = (phase + size) - (int)(size*0.66);//index is somewhere between 0 and size
        phaseIndex3 = (phase + size) - (int)(size*0.33);
        float output2 = input*0.5 - (memory[phaseIndex2]);
        float output3 = input*0.5 - (memory[phaseIndex3]);
        memory[phase]=output;
        phase=(phase+1)%size;
        
        return( 0.33*(output+output2+output3) );
        
}

Progress
Geoff

Post Reply

Return to “DSP and Plugin Development”