SynthMaker

1 sample delay bug

Archive · 2010 31 old posts

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

kirkagur ·

Hi

It looks like the one sample delay is act's like two samples delay,and the regular delay has 1 sample delay extra.

correct me if i am wrong.

here is an OSM to test.

trogluddite ·

Sussed it... Try changing your code delay modules so that they execute in stage(3) - the problem disappears.

The 1sample must be like the regular delay where the inputs happen in stage (1) or (2) and the output happens in stage(3). Because all of stages(1) and (2) are completed for every module before stage(3) begins, the downstream modules are always reading the previous output value of the 1sample delay. Weird, because ASM and code always uses stage(1) unless you explicitly say otherwise - so in most cases the 1sample would seem to act as a 2sample - using your little bit of code would be needed to get a genuine 1sample! The stage(2), stage(3) stuff is needed sometimes to make sure the order of code execution is correct when you are chaining multiple delays - so I guess the built in module has to have that just as a safety net coz' malc can't predict where we're going to use it.

MegaHurtz ·

That explains the liniar phase highpass i was getting 😀 cheers!

MegaHurtz ·

luddite it`s < instead of <= 😉

MegaHurtz ·

streamin in; streamout out;

float delay;

out=delay; delay=in;

trogluddite ·

Or even

stage(3) { out=in }

in a lot of cases.

MegaHurtz ·

nice to have some programmers to relate to 🙂

trogluddite ·

One day, I might even get around to doing some music with this stuff I'm spending all my time making LOL! 😉

MegaHurtz ·

lol, you are presuming alot here.

Andrew J ·

Old news, but still not fixed - Delay primitive has extra sample delay

trogluddite ·

AFAIK using stage(3) as the output stage of the delays is needed to be certain of correct processing order if multiple delays are in series. I had a few problems with my first attempts at coding through not understandng how important the order of execution is. Interestingly - it you look at malc's response to that old thread, it seems that something has been changed. Back then the problem seems to have been that delay1 was not delaying its input at all until you chained a few. My guess is that at that time, the delay1 was not using stages and so giving precisely the execution order problems described earlier - now that it does use stage(3) we have the opposite problem; too much delay. Those of us who know our code and assembly can of course decide for ourselves whether stage(3) is needed or not and program accordingly - but the primitives in the toolbox are there to make life easier for people who don't want to delve into that kind of programming, so I'm not sure there's a definitive solution without leaving the possibility that less experienced users would run into problems when using feedback loops etc.

MegaHurtz ·

I was under the impression 2,3 are similar. Did you find otherwise?

trogluddite ·

stage 0 is the exception because it only runs once. Stages 1,2,3 all do the same thing - but stage 1 executes for every module, then stage 2 for every module, then stage 3. Putting the final output in stage 3 just makes sure that it will always happen after just about all of the other code in the schematic has finished calculating. AFAIK this is done because the modules in your schematic are not always compiled and processed in the same order that the audio is flowing - that would be difficult to do without compiling times being really long every time you did an edit. Using stages makes sure that the audio is always flowing in the right direction. I can kind of visualise this in my head - but apologies or not being able to put it into words too well! Whether stage(2) behaves like (3) would depend on how stages are used within the built in modules - only malc really knows that.

MichaelBenjamin ·

trogluddite, could you give an example for this flow direction staging thing? like for a feedback loop, the out=feed+in; needs to be one stage behind or what?

trogluddite ·

I'll see if I can show the effect in a schematic somehow - I'm pretty sure I had a delay algorithm a while back that behaved very weirdly until I figured out it needed stages. I good analogy for it would be those bits of green schematic where you have to fiddle around getting the little ticks on the connections right to make things flow correctly. It's more about making the behavior predictable rather than because it causes nasty errors or anything. Using stages would only make a difference when you have different code blocks in series too - if you can get all of that code into one block, then the effect shouldn't happen. Get back to you when I've done a bit a rummaging on my big machine.

MegaHurtz ·

If you convert asm to binary it`s done inside stages. Don`t know exactly what this implies but i think it has something to do with the feedback handeling.

trogluddite ·

While trying to design a schematic to demonstrate why stages might affect things (couldn't find my old delay anywhere), I came across this old post... [old link] Can't say I undestand it all - but it seems from this that my reasoning is pretty sound (phew) - stages were implemented so that the very short delays used in filters etc. would behave predictably.

trogluddite ·

Took me a while to find something that reliably shows the effect, but here goes...

Two identical feedback loops, with multiple 'taps' - if you look at the schematic it seems obvious that the stream subtract should always output zero. Now click on one of the stream subtract's inputs to alter the connection order - suddenly, things are not so symmetrical any more. One of the '*-0.5' blocks is being calculated before the subtract and the other is being calculated after the subtract has already happened. If you use stages to make the order of execution explicit, you can make it so that the connection order doesn't matter. So, to go back to the start of the thread - the delay one sample module does kind of add an extra sample of delay, because of using stage(3) - but at least it will always behave predictably, regardless of how the connections are ordered.

MegaHurtz ·

Cool find although a bitter one, loss of sync is never good for a music program.

trogluddite ·

Know what you mean - our sample rates leave the Nyquist limit way too close to the audio range - one sample really can make a BIG difference to the sound.

MegaHurtz ·

It does seem to be restored when the audio is restarted. Lets hope our vst`s don`t suffer this issue.

MichaelBenjamin ·

thanks for your effort - however i wouldnt know yet how to spot such a situation with code modules.

trogluddite ·

MichaelBenjamin wrote: thanks for your effort - however i wouldnt know yet how to spot such a situation with code modules

Me neither really - the example was the result a lot of trial and error - so maybe we shouldn't worry about it too much, it must be a problem that wouldn't happen very often in a typical schematic. The geeky bit of my brain just has to solve these little mysteries before it'll let me get to sleep at night. 😕

MegaHurtz ·

It`s to enshure the data written is written before it`s read in the same code. basicly input input > output input.

Acrobat ·

trogluddite wrote: Took me a while to find something that reliably shows the effect, but here goes...

ouch! 🙁

trogluddite ·

Acrobat wrote: ouch!

Oh no, this stuff keeps me sane(ish) 😕 - when there is only simple, boring, dum-de-dum-de-dum things to think of, then my brain goes 'ouch!'

DigitalWhiteByte ·

trogluddite wrote: An execution order problem most likely - without using stages, there's no easy way to predict the order in which the primitives will execute, so some of them may run before others have prepared the values that they need to see as inputs. Probably the run order is dependent on the order that you drag modules into the schematic combined with the order that links are made. That's why SM has the stage() thing in code, so that you are able to guarantee that all the outputs have correct values before reading inputs - however that often introduces an additional 1sample latency. Link Post

They went to peek at the code in the executable file 😈 for the module Delay One Sample, i got the same ASM code without modification, the test seems to work well and gives excellent results, with the function stage, without additional 1 sample. 😮

aliasant ·

DigitalWhiteByte wrote: trogluddite wrote: An execution order problem most likely - without using stages, there's no easy way to predict the order in which the primitives will execute, so some of them may run before others have prepared the values that they need to see as inputs. Probably the run order is dependent on the order that you drag modules into the schematic combined with the order that links are made. That's why SM has the stage() thing in code, so that you are able to guarantee that all the outputs have correct values before reading inputs - however that often introduces an additional 1sample latency. Link Post

They went to peek at the code in the executable file 😈 for the module Delay One Sample, i got the same ASM code without modification, the test seems to work well and gives excellent results, with the function stage, without additional 1 sample. 😮

Seems to work. Excellent 🙂

trogluddite ·

Works beautifully in isolation, I tried tripping it up with multiple copies etc. always reads 1 sample! However it doesn't remove the need to be careful with connection orders when used in combination with 'unstaged' primitives/code. For guaranteed execution order every module/primitive in a schematic would have to use stages - and sadly tor can't do that for his filter coz there's no DP in code. Here's my 'stages example' schematic with the new code, and you'll see that you can still screw up the maths by changing the link order to the subtraction. I suppose it's not terribly different to juggling link orders with green triggers, but once you have multiple feedback paths etc. it's certainly a headscratcher.

infuzion ·

DigitalWhiteByte wrote: They went to peek at the code in the executable file 😈 for the module Delay One Sample, i got the same ASM code without modification, the test seems to work well and gives excellent results, with the function stage, without additional 1 sample.

Your Code looks really interesting! streamin in; streamout out; float prev=0.0; stage 3; movaps xmm0,in; movaps prev,xmm0; stage 1; movaps xmm0,prev; movaps out,xmm0; But how does it work in a larger OSM with more stuff in it please?

DigitalWhiteByte ·

infuzion wrote: But how does it work in a larger OSM with more stuff in it please?

I hope that this example is what you asked ... 🙂

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.