Using the constructor seems reasonable, if you know which file you want to write. If you want the file to be configurable from the plugin editor, you might want to set the logger from the callback of a FileChooser, or after a text editor field is modified. That said, the JUCE Logger may not be a good fit for your use-case, and more general file-writing mechanisms might work better.
You could do something like this:
Keep track of the current level on the audio thread. Every N samples, you can push the accumulated level into a queue (check out JUCE’s AbstractFifo for a wait-free implementation).
Use a Timer to read levels out of the fifo on the message thread, and write them to file.
It’s probably not worth using JUCE’s Logger in this scenario. You can just use File::appendText to add some text to a file. Alternatively, you could use FileOutputStream::writeText (this has the advantage that you only open and close the file once, rather than each time you write to the file).
This will happen automatically when using the methods I described above.
I just wanted to raise thoughts about the use case. If this is intended as a debug mode to tackle a problem (even when it is already rolled out to the customer) you might want to consider just logging on the audio thread as it saves you a hole lot of trouble.
That said: as reuk wrote a fifo queue populated by the audio thread and worked by the message thread or a different one is the safe way to go. When implementing the queue, make sure to push only the input/output value into the queue to avoid allocations. Don’t push the entire log message – that will allocate the string stuff on the heap.
Depending on your scenario take into consideration, that AbstractFifo only allows for one thread at a time to add stuff while one thread at a time removes/receives stuff. That might be an important constrain when you are multi threading your audio rendering.
I would need to look into the message thread, in this case. This is also new to me. I’ll look up the documentation – but I don’t suppose either of you could suggest some resources to get a better understanding of the message thread?
The message thread is the “main” thread, which will be used to process most of the events related to your plugin’s UI (mouse movement, keyboard input, window management etc.). It’s also the thread that will be used to run callbacks from Timer instances. The vast majority of Component member functions must be called from the message thread.
The message thread will always exist, and has fewer constraints than the realtime/audio thread. If you know that a particular operation is too expensive to run on the audio thread, but is still fairly fast (a few milliseconds), then it’s probably a good idea to run it on the message thread.
Create a juce::Timer (either derive your AudioProcessor from Timer, or create a whole new Timer object).
Override timerCallback. Inside this function, read from your FIFO, and write the values to file.
For an example of a similar pattern, take a look at the MidiLoggerPluginDemo example. In this example, there’s a queue of MIDI messages (MidiQueue). Messages are added to the queue in the plugin’s processBlock. The plugin’s AudioProcessor also implements Timer. In the timerCallback, any new messages are removed from the queue, and then used to update the UI.
For your use-case, you can do something very similar, but instead of writing MIDI messages to the queue, you can write the audio buffer amplitude; and instead of updating the UI, you can write directly to file.