Code review? (Ramp)

Calling sin every process call will make your code 10x slower than it needs to be. Rack has a sin aproximation built in.

1 Like

You could tidy a bit by assigning the interpolate variables out of scope.

float time = params[TIME_PARAM].getValue(), 
      voltFrom = params[VFROM_PARAM].getValue(),
      voltTo = params[VTO_PARAM].getValue(), 
      interp = params[INTERP_PARAM].getValue();

outputs[VOUT_OUTPUT].setVoltage(interpolate(gc, time, voltFrom, voltTo, interp);

Not sure if there is another way around not using nested statements.

@lomasmodules I’ll look into the 1/sampleTime again tomorrow and investigate the ! operator. 8 arrays are working now after many crashes and vague errors :slight_smile: lerp the knob is what I’ll try.

@Coirt Ah, polyphony, that’s why it sometimes works and then in an other module not. Would it be useful to add polyphony to a ramp? Regarding tidying up, somehow I always end up with “black pages” of code :wink:

@Squinky The cos and pow and thinking about other blending functions like logistic-sigmoid is why I looked at simd. I’ll look into the approixmated one. Currently it does .75us with all 8 ones running on an 8 year old AMD athlon under win10.

Thank y’all, Cheers

Well if you wanted combine inputs you could use polyphony to sum, but there might be some conflict if it was full poly. Probably just better to have it full poly rather than 2 channel poly. If it was full poly then the extra in port would probably be a must from a UX stand point, unless someone would read a manual they may not realise that function exists on the module.

It is useful to have poly but with regards to params you can’t have different settings across all channels from controlled by 1 knob, no choice but to be the setting across all poly channels.

Regarding inputs, decided to keep it monophonic and with just one input.

The matter with 1/sampleTime was a bug in my logic. I connected the end signal to the stop input, then the pulse generator never times out. Manually pulling the signal down on stop works fine.

Where can I find the faster cos approximation?

pow has been implemented so far in dsp/approx.hpp

the dsp/approx.hpp seems only do pow(2,x), not pow(x,y)?

Edit: moved the code to https://github.com/Moaneschien/4rack Will have to do some work on the knobs now.

Thanks,

There is a simd cos approximation in /include/simd/sse_mathfun.h

I don’t know if there is a single float version.

I’ve always used an interpolating lookup for all fancy functions. It’s not as fast as some of the approximations, but it does work for any function, and is always fast enough. If you remember your high school math it’s easy to do.

just adding using simd::float_4; made it ~30% faster as well on ideling and all interpolations. Couldn’t see no difference wit simd::cos, then again I only have the engine cpu meter to observe,

Thanks, I’ll investigate more,

Ingo

Cpu meters are good enough for gross things. If the trig function isn’t a critical path, then you don’t need to worry.

the difference you’ll notice is when you’re running multiple parallel operations. executing simd::cos(1.0f) essentially runs four parallel instances of cos(1.0f). if you’re doing math on four in parallel, you’ll see a much better savings:

float_4 v;
v[0] = 1.0f;
v[1] = 0.9f;
v[2] = 0.8f;
v[3] = 0.7f;
v = simd::cos(v);

note that accessing the individual float values is still a bit expensive, but if you load up float_4 values and do the math with float_4 as much as possible, you’ll see a significant gain: especially when executing 4 paths in parallel.

if you have the Synthetic FX (non-free), you can see this in action by using Curds or Whey, where up to 64 Biquad operations are occurring for every step (16x polyphony and a customized Biquad making 4 parallel operations).

it makes quite an improvement if done correctly.

It’s not just simd. I replaced the scalar trig functions in the AS mixer with scalar lookup tables and it was 8 times faster! Every plugin I’ve improved was significantly slowed down by trig functions. Befaco Even VCO, the old Fundamental VCO-1. sin and cos are just really slow, at the resolution mandated by IEEE math spec.

Insightfull,

Thanks.

1 Like

Just been poking in your code & docs a bit. Only calculating every 4 samples is a nice one I’ll try.

x^y = 2^{y \log_2 x}

Haha. Sometime we need to look at Wikipedia when the answer isn’t on stack overflow!

like @Squinky I use a lot LUTs, everywhere It’s a long time choice coming from reading Chamberlin book years ago

And of course I have also big jumps in the updates of params (4 -> 64 samples) + smoothers

I still have that book!

Yeah, I use that trick in almost every module. I think you will like it. Have you seen the paper on efficient plugins on the github? It’s pretty good, imho.