What is KVR Audio? | Submit News | Advertise | Developer Account

Options (Affects News & Product results only):

OS:
Format:
Include:
Quick Search KVR

"Quick Search" KVR Audio's Product Database, News Items, Developer Listings, Forum Topics and videos here. For advanced Product Database searching please use the full product search. For the forum you can use the phpBB forum search.

To utilize the power of Google you can use the integrated Google Site Search.

Products 0

Developers 0

News 0

Forum 0

Videos 0

Search  

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

DSP, Plug-in and Host development discussion.

Moderator: Moderators (Main)

foge
KVRist
 
31 posts since 14 Aug, 2010

Postby foge; Tue Dec 04, 2012 5:23 am Making a Delay into a Multitap delay in C++ problems.

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
User avatar
antto
KVRAF
 
2281 posts since 4 Sep, 2006, from 127.0.0.1

Postby antto; Tue Dec 04, 2012 7:33 am

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.freenode.net >>> #kvr
foge
KVRist
 
31 posts since 14 Aug, 2010

Postby foge; Tue Dec 04, 2012 9:27 am

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

Moderator: Moderators (Main)

Return to DSP and Plug-in Development