grame-cncm / faustlibraries

The Faust libraries
https://faustlibraries.grame.fr
183 stars 59 forks source link

add smoothq #160

Closed marchingband closed 8 months ago

marchingband commented 9 months ago

I have an alternate implementation to consider:

smoothq(time, q, tar) = out letrec {
    'src = select2(trig, src, out);
    'b = select2(trig, b, 
        select3(dir,
            (0.0 - ratio) * (1.0 - coef),
            0,
            (1.0 + ratio) * (1.0 - coef)
        )
    );
    'y = select3(dir, 
        select2(trig, max( 0, b + y * coef), 1), // 
        0,
        select2(trig, min( 1, b + y * coef), 0)
    );
    'out = select2(trig,
        select3(dir,
            tar + y * dis, 
            out,
            src + y * dis
        ),
        out
    );
    where 
        trig = tar != tar';
        ratio = pow(q, 5) / 10000 + 0.001;
        coef = exp((-1 * log((1.0 + ratio) / ratio)) / (ma.SR * time));
        dis = abs(tar - src);
        dir = (tar > out) + (tar >= out); // 0=lt 1=eq 2=gt
    };
DBraun commented 9 months ago

Similarly to your other PR, I think

coef = exp((-1 * log((1.0 + ratio) / ratio)) / (ma.SR * time));

could be refactored into

coef = (ratio/(1.0 + ratio)) ^ (1/(ma.SR * time));

so that the c++ at the end is faster.

sletz commented 9 months ago

@marchingband Is this PR ready for merge ?

marchingband commented 9 months ago

@sletz As far as I know yes. @DBraun does your work on adsr_bias have potential to improve this smoothing algo as well?

DBraun commented 9 months ago

I'm not sure the other adsr_bias code would help. It relies on knowing where the y is coming from in addition to its current state. For example, during decay you're definitely coming from 1.0, but you could be anywhere between 1 and sustain. In smoothq there doesn't seem to be a record keeping of something equivalent.

sletz commented 9 months ago

So ready to be merged ? OK for you @marchingband and @DBraun ?

DBraun commented 9 months ago

If you don't mind waiting I can try to produce some graphs tomorrow.

DBraun commented 8 months ago

Looks good! I was surprised to not run into issues even though there's an unsafe divide by ma.SR * time in the code. Maybe we should change it to /max(1, ma.SR*time) until someone shows that it's provably safe without it.

I tested a 1 Hz square wave going into the smoothq. So the input is -1 for 0.5 seconds, then 1 for 0.5 seconds and so on. For time=0, all the graphs start at y=0 for just the first sample, but si.smoo does this too. The graphs for larger t look correct.

So do the change with /max(1, ma.SR*time) and then I would be happy with a merge.

image image image

marchingband commented 8 months ago

Awesome! This is my first ever PR so I'm considering getting these graphs printed onto a shirt :)

sletz commented 8 months ago

@marchingband waiting for the proper documentation of smoothq(time, q, tar) (tar parameter is not documented). Can you have a look ?

marchingband commented 8 months ago

I copied the way that the other smooth functions are documented, tar stands for target, which isn't meant to be manually passed to the function. How should I fix this up?

sletz commented 8 months ago

OK, I was confused here, so nothing todo.

sletz commented 8 months ago

Thanks, merged in https://github.com/grame-cncm/faustlibraries/commits/master.

marchingband commented 8 months ago

How often does this repo get merged into grame-cncm/faust.git ?

sletz commented 8 months ago

Just done here: https://github.com/grame-cncm/faust/commit/53571fbd9a29d1c0fff44717561c26716434d0a0.