MatN prevents continuous reload of plugins for AppImage + Andrew libaom compile mod
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / pluginlv2client.C
index 289eed4ea98541b06a3df7198e537a0a787628ea..7493d3b22662239c7f606063cad61fd7cb0cbd23 100644 (file)
 #include "pluginlv2ui.inc"
 #include "pluginserver.h"
 #include "pluginset.h"
+#include "preferences.h"
 #include "samples.h"
 #include "track.h"
+#include "tracks.h"
 
 #include <ctype.h>
 #include <string.h>
@@ -95,46 +97,40 @@ PluginLV2ParentUI *PluginLV2UIs::add_ui(PluginLV2ParentUI *ui, PluginLV2Client *
        return ui;
 }
 
-PluginLV2ParentUI *PluginLV2UIs::search_ui(Plugin *plugin)
+PluginLV2ParentUI *PluginLV2UIs::search_ui(int plugin_id)
 {
-       int64_t position = plugin->startproject;
-       PluginSet *plugin_set = plugin->plugin_set;
-       int set_no = plugin_set->get_number();
-       int track_no = plugin_set->track->number_of();
-
        PluginLV2ParentUI *ui = 0;
        for( int i=size(); !ui && --i>=0; ) {
                PluginLV2ParentUI *parent_ui = get(i);
-               if( parent_ui->position != position ) continue;
-               if( parent_ui->set_no != set_no ) continue;
-               if( parent_ui->track_no == track_no ) ui = parent_ui;
+               if( parent_ui->plugin_id == plugin_id )
+                       ui = parent_ui;
        }
        return ui;
 }
 
-PluginLV2ParentUI *PluginLV2UIs::find_ui(Plugin *plugin)
+PluginLV2ParentUI *PluginLV2UIs::find_ui(int plugin_id)
 {
-       if( !plugin ) return 0;
+       if( plugin_id < 0 ) return 0;
        lock("PluginLV2UIs::find_ui");
-       PluginLV2ParentUI *ui = search_ui(plugin);
+       PluginLV2ParentUI *ui = search_ui(plugin_id);
        unlock();
        return ui;
 }
 PluginLV2ParentUI *PluginLV2Client::find_ui()
 {
-       return PluginLV2ParentUI::plugin_lv2.find_ui(server->plugin);
+       return PluginLV2ParentUI::plugin_lv2.find_ui(server->plugin_id);
 }
 PluginLV2ParentUI *PluginLV2ClientWindow::find_ui()
 {
-       return PluginLV2ParentUI::plugin_lv2.find_ui(client->server->plugin);
+       return PluginLV2ParentUI::plugin_lv2.find_ui(client->server->plugin_id);
 }
 
 PluginLV2ParentUI *PluginLV2UIs::get_ui(PluginLV2Client *client)
 {
        lock("PluginLV2UIs::get_ui");
-       Plugin *plugin = client->server->plugin;
-       PluginLV2ParentUI *ui = search_ui(plugin);
-       if( !ui ) ui = add_ui(new PluginLV2ParentUI(plugin), client);
+       int plugin_id = client->server->plugin_id;
+       PluginLV2ParentUI *ui = plugin_id >= 0 ? search_ui(plugin_id) : 0;
+       if( !ui ) ui = add_ui(new PluginLV2ParentUI(plugin_id), client);
        unlock();
        return ui;
 }
@@ -182,6 +178,7 @@ int PluginLV2Client::load_configuration()
 {
        int64_t src_position =  get_source_position();
        KeyFrame *prev_keyframe = get_prev_keyframe(src_position);
+       if( prev_keyframe->is_default ) return 0;
        PluginLV2ClientConfig curr_config;
        curr_config.copy_from(config);
        read_data(prev_keyframe);
@@ -198,16 +195,16 @@ void PluginLV2Client::update_gui()
        load_configuration();
        if( config.update() > 0 ) {
                gui->update_selected();
-               update_lv2();
+               update_lv2(LV2_UPDATE);
        }
        gui->unlock_window();
 }
 
-void PluginLV2Client::update_lv2()
+void PluginLV2Client::update_lv2(int token)
 {
        PluginLV2ParentUI *ui = find_ui();
        if( !ui ) return;
-       ui->send_child(LV2_UPDATE, config.ctls, sizeof(float)*config.nb_ports);
+       ui->send_child(token, config.ctls, sizeof(float)*config.nb_ports);
 }
 
 
@@ -250,8 +247,10 @@ void PluginLV2Client::read_data(KeyFrame *keyframe)
                if( !input.tag.title_is(name) ) continue;
                for( int i=0; i<config.size(); ++i ) {
                        PluginLV2Client_Opt *opt = config[i];
-                       float value = input.tag.get_property(opt->get_symbol(), 0.);
-                       opt->set_value(value);
+                       float v = opt->get_value();
+                       float value = input.tag.get_property(opt->get_symbol(), v);
+                       if( value != v )
+                               opt->set_value(value);
                }
        }
 }
@@ -295,27 +294,54 @@ void PluginLV2Client::process_buffer(int size)
 }
 
 int PluginLV2Client::process_realtime(int64_t size,
-       Samples *input_ptr, Samples *output_ptr)
-{
-       if( load_configuration() )
-               update_lv2();
-       init_buffer(size);
-       load_buffer(size, &input_ptr, 1);
-       process_buffer(size);
-       return unload_buffer(size, &output_ptr, 1);
+       Samples **input_ptr, Samples **output_ptr, int chs)
+{
+       int64_t pos = get_source_position();
+       int64_t end = pos + size;
+       int64_t samples = 0;
+       while( pos < end ) {
+               KeyFrame *prev_keyframe = get_prev_keyframe(pos);
+               if( !prev_keyframe->is_default ) {
+                       read_data(prev_keyframe);
+                       update_lv2(LV2_CONFIG);
+               }
+               KeyFrame *next_keyframe = get_next_keyframe(pos);
+               int64_t next_pos = next_keyframe->position;
+               if( pos >= next_pos || next_pos > end )
+                       next_pos = end;
+               int64_t len = next_pos - pos;
+               if( len > block_length )
+                       len = block_length;
+               if( pos + len > end )
+                       len = end - pos;
+               init_buffer(len);
+               for( int i=chs; --i>=0; ) {
+                       input_ptr[i]->set_offset(samples);
+                       output_ptr[i]->set_offset(samples);
+               }
+               load_buffer(len, input_ptr, chs);
+               process_buffer(len);
+               unload_buffer(len, output_ptr, chs);
+               samples += len;
+               pos += len;
+       }
+       for( int i=chs; --i>=0; )
+               output_ptr[i]->set_offset(0);
+       return samples;
 }
 
 int PluginLV2Client::process_realtime(int64_t size,
        Samples **input_ptr, Samples **output_ptr)
 {
-       if( load_configuration() )
-               update_lv2();
-       init_buffer(size);
-       load_buffer(size, input_ptr, PluginClient::total_in_buffers);
-       process_buffer(size);
-       return unload_buffer(size, output_ptr, PluginClient::total_out_buffers);
+       return process_realtime(size, input_ptr, output_ptr,
+               PluginClient::total_out_buffers);
 }
 
+int PluginLV2Client::process_realtime(int64_t size,
+       Samples *input_ptr, Samples *output_ptr)
+{
+       return process_realtime(size, &input_ptr, &output_ptr, 1);
+}
 
 PluginLV2BlackList::PluginLV2BlackList(const char *path)
 {
@@ -357,13 +383,13 @@ PluginClient *PluginServer::new_lv2_plugin()
 {
        PluginLV2Client *client = new PluginLV2Client(this);
        if( client->load_lv2(path, client->title) ) { delete client;  return client = 0; }
-       client->init_lv2();
+       if( client->init_lv2() ) { delete client;  return client = 0; };
        return client;
 }
 
 int MWindow::init_lv2_index(MWindow *mwindow, Preferences *preferences, FILE *fp)
 {
-       printf("init lv2 index:\n");
+       printf("build lv2 index for: %s\n", preferences->lv2_path);
        PluginLV2BlackList blacklist("lv2_blacklist.txt");
 
        LilvWorld *world = lilv_world_new();
@@ -374,12 +400,19 @@ int MWindow::init_lv2_index(MWindow *mwindow, Preferences *preferences, FILE *fp
                const LilvPlugin *lilv = lilv_plugins_get(all_plugins, i);
                const char *uri = lilv_node_as_uri(lilv_plugin_get_uri(lilv));
                if( blacklist.is_badboy(uri) ) continue;
-printf("LOAD: %s\n", uri);
+// TODO It would be nice to print the full path of this particular plugin
+// in case it fails, because the systems' LV2 path might include multiple
+// directories. But function lilv_uri_to_path does not like the uri.
+
+// Don't print the newline, so called functions can concatenate their
+// error to the name.
+               printf("LOAD: %s ", uri);
                PluginServer server(mwindow, uri, PLUGIN_TYPE_LV2);
                int result = server.open_plugin(1, preferences, 0, 0);
                if( !result ) {
                        server.write_table(fp, uri, PLUGIN_LV2_ID, 0);
                        server.close_plugin();
+                       printf(" \n");
                }
        }
 
@@ -387,17 +420,9 @@ printf("LOAD: %s\n", uri);
        return 0;
 }
 
-PluginLV2ParentUI::PluginLV2ParentUI(Plugin *plugin)
+PluginLV2ParentUI::PluginLV2ParentUI(int plugin_id)
 {
-       this->position = plugin->startproject;
-       PluginSet *plugin_set = plugin->plugin_set;
-       if( plugin_set ) {
-               this->set_no = plugin_set->get_number();
-               this->track_no = plugin_set->track->number_of();
-       }
-       else
-               this->track_no = this->set_no = -1;
-
+       this->plugin_id = plugin_id;
        output_bfr = new Condition(0, "PluginLV2ParentUI::output_bfr", 1);
        client = 0;
        gui = 0;