free-audio / clap

Audio Plugin API
https://cleveraudio.org/
MIT License
1.73k stars 98 forks source link

Why is params->flush() allowed to be called when the plugin is active? #296

Closed SamWindell closed 1 year ago

SamWindell commented 1 year ago
   // Flushes a set of parameter changes.
   // This method must not be called concurrently to clap_plugin->process().
   //
   // Note: if the plugin is processing, then the process() call will already achieve the
   // parameter update (bi-directional), so a call to flush isn't required, also be aware
   // that the plugin may use the sample offset in process(), while this information would be
   // lost within flush().
   //
   // [active ? audio-thread : main-thread]
   void(CLAP_ABI *flush)(const clap_plugin_t        *plugin,
                         const clap_input_events_t  *in,
                         const clap_output_events_t *out);

I'm probably missing something but it feels like such a 'gotchya'.

It means that there 2 locations for event processing - and handling 2 locations for it is considerably more complicated than a single location (I'm finding this to be the case due to the nature of the lock-free queue structures I am using for GUI->audio communication).

I'm trying to think of the easiest-to-maintain solution for handling flush() when active. Am I missing something if I just pretend I am the host and call my own process() callback but with 0 for number of frames?

Do you have any other advice?

abique commented 1 year ago

Why is params->flush() allowed to be called when the plugin is active?

To avoid calls of process() with 0 samples.

abique commented 1 year ago

Please don't create issues for asking questions, use the discussion instead.

abique commented 1 year ago

See example implementation: https://github.com/free-audio/clap-plugins/blob/main/plugins/core-plugin.cc#L643

SamWindell commented 1 year ago

Noted, I'll use discussion next time.

Thanks for the link. It looks like you have a gui-to-audio queue that contains only parameter messages. That seems like the solution I should go for. My queue currently contains many types of message some of which should only be handled in process() instead of flush().