Page 8 of 9

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 3:31 pm
by Nowhk
tulamide wrote:*popcorn ready* :mrgreen:

Takes the salad ones, my favorites <3

TheOm wrote:Now try with Input = 3 (odd number)
CountInt = round(3 - 0.5) = 2
CountFrac = 3 - 2 = 1
(1.0 - 1.0) * sample[2] + 1.0 * sample[3] = sample[3]

Oh I see! The "magic" acts later. :ugeek: Thanks for the explanation, very kind.
So CountFrac in this case is also used to "compensate" the round to even approximation from Precise Counter, since it skips odd values?

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 3:43 pm
by TheOm
Nowhk wrote:Oh I see! The "magic" acts later. :ugeek: Thanks for the explanation, very kind.
So CountFrac in this case is also used to "compensate" the round to even approximation from Precise Counter, since it skips odd values?

Exactly.
If you wanted to make a wave reader that doesn't use linear interpolation but instead only reads the sample at the index closest to the requested index, you would just use round without subtracting 0.5 first.

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 3:54 pm
by Nowhk
TheOm wrote:Exactly.
If you wanted to make a wave reader that doesn't use linear interpolation but instead only reads the sample at the index closest to the requested index, you would just use round without subtracting 0.5 first.

Yes, but the problem there will be that I cannot pitch the sample, since it could read only fixed int index, without interpolate with frac part.

Honestly, I'm not sure why you subtract 0.5 :o : round problems?

Anyway, the magic here is that it would work the same even if "Round" prim would use round to down instead of round to even, because on integer values CountInt will take "correct" odd values, and CountFrac will be 0.
In some other Sampler, for example, CountFrac interval is [0, 1[, so it will never take "1" as value. But that's also true that here the logic is different (for example, at T0, CountInt is 0, not 1).

Did you program WavePlayer? Smart work!!!

Furthermore (because I miss it), you said:

TheOm wrote:No, MyCo is talking about the int() function. That is indeed a bug (or at least unexpected behaviour).

Is it because int() should "round to down"? And instead it seems that acts as Double Round prim and does "round to even"? Just for a better understanding...

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 4:18 pm
by TheOm
Nowhk wrote:Yes, but the problem there will be that I cannot pitch the sample, since it could read only fixed int index, without interpolate with frac part.

Yes you would be able to pitch the sample just the same as with linear interpolation, however aliasing would be even worse than linear interpolation. There are also other better interpolation techniques, but its almost always a tradeoff between quality and computational complexity.

Nowhk wrote:Honestly, I'm not sure why you subtract 0.5 :o : round problems?

This subtraction is required in flowstone to turn the round into a floor.
Let's say you request a sample index of 6.75. Linear interpolation should then give you 0.25 * sample[6] + 0.75 * sample[7].
It would be wrong to round, because that would give you 1.25 * sample[7] + (-0.25) * sample[8]

Nowhk wrote:The magic here is that it would work the same even if "Round" prim would use round to down instead of round to even, because on integer values CountInt will take "correct" odd values, and CountFrac will be 0.
In some other Sampler, for example, CountFrac interval is [0, 1[, so it will never take "1" as value. But that's also true that here the logic is different (for example, at T0, CountInt is 0, not 1).

Yes it would work with round towards 0 aswell I think, but we don't have control over the processors rounding mode in FS so round to even it is.

Nowhk wrote:Did you program WavePlayer? Smart work!!!

No I didn't, but from what I've seen from looking at it I actually think it's kind of poor work(lots of unnecessary operations).

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 4:33 pm
by TheOm
Nowhk wrote:Furthermore (because I miss it), you said:

TheOm wrote:No, MyCo is talking about the int() function. That is indeed a bug (or at least unexpected behaviour).

Is it because int() should "round to down"? And instead it seems that acts as Double Round prim and does "round to even"? Just for a better understanding...

Yes that's basically what I meant. It looks like a typecast to int in C++, where the result would be truncation(floor) instead of rounding.

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 5:24 pm
by Nowhk
TheOm wrote:This subtraction is required in flowstone to turn the round into a floor.
Let's say you request a sample index of 6.75. Linear interpolation should then give you 0.25 * sample[6] + 0.75 * sample[7].
It would be wrong to round, because that would give you 1.25 * sample[7] + (-0.25) * sample[8]

Oh I see. This because Round prim does "round to even" when tie-breaking is needed (i.e. .5 values); otherwise it round to the nearest integer above or below (there isn't any "forced" round to down). This is why you sub 0.5: to force the round to down. CountFrac will become -0.25 because Input - CountInt=6.75 - 7, and 1-CountFrac is 1.25 (as you specified).

And the compensation of "missing" odd values due to the round to even its compensated by CountFrac that acts as frac of a whole integer (even if this happens only on few values where there is tie-breaking).

Great, that's reveals the meaning of sub 0.5. Great!!! Thanks TheOm, I've finally got it!

TheOm wrote:No I didn't, but from what I've seen from looking at it I actually think it's kind of poor work(lots of unnecessary operations).

Ahhah, the differences between experts and noob 8-)

Re: Clock Accuracy - 10ms?

Posted: Thu Feb 11, 2016 6:32 pm
by TheOm
Exactly, you got it!

Re: Clock Accuracy - 10ms?

Posted: Fri Feb 12, 2016 4:35 pm
by Nowhk
@TheOm: two additional questions:

1 - Is there any advantages to use FlowStone prims to calculate CountInt/Frac instead of doing it inside DSP code and output directly them?
2 - I think you have miss a important thing in this explanation: it doesn't use CountInt and CountInt+1 as indexes for Read module, but respectively CountInt-1 and CountInt:

Code: Select all

pos1 = readposInt-1;
pos2 = pos1 + 1;

this have an impact using Input (thus step) lower than 1. Try to use (for example) Input (step) of 0.5:

First step, Input = 0.5:
CountInt = round(Input - 0.5)=0
CountFrac = Input - CountInt = 0.5
it reads 0.5 * sample[-1] + 0.5 * sample[0]

Second step, Input = 0.5+0.5=1:
CountInt = round(1 - 0.5)=0
CountFrac = Input - CountInt = 1
it reads 0.0 * sample[-1] + 1 * sample[0]

This could create strange artefacts, because if the first sample is 0, it's not a real "interpolation", but seems it "delay" the first sample. I've make a Ruby that show it:

Immagine.png
Immagine.png (17.08 KiB) Viewed 24416 times

Linear Interpolation Emulation.fsm
(3.52 KiB) Downloaded 1121 times


Is that a normal behaviour of Linear Interpolation? Or due to the "trouble" with Round (that "force" this algorithm to use CountInt 1 based instead of 0) it will introduce this issue?

Anyway, having this code the whole process looks very better to understand and manage:

Code: Select all

foreach sample:
   base = floor(index_pointer)
   frac = index_pointer - base
   out = in[base] * (1 - frac) + in[base + 1] * frac
   index_pointer += speed

what we have in WavePlayer instead is this:

Code: Select all

foreach sample:   
   index_pointer += speed
   base = round(index_pointer - 0.5)
   frac = index_pointer - base
   out = in[base-1] * (1 - frac) + in[base] * frac

due to how "round" acts (and I'm also not very sure if they produce exactly the same results).

Isn't any way to "emulate" a floor in DSP Code? (round to down)

Re: Clock Accuracy - 10ms?

Posted: Fri Feb 12, 2016 11:50 pm
by TheOm
Nowhk wrote:1 - Is there any advantages to use FlowStone prims to calculate CountInt/Frac instead of doing it inside DSP code and output directly them?

I suspect they use doubles to prevent rounding errors that happen when you add a small floating point number to a big one (the current index and the step value) and to get a more precise result when subtracting two large numbers (subtracting the floored current index from current index).
I have not tested if it really makes much of an important difference in this case.
Nowhk wrote:2 - I think you have miss a important thing in this explanation: it doesn't use CountInt and CountInt+1 as indexes for Read module, but respectively CountInt-1 and CountInt:

You are correct. Unfortunately I couldn't come up with a working sample reader that still uses double precision, because Flowstone lacks a "Delay by one sample" primitive for doubles. I will keep looking at it.

Re: Clock Accuracy - 10ms?

Posted: Sat Feb 13, 2016 1:32 am
by nix
The sample player was done by Exo, including double precision counter.
Interesting stuff people!