-
Notifications
You must be signed in to change notification settings - Fork 193
Description
This is a write-up of something I have been pondering for quite some time, now: One of the larger problems with Mozzi is that in order to change something in the config (and the need to do so is not uncommon at all), you have to modify config files in the library itself. To spell out some of the problems with that:
- It's really unfriendly to new users
- Dependent projects (using Mozzi) that require a certain config have to pass the same problem to their users
- It's really annoying when working on several projects in parallel
- It prevents us from having automated testing coverage on non-default configuration options such as stereo output
That problem has been felt, before, so why didn't we fix it, yet?
- Switching to run-time configuration is not an option (or at least not for everything), for performance and code-size concerns
- We cannot currently allow users to e.g. customize
AUDIO_RATEat the top of their sketch
Why can't we have the latter? Compilation units. For a very rough summary, every .cpp-file is compiled, separately, and only in a final stage everything is linked together. One such .cpp-file is the user's sketch. Another, for example is MozziGuts.cpp. Both also include several common .h-files, but importantly, where they make use of defines such as AUDIO_RATE, this has to match in all compilation units. If AUDIO_RATE was defined at the top of the user-sketch, the MozziGuts.cpp compilation unit would not "see" that define. The current way to make things work, is thus to have both MozziGuts.cpp and the user sketch include a common configuration file. Due to the way the arduino build system works (I won't go into details, mostly, because I don't have them at the top of my head, but I did investigate, before), this common configuration file can only reside in the library folder itself. -> The situation we are in.
So what's the alternative? Putting everything into a single compilation unit. Note this does not mean a single code file, but rather than having MozziGuts.cpp include MozziGuts.h, we'd have MozziGuts.h include (a renamed) MozziGuts.hpp (and the same for all other .cpp files inside Mozzi). In effect, starting with the user sketch as the first file the preprocessor will lump all #included code files together into one big file, and compile that in a single go. Thus a #define near the top of the user sketch will affect all Mozzi code files, too.
What are the drawbacks of that plan?
- Compilation times may go up a bit, because any change in the user sketch will require a recompilation of everything inside Mozzi. I don't really see this as an issue, though. Mozzi code size is not that huge in the first place. The majority of compilation times "heavy" platforms such as ESP32 is spent in other libraries that will not be affected.
- It may not be technically trivial: Importantly we need to make sure, local variables and function names in the Mozzi .cpp files do not clash with user code, and not with locals in other .cpp files inside Mozzi, either. All of that should be fixable, somehow, possibly using namespaces or some-such. However, it may take some time to get there. This, in turn, may mean it will be difficult to address other, unrelated fixes and additions to Mozzi, without ending up in a terrible mess.
- Simple sketches should continue to work, unchanged, but, importantly, sketches consisting of more than one .cpp-file, themselves, will need extra effort. This is actually my biggest concern, but in order to ever finish this write-up at all, I'll detail my thoughts on that in a separate comment (hopefully, within a few days at most).
- Users who have already done some customizations to their Mozzi config will have to re-do those in their sketches. In other words, this is not going to be fully backwards compatible.
What are some side-benefits?
- In theory the compiler should be able to perform more optimizations. Whether that works out remains to be seen.
What else should we worry about?
- Since we're already breaking existing custom configurations, we should seize the opportunity and do some cleanup, there. Importantly, what I have in mind is to use the same configuration defines across all platforms (although not all of them will be supported, everywhere). I'll post details on that, separately, as well. It's not directly related to the plan outlined, here, but should be addressed at the same time, to keep the phase of transition short, and should thus also be mostly planned and agreed on, before we actually start doing anything.
So what will this mean for user sketches? Sketches using the default config will remain 100% unchanged. Others might look like:
#include <MozziCustomConfig.h>
#define AUDIO_RATE 32768
#define AUDIO_CHANNELS 2
#define AUDIO_CHANNEL_1_PIN 5
#include <MozziGuts.h> // this line and everything below unchanged
So, as indicated, I'll write up some further details over the coming days, but of course I'd also like to hear your thoughts on the general plan. Also, what else has always annoyed you about Mozzi, but wasn't quite fixable in a backwards compatible way? Now might be the time to plan that, too.