Getting Unique ID per-plugin Instance?:

Is there a best accepted practice for getting a unique ID for each instance of a plugin that has been instantiated from the DAW by a user?

I’m in a situation where I need to debug the interactions between multiple instances of a plugin, where all instances are sharing (via SharedResourcePointer) a struct, and I want to put some unique ID in my DBG() strings to clarify read/write activity when there are multiple instances of my plugins running. I had thought that I might just use juce::Uuid().toString() but this turns out to produce the same UID among all instances …

Is it enough to just use the address of my AudioProcessorEditor object, or is there really some better way to do it?

1 Like

UUID constructor should create a new one each time it’s called (that’s the whole purpose of it). If it looks like it creates the same UUID multiple times, it’s very likely you’ve just found an important clue to the bug you’re trying to find!

1 Like

Hehe, actually I did just have the ‘debug function’ I’d used to generate the UUID in the wrong place, so yeah, burned my own finger … anyway I just decided to prefix all DBG messages that are relevant to me with this:

DBG(String::formatted("PLUGINPROCESSOR %p", this));

… and that works out okay for debugging, with the bonus that I have the addresses at hand for later use in lldb …

I thought there might be a JUCE-style per-Plugin object way of doing it, but I guess this is it.

Another way of identifying exact plugin instances could be overriding AudioProcessor::updateTrackProperties and store the track name retrieved from there. This can help you identifying the actual instance in your test session. This however requires that

  • Your host correctly reports track names (most I tested in the recent past do so but not all)
  • You are working with a test session that has exactly one instance of the plugin in question per track and properly named tracks
  • You have access to the stored processor track name variable from where you want to emit your debug messages

Yeah in my case its in order to differentiate between multiple instances of the plugin, strictly for debugging purposes … now that its all thread’ed out it of course makes sense to me to just use the pointer to the processor/editor object, but I had wondered if there was some more JUCE-aligned method of making this distinction. Anyway String::formatted(“%p”, this) works okay for now …

Given that some hosts allow separate (possibly duplicated) plugins on multiple regions in a track, the track info might not be sufficient for their needs. We have that in our plugin, and it makes it hard to see which plugin is being debugged at any instant without using their method of using the pointer to the Processor instance to identify them. So that’s what we do, as well.

I’d probably address this by adding something like this at the bottom of my AudioProcessor:

private:
    inline static std::atomic<int> instanceCounter { 0 };
    const int thisPluginInstance = instanceCounter++;

Now, every time a plugin instance is constructed, it’ll get a unique monotonically-increasing ID. It should be easy to differentiate plugin instances by checking the value of thisPluginInstance.

5 Likes

For sure, the track name is no real unique identifier – just wanted to mention it as an option where it might help to find out about the actual track a plugin instance is on, this might be helpful in some debugging contexts where per-region plugin instances are a rather exotic edge case I’d say :wink:

Knowing which track an instance is assigned to can e.g. help if you are debugging what happens if you add/remove a certain instance to/from the session. In the end it always depends on what exactly you are trying to debug.

1 Like

Thanks for the tips guys.

I ended up just using the AudioProcessorEditor’s pointer as a unique identifier for the plugin instance, which is reported to testers in the form of a tooltip containing version and git hash ID alongside the unique pointer value, but at some point we may end up adding an atomic instance counter to the already-existing SharedResourcePointer<SharedParams> sharedParams structure that is being shared between instances, so that plugins can be aware of how many other instances are running, when its necessary.