Can't cast sfloat to float
-
Just trying to use the below smoothed parameter inside snex. I am seeing
Can't cast sfloat to float
error.Smoother for Snex Parameters
@dustbro Yeah, that shouldn't be necessary. BTW, there's a inbuilt smoothed float type in SNEX, which might be better (from a design perspective it's more el...
Forum (forum.hise.audio)
template <int NV> struct snex_node { SNEX_NODE(snex_node); sfloat amount = 0.0f; sfloat getSamples(sfloat input) { input = amount * input; return input; } // Initialise the processing specs here void prepare(PrepareSpecs ps) { // uses the sample rate from the processing specs to create a 100ms ramp. amount.prepare(ps.sampleRate, 100.0); } // Reset the processing pipeline here void reset() { // reset the ramp when this is called amount.reset(); } // Process the signal here template <typename ProcessDataType> void process(ProcessDataType& data) { for(auto ch: data) { for(auto& s: data.toChannelData(ch)) { s *= amount.advance(); s = getSamples(s); } } } // Process the signal as frame here template <int C> void processFrame(span<sfloat, C>& data) { for(auto& s: data) { s = getSamples(s); } } // Process the MIDI events here void handleHiseEvent(HiseEvent& e) { } // Use this function to setup the external data void setExternalData(const ExternalData& d, int index) { } // Set the parameters here template <int P> void setParameter(double v) { if (P == 0) { amount.set((float)v); } } };
-
There are a few issues with the code. First of all the compile errors says that you can't convert a
sfloat
object (which is more than just the number) to afloat
number (at least implicitely, it might be possible that I'm allowing an explicit cast when the users expresses the intention).So you need to change the return type of
getSamples
tofloat
and then callamount.advanc()
inside the function to get the next smoothed float value.This will make it compile and work somewhat, but the next problem is that you're using a single ramp object for all channels which will create a discontinuity and zipper noises.
You're basically iterating over every channel and thus treat the channels as if they would be a single continous signal which is not the case so if the
sfloat
starts ramping, it will distribute the ramp state over multiple channels and the next time theprocess
function is called, the state for each channel will not match the value where it was last time.There are multiple solutions for this:
- Resort to frame-processing, use a single ramp object, call
advance()
once per frame and then use this value for every channel's sample. This will add the overhead of converting the channel data arrays to interleaved frames so if the rest of your process is trivial (a few simple math operations), this might be the performance bottleneck. - Create an array of
sfloats
and then use a ramp object for each channel. This might be inefficient because you're calculating the same ramp value for each channel, but you don't have the memory juggling required to convert the channel data to interleaved frames. - If you don't need sample-accurate smoothing and might get away with a once per buffer smoothed value (especially if you put the node into a
fix32
container or something, you could just create a single ramp value at the start of process() and then use this for all calculations. In that case you will have to divide thesampleRate
with theblockSize
in theprepare
callback so that the ramp time is still valid (if you're calling it once per block, you are effectively reducing the sample rate that the ramper operates in).
- Resort to frame-processing, use a single ramp object, call
-
@Christoph-Hart Now I get it, That's very helpful, Thank you so much!