Hi Jucers! I started learning C++ and Juce a couple months ago. So far it’s been a great experience — the tutorials and documentation are very well-written, and I’ve been able to get things working pretty well. I’m developing a MIDI plugin right now, and I’d like to run some of my design decisions past you more experienced people, to see if they make sense.
1 — I’m using an APVTS for my parameters. I’m wrapping this in a custom State object, which gets passed by reference to most of my Components, so they can access the parameters. The object also includes pointers to the individual parameters, so I can read their normalized values quickly with get() or getIndex(), or set them with =.
2 — Sometimes processBlock needs to trigger some audio parameter changes or other time-consuming work. I’ve been avoiding making these changes directly from that function, since I’m not sure whether they may block. So based on some advice I’ve seen here, I’ve used readerwriterqueue to set up a few non-blocking FIFO queues. I can push a “message” to them from processBlock. There’s a queue for each type of message I may need to send.
Then I have a separate juce::Timer, which I start in prepareToPlay. It repeatedly looks for new messages in these queues, and responds if necessary. I didn’t want to run this timer in one of the UI components, because it needs to still function when the plugin editor is closed.
I do have a second timer in the main UI component, for when I need to update the UI based on the player state. I generally trigger these updates by setting std::atomic values in processBlock, and reading them in the timer callback.
3 — Sometimes I need to trigger an audio parameter change when another parameter changes. So I use addListener on the parameter, check the parameter index/value, and push a message onto one of my queues if necessary. The addListener docs state that you can use AsyncUpdater for this, but the AsyncUpdater docs say to beware of using it from an audio thread, so I’ve avoided this.
4 — So far I haven’t run into any issues with processBlock taking too long. But is there a typical way to measure its performance, to ensure that I’m not doing too much work? Or just run it on a slow machine and see if it crashes? I’m already trying to make sure I don’t make any blocking calls.
Thanks to anyone reading this.