De-zipper code?

For general discussion related FlowStone
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: De-zipper code?

Post by Perfect Human Interface »

tulamide wrote:But I'm not sure, what you are really heading for?


Just to recreate the dezipper outside of Flowstone. The rest of the conversation is just some oddities I found while testing.

If I'm not mistaken what you described is the same as what my partner wrote: "old + (new - old) * coef." If you're correct then maybe the error is elsewhere.

However, would this really be linear if it's recalculated every sample? Should there not be a check to see if current sample is changed from previous sample?
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: De-zipper code?

Post by tulamide »

Perfect Human Interface wrote:However, would this really be linear if it's recalculated every sample? Should there not be a check to see if current sample is changed from previous sample?

That's why I asked what you're heading for, because while it is strictly linear per moment, you won't see a straight line of change over a longer period.

when a and b change per sample:
-1|0|1|-1 with t mapped to 4 samples, will result in -1, 0.5, -1
-1|-1|-1|-1 with t mapped to 4 samples, will result in -1, -1, -1

when a never changes during transition:
-1|0|1|-1 with t mapped to 4 samples, will result in -1, 0, -1
-1|-1|-1|-1 with t mapped to 4 samples, will result in -1, -1, -1

You see that the first example goes to more extremes in between. Both will result in straight lines, but the first one will seem more hectic. So, if you go with the first one, but don't want "sharp angles", you could go with qarp, which is quadratic interpolation. Easier said, qarp is the linear interpolation of two linear interpolations, and therefore requires 3 samples and t.

Code: Select all

lerp(lerp(a, b, t), lerp(b, c, t), t)
or
(a + t * (b - a)) + t * ((b + t * (c - b)) - (a + t * (b - a)))
Note: requires at least one intermediate step to avoid calculating a + t * (b - a) two times


Another more curvy (read: smoother) approach would be cosine interpolation:

Code: Select all

(a + b + (a - b) * cos(t * 180°)) / 2


Other interpolations are too demanding.
"There lies the dog buried" (German saying translated literally)
TheOm
Posts: 103
Joined: Tue Jan 28, 2014 7:35 pm
Location: Germany

Re: De-zipper code?

Post by TheOm »

This would basically be the corresponding C++ code.

Code: Select all

struct DezipState {
    float output;
    float lastTarget;
    float startValue;
    float coef;
};

float dezip(DezipState& state, float target, float rate) {
    if (target != state.lastTarget) {
        state.lastTarget = target
        state.coef = 0
        state.startValue = state.output
    }
    state.coef = min(state.coef + rate, 1.0f)
    state.output = state.startValue + state.coef * (target - state.startValue)
    return state.output;
}


Perfect Human Interface wrote:By the way, I discovered something interesting! With the dezipper, when the input value changes, it's smoothed to that new value linearly, but if the input is changing continuously, it appears to smooth logarithmically. I can only guess that the input changing continuously causes the algorithm to update at each step which manifests as a curve.


Yes that is exactly what's happening. If the target is changing continuously it basically degrades into a 1-pole lowpass.

Perfect Human Interface wrote:By the way, the Assembler dezipper that TheOm provided above doesn't seem to work at all with the input changing continuously.

The problem was that I updated the coef value after computing the new output.
Try this:
Attachments
dezip asm fix.fsm
(988 Bytes) Downloaded 1019 times
Last edited by TheOm on Sun Aug 06, 2017 6:13 pm, edited 2 times in total.
User avatar
martinvicanek
Posts: 1334
Joined: Sat Jun 22, 2013 8:28 pm

Re: De-zipper code?

Post by martinvicanek »

I think it is easier than that. The updating takes place at hop(128). An increment is calculated such that the (current) target will be reached after an integer number of hops. The code is so lightweight you don't even have to asm it.
Attachments
dezip MV.fsm
(1.11 KiB) Downloaded 1094 times
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: De-zipper code?

Post by Perfect Human Interface »

That's a neat smoother Martin, although it creates a logarithmic curve, and linear is what we're looking for.
(PS glad to see you're still around. Hopefully I will be contacting you within the next few months.)

Many thanks TheOm and everyone else in this thread. I think we'll be able to figure it out now. And I learned some stuff to boot. :D
User avatar
Spogg
Posts: 3368
Joined: Thu Nov 20, 2014 4:24 pm
Location: Birmingham, England
Contact:

Re: De-zipper code?

Post by Spogg »

Yay!! We're all making stream de-zippers!

Here's my offering. I'm using this in my current project to limit slew rate to be like the old 741 op-amp (0.5V/uS for a 10 volt p-p swing in open loop).

Cheers

Spogg
Attachments
Spogg's de-zipper.fsm
(284 Bytes) Downloaded 1075 times
User avatar
martinvicanek
Posts: 1334
Joined: Sat Jun 22, 2013 8:28 pm

Re: De-zipper code?

Post by martinvicanek »

Perfect Human Interface wrote:it creates a logarithmic curve, and linear is what we're looking for.

:?: :o :!: The output consists of linear segments.
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: De-zipper code?

Post by tulamide »

martinvicanek wrote:
Perfect Human Interface wrote:it creates a logarithmic curve, and linear is what we're looking for.

:?: :o :!: The output consists of linear segments.

See, Martin? That's what was confusing me as well!

tulamide wrote:That's why I asked what you're heading for, because while it is strictly linear per moment, you won't see a straight line of change over a longer period.
"There lies the dog buried" (German saying translated literally)
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: De-zipper code?

Post by Perfect Human Interface »

See the difference here.
I think Spogg's might be too subtle to visualize.
Attachments
dezip Test 3.fsm
(13.67 KiB) Downloaded 1066 times
adamszabo
Posts: 667
Joined: Sun Jul 11, 2010 7:21 am

Re: De-zipper code?

Post by adamszabo »

To make Martins version linear, you have to have the multiplier coefficient be the hop numbers ratio. So you have to divide 1 by the hop number. Martins 128 it too small, but if you increase it to 2048, or even 4096, you will see a difference and it will be linear.

Code: Select all

streamin in;
streamout out;

float step = 0;

hop(2048) {
       // 1/2048 = 0.00048828125
   step = (in - out) * 0.00048828125;
}

out = out + step;
Post Reply