I am a deep user of JUCE, but when I use the dsp module, I feel it is not very comfortable to use. One of the most important reasons is that the code style of the dsp module is too different from other JUCE modules. Let’s use the new “Panner” class as an example. The Panner::process method (and all other similar methods of the dsp classes) uses a ProcessContext template type as a parameter. However, using the template type will bring many negative effects. One of them is that because the actual type of the parameter is unknown, the doxygen documentation will unable to locate any useful information of the type:
As you can see, this type is grayed out and is not clickable or navigable. However, it is clear that this type is not arbitrary, it needs to have certain conditions (such as having certain methods or properties). To make matters worse, not only does doxygen fail to provide me with this information, nor is it provided in the comments. In other modules of JUCE, first of all, I did not see a method that uses a template as a parameter (I also don’t like this approach. All such practices can theoretically be achieved through abstract classes + pure virtual functions + inheritance. This kind of approach is better for ease of use and readability), and even if there are, the comments will specify in detail what conditions are required for the type.
This is not the whole problem. When neither the type itself nor the comments provide me with information on how to use it, I think the only solution is probably to read the implementation of this method, until I see such an implementation. . .
template <typename ProcessContext>
void process (const ProcessContext& context) noexcept
{
const auto& inputBlock = context.getInputBlock();
auto& outputBlock = context.getOutputBlock();
const auto numInputChannels = inputBlock.getNumChannels();
const auto numOutputChannels = outputBlock.getNumChannels();
const auto numSamples = outputBlock.getNumSamples();
jassert (inputBlock.getNumSamples() == numSamples);
ignoreUnused (numSamples);
if (numOutputChannels != 2 || numInputChannels == 0 || numInputChannels > 2)
return;
if (numInputChannels == 2)
{
outputBlock.copyFrom (inputBlock);
}
else
{
outputBlock.getSingleChannelBlock (0).copyFrom (inputBlock);
outputBlock.getSingleChannelBlock (1).copyFrom (inputBlock);
}
if (context.isBypassed)
return;
outputBlock.getSingleChannelBlock (0).multiplyBy (leftVolume);
outputBlock.getSingleChannelBlock (1).multiplyBy (rightVolume);
}
The combination of template type and “auto” type automatic derivation makes this code completely unreadable. All positioning, navigation, auto-complete functions in the IDE are all unavailable here. I think this is very unfriendly to users.
I have a few suggestions that you should seriously consider:
- Change the template parameters to use “abstract class + pure virtual function + inheritance” to achieve.
- Make the comments of the dsp module more delicate. There are too many rough comments in this module.
- If the type is not too long, use less “auto” in the implementation to enhance readability.
Of course, I personally hope that all three of my suggestions will be accepted by you. But I know you may have some other considerations. So this post is also a discussion post. Friends who disagree with my suggestions are welcome to raise some objections.