getSampleRate() returns zero in setStateInformation()

Hello,
like in subject: getSampleRate() returns 0 in setStateInformation().
In the documentation there is written:

    This can be called from your processBlock() method - it's not guaranteed
    to be valid at any other time, and may return 0 if it's unknown.

OK. But then how to get proper sample rate in setStateInformation()?
Sometimes it’s very important to set other parameters from saved parameters.
Do I need to check if getSampleRate() returns zero, and if yes then to set some flag to recall setStateInformation() from prepareToPlay(), or what?

Definitely don’t call any of these methods yourself. The prepareToPlay and setStateInformation are callbacks, that you implement and that will be called by the host whenever it seems fit.

You can save the sampleRate from prepareToPlay into a member variable.

But actually you should design your code to be agnostic towards samplerate, since next time the user opens a session, there is no guarantee, that the samplerate is in any way related to the samplerate last time.

1 Like

OK, great thanks for your support.
But how to design code to make things like attack time or release time to be agnostic towards sample rate? I don’t thing it’s good idea.
But in some way I need to make my attack/release slider to be saveable, so I need sample rate.

You store the attack and release as time as seconds and calculate in your processBlock or somewhere those as samples…

4 Likes

It’s interesting idea. I need to consider that. Thanks.
But wait. I actually already do that. I save attack/release as microseconds. And I calculate them to sample when I recall saved parameters, but it happens in setStateInformation() so I still end at the same point - I need to know sample rate in setStateInformation()

so don’t…
it’s not that expensive to calculate this on your processBlock.
it’s also not safe even if you get sample rate available in the setStateInformation. you’re not guaranteed it’ll be called from the audio thread. and if you have a global variable you “calculate” during the state and it’s used on your processBlock it’s NOT thread safe… so you might end up having some pops or even crashes (div by zero, overflows)…

Also, what happens if the user change session sample rate? if you’re locked to a samplerate the preset will now be incorrect…

  • save parameters in sample-rate agnostic values
  • calculate them as sample on the processBlock
  • if you need to have buffers/allocations, do them on the prepareToPlay and allocate your worst case scenario (eg. max needed size for most extreme parameter value).
2 Likes

great thanks for your deep explanation. It’s very handy :slight_smile:

OK ttg, I have some thoughts in subject.

Ok, but even if I calculate AttackInSeconds to AttackInSamples in the processor block I still need to be able to change AttackInSeconds outside of audio thread (for example by some Slider). That’s why to ensure thread safety my AttackInSeconds is std::atomic<float> variable.
But if I calculate them outside of audio thread I still assign calculations to AttackInSamples which is also std::atomic<float>. So untill I have sample rate propery defined my audio thread is safty - no matter if I calculate it inside or outside the proccessBlock.
Am I right? Please correct me if I am wrong.

Other thing is efficiency.
You told:

I calculate my AttackInSamples by:
AttackInSamples= exp( 0.435f /( AttackInSeconds * sampleRate * 0.001f) );

And I’ve made some small tests with calculation it in proccessBlock. You are right it’s not “that” expensive. But if I have a lot of other calculations I try to be as fast as possible. So I still claim to calculate AttackInSamples outside of processBlock().
That’s why I wonder if is it OK to call my saved parameters in prepareToPlay() where I have always sample rate defined. Is it good idea?

You tried it by calculating it just once per processBlock call, and not for each sample, right? Recalculating it for each sample would be useless because the parameter values are not expected to change during the processBlock call in Juce based code.

1 Like