SynthMaker

Interpolated delay

Archive · 2012 16 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

Mo ·

Aloha,

Compared to the toolbox delay, the toolbox interpolated delay seems not to be right.

I managed to fix it introducing stage3. I think the code should be:

streamin in; streamout out; streamin delay;

float index; float intdelay,frac; float temp1,temp2; float out1;

float mem[44100]; float MAXDELAY=44100;

stage(2) { index=index+1; index=(index<MAXDELAY)&index; } stage(3) { mem[index]=in;

intdelay = delay - 0.499999; intdelay = rndint(intdelay); frac = delay - intdelay;

temp1 = index - intdelay; temp2 = temp1 - 1;

temp1 = temp1 + (temp1 < 0)&MAXDELAY; temp1 = mem[temp1];

temp2 = temp2 + (temp2 < 0)&MAXDELAY; temp2 = mem[temp2];

frac = (1 - frac)/(1 + frac); out = temp2 + frac * (temp1 - out1); out1 = out; }

oddson ·

Doesn't it cause a problem with the delay length if you increment the index before it's used?

Is there a specific problem with the stock code? I wonder if it's related to the problem referenced in this thread: packed audio flow does not start fractional delay anymore

Mo ·

oddson wrote: Doesn't it cause a problem with the delay length if you increment the index before it's used?

That was the only way i could make it sound right. It seems not to cause problems. I was analyzing the delays in a bypass filter and found the stock interpolated delay sounding different compared to the normal stock delay. Same with optimized delays posted elsewhere on forum. I think it's not related to the other thread, but a missing stage 3.

infuzion ·

Shouldn't a interpolated delay sound difference, since it is um... interpolated? IIRC, the new stage segments should have delays working in Stage(2) & (4), while most other DSP work in (3)? I think we need to see your OSMs so we can also a/b. I know you're smart with DSP, but perhaps someone else has a different testing angle.

Mo ·

infuzion wrote: Shouldn't a interpolated delay sound difference, since it is um... interpolated?

No, when no delay time modulation.

infuzion wrote: IIRC, the new stage segments should have delays working in Stage(2) & (4), while most other DSP work in (3)?

Stage(2) is default and not necessary. I think there's no stage(4). Here's my test example. It's the bypass filter from freeverb with different delays; 1. Normal stock delay, 2. Fixed interpolated delay (sounds the same as 1.) and 3. stock interpolated delay (here the sound is wrong when listening closely to highhats in a drumloop for example, there's a ringing sound to it).

aliasant ·

Mo wrote: (here the sound is wrong when listening closely to highhats in a drumloop for example, there's a ringing sound to it).

I think your right. At least yours sounds cleaner. If this is confirmed perhaps we should fix all the different optimized versions out there?

Mo ·

aliasant wrote: If this is confirmed perhaps we should fix all the different optimized versions out there?

Indeed, all delays seems to need stage(3) outside the index increment.

Here's another way to do the same:

streamin in; streamout out; streamin delay; float index; float intdelay,frac; float temp1,temp2; float out1; float mem[44100]; float MAXDELAY=44100;

stage(2) { mem[index]=in; } stage(3) { intdelay = delay - 0.499999; intdelay = rndint(intdelay); frac = delay - intdelay;

temp1 = index - intdelay; temp2 = temp1 - 1;

temp1 = temp1 + (temp1 < 0)&MAXDELAY; temp1 = mem[temp1];

temp2 = temp2 + (temp2 < 0)&MAXDELAY; temp2 = mem[temp2];

frac = (1 - frac)/(1 + frac); out = temp2 + frac * (temp1 - out1); out1 = out;

index=index+1; index=(index<MAXDELAY)&index; }

stw ·

Ouch that's a big one! Good finding Mo! It seems the wrong stage introduces aliasing. What scares me a is that even the asm versions without stage ordering are blured (as you already found out). I tested it with an optimized version from MyCo (which i unfortunately use in my current project) 😝 To make it a bit more obvious for us naturalagedhicutfilterowners i mocked up another test osm. The ringing can be heard best with a noise input. And it becomes visual obvious when feeded with a saw.

cyto ·

This is only an issue when the delays are getting fed back into themselves (as in the AP architecture). The problem stems from the fact that the outputs are not getting updated before the inputs expect them, so an extra "unit delay" is introduced. If you were to use the interpolated delay straight (without any feedback), there wouldn't be as noticeable an effect. I think the "correct" way to deal with this is to update the outputs in stage 1, do all the "math" in stage 2, then update the inputs in stage 3...

streamin in; streamout out; streamin delay;

float index; float intdelay,frac; float temp1,temp2; float out1;

float mem[44100]; float MAXDELAY=44100;

stage(1) { out = temp2 + frac * (temp1 - out1); out1 = out; }

stage(2) { intdelay = delay - 0.499999; intdelay = rndint(intdelay); frac = delay - intdelay;

temp1 = index - intdelay; temp2 = temp1 - 1;

temp1 = temp1 + (temp1 < 0)&MAXDELAY; temp1 = mem[temp1];

temp2 = temp2 + (temp2 < 0)&MAXDELAY; temp2 = mem[temp2];

frac = (1 - frac)/(1 + frac);

index=index+1; index=(index<MAXDELAY)&index; }

stage(3) { mem[index]=in; }

-cyto

stw ·

cyto wrote: This is only an issue when the delays are getting fed back into themselves (as in the AP architecture). The problem stems from the fact that the outputs are not getting updated before the inputs expect them, so an extra "unit delay" is introduced. If you were to use the interpolated delay straight (without any feedback), there wouldn't be as noticeable an effect. I think the "correct" way to deal with this is to update the outputs in stage 1, do all the "math" in stage 2, then update the inputs in stage 3...

-cyto

Although this sounds reasonable (theoretically) i'm still confused how to handle processing order with that. I just ran into trouble when optimizing my current project which includes some allpasses too. After hours of trial and error and just one moment before getting the phonebook to search for some local psychiatrist i found out that my code wasn't wrong at all. I attached an example osm which contains an allpass with a fixed delay code. I marked the place where the signals are summed for feedback and output. Just changing the link order of the group module (which simply adds the signals) by clicking on it let the feedback go out of control. So blewed up every attempt of me putting all calculations into one asm box. I'm not sure if it's the order of stages or something else what corrupts the process. But I still couldn't find a workaround for that. I really would like to understand what's going on here... Maybe someone can help?

cyto ·

stw wrote: I'm not sure if it's the order of stages or something else what corrupts the process. But I still couldn't find a workaround for that.

It appears that the real culprit here is the little "node" module. When you remove it and just connect directly to the subsequent points, the problem seems to go away (at least in my limited tests)...

I tried every combination of link order in the above scenario, and none of them cause that crazy ringing. I have no idea why this is the case, though. I suspect it has something to do with the way SM "tracks back" through the schematic, but I'm really not sure. 😕

-cyto

stw ·

cyto wrote: stw wrote: I'm not sure if it's the order of stages or something else what corrupts the process. But I still couldn't find a workaround for that.

It appears that the real culprit here is the little "node" module.

Exactly! The summed connection seems to force another processing order than providing two (mathematical) equal outputs. And that's what happens if all is done in one coder block. This is really disgusting because there's absolutely no way to predict that behaviour.

cyto wrote: I suspect it has something to do with the way SM "tracks back" through the schematic, but I'm really not sure. 😕 -cyto

If so... why? Is it a bug or a feature?

Tzarls ·

We had a topic about this same thing (processing order) here:

[old link]

cyto ·

stw wrote: ...and just one moment before getting the phonebook to search for some local psychiatrist

You're not kidding! I just spent the good part of the evening trying to get a "one code block" version of this thing going, and no matter what I tried, I couldn't make it work. Something is definitely screwy here 😕 Just as I was ready to throw in the towel, I decided to throw together a quick asm version, just to see if I ran into the same problems, and lo and behold it seems to work!!! So at least we have that option.

stw wrote: If so... why? Is it a bug or a feature?

I think it is a little of both. Considering the sheer complexity of compiling the complex schematics that SM can, there are surely going to be oddities in the behavior. I worked with Synthedit years ago and I seem to remember that it only processed data in chunks of 4 (or was it 8?) samples at a time. One of the reasons I originally checked out SM was its ability to process sample by sample. That must be no easy feat. It seems like the staging system is supposed to be able to deal with these little oddities, but I am now convinced that it is not 100% there.

-cyto

stw ·

cyto wrote: Just as I was ready to throw in the towel, I decided to throw together a quick asm version, just to see if I ran into the same problems, and lo and behold it seems to work!!! So at least we have that option.

Great!! And a good code reduction too. Thanks for giving it a try! I guess i failed and your code works because i had the packing in an extra asm block. But i can't verify that atm. I'll try to put that solution into the interpolated version. However when Tzarls posted the link to the other thread i remembered that. I never had a deeper look into that before but the discussion there makes perfectly sense. At least that teaches me to give some extra caution and testing on these feedback things.

DigitalWhiteByte ·

AZZ, 😀 it sounds really clean

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.