Which are the SampleTypes?

Maybe this is a very stupid questions but the SampleType used in the dsp modules. Which are these?

In the documentation it says

“The type of a single sample (which may be a vector if multichannel).”

But surely there must be a lot of restrictions on which types to use?
Are these documented somewhere? I couldn’t find anything further in the documentation.

Juce uses floating point numbers, so your choices are float or double.
There is no fixed point processing in juce.

floats or doubles can be used.

Thanks, so are these two all the types permitted?

Not that I need anything else right now but from a theoretical point of view are the restrictions on types documented somehow? As an example one could get the idea to use fixed point for old school processing and stuff like that… I mean it looks very generic, like a template type.

I did a small test with one of the DSP classes (StateVariableTPTFilter), and using a custom numeric type was a straight no-go with that, it’s been limited to work with only floats and doubles, as far as I can tell. While that’s not very “template-like”, it’s still a valid use case for templates because more than 1 allowed type is involved.

When compiled on modern macOS and Windows architectures is float in these cases 64-bit? Since 64-bit is the standard nowdays in processing…

Otherwise, if I need double for 64-bit processing how can I assert this is not broken somewhere within the Juce framwork?

This is merely out of curiosity, but since there’s a lot of talk on 64-bit from plugin makers and a lot of them use Juce it’s interesting to know.

No, the compiler developers didn’t repeat that mistake: a float is a float is 32 bit and a double is 64 bit.

You mustn’t confuse architecture bit size with processing precision. The advantages to move the platform to 64 bit was to have a wider address bus. This helps for large storage (and speed, since 64 bit values fit in the address bus).
Some used this to advertise double processing precision, but when a plugin says it’s 64 bit it usually means it runs on 64 bit architectures without a backward compatibility layer.

If they support double they usually say that explicitly.

1 Like

For the sake of completeness, beneath float and double, some classes (dsp::IIR at least) also work with dsp::SIMDRegister<float> and dsp::SIMDRegister<double>, allowing you processing of multiple channels loaded into a simd register with a single filter instance.

However, this is a quite special case, which only makes sense in a few special situations :slightly_smiling_face:

1 Like

Ah, yes. I mixed up those a bit although I know the difference in theory.

It’s the kind of considerations mentioned below quoted from a dsp forum I was curious of regarding Juce. That is, if I set an AudioBuffer<double>, am I guaranteed all processing will be at least in double precision in any Juce module as of Juce 6? Since the old AudioSampleBuffer was equal to AudioBuffer<float> I was thinking there might be conversions or truncations from double to float sometimes in older modules.

EEE float singles only provide about 24 bits of mantissa. But many DSP/filtering algorithms (IIR biquads with poles/zeros near the unit circle, etc.) require far more than 24 bits of mantissa for intermediate computational products (accumulators, etc.), just to get final results accurate to near 16 or 24 bits. For these types of algorithms, 32, 40 and 48-bit scaled integer accumulators were often used with DSPs that had no FPU.

But on many current processor implementations (for PCs, smartphones, etc.), the double precision FPU is far faster than trying to use 32 or 64 bit scaled integer when your algorithm needs to have more than 24 bits of intermediate product.

To prevent trashing the data cache, the raw data can be in short integer or single precision float format, while only the more local computational kernel might use a higher resolution format. But if you are sharing intermediate computation results between DSP modules, the interchange protocol between modules may also benefit from a higher resolution (more than 24-bit mantissa) bus or data format.

The main thing is to override “supportsDoublePrecisionProcessing()” to return true. Then the host will call void processBlock (juce::AudioBuffer<double>&, MidiBuffer&) instead of void processBlock (juce::AudioBuffer<float>&, MidiBuffer&), if the host supports it at all.

For filters it is indeed a good idea to have the state in double numbers, but have the input and output data as float. The precision in the audio data is in no relation to the additional memory cost IMHO. But that is on you and your user base to decide.

1 Like