+/*
+ * CINELERRA
+ * Copyright (C) 2016-2020 William Morrow
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
#ifdef HAVE_LV2
#include "bctrace.h"
samplerate = 44100;
refreshrate = 30.;
+ min_block_length = 1;
block_length = 4096;
midi_buf_size = 8192;
schedule.schedule_work = lv2_worker_schedule;
worker_iface = 0; worker_done = -1;
pthread_mutex_init(&worker_lock, 0);
+ pthread_mutex_init(&startup_lock, 0);
+ pthread_mutex_lock(&startup_lock);
pthread_cond_init(&worker_ready, 0);
work_avail = 0; work_input = 0;
work_output = 0; work_tail = &work_output;
}
}
+ if( !nb_inputs || !nb_outputs ) {
+ printf(": Unsupported lv2 plugin, missing audio input or output\n");
+ reset_lv2();
+ return 1;
+ }
- uri_map.callback_data = (LV2_URI_Map_Callback_Data)this;
- uri_map.uri_to_id = uri_to_id;
- features.append(new Lv2Feature(NS_EXT "uri-map", &uri_map));
- map.handle = (void*)&uri_table;
- map.map = uri_table_map;
- features.append(new Lv2Feature(LV2_URID_MAP_URI, &map));
- unmap.handle = (void*)&uri_table;
- unmap.unmap = uri_table_unmap;
- features.append(new Lv2Feature(LV2_URID_UNMAP_URI, &unmap));
+ uri_map.handle = (LV2_URID_Map_Handle)this;
+ uri_map.map = map_uri;
+ features.append(new Lv2Feature(LV2_URID__map, &uri_map));
+ uri_unmap.handle = (LV2_URID_Unmap_Handle)this;
+ uri_unmap.unmap = unmap_uri;
+ features.append(new Lv2Feature(LV2_URID__unmap, &uri_unmap));
features.append(new Lv2Feature(LV2_BUF_SIZE__powerOf2BlockLength, 0));
features.append(new Lv2Feature(LV2_BUF_SIZE__fixedBlockLength, 0));
features.append(new Lv2Feature(LV2_BUF_SIZE__boundedBlockLength, 0));
ui_updateRate = uri_table.map(LV2_UI__updateRate);
samplerate = sample_rate;
- block_length = bfrsz;
options.add(param_sampleRate, sizeof(float), atom_float, &samplerate);
- options.add(bufsz_minBlockLength, sizeof(int), atom_int, &block_length);
+ if( min_block_length > bfrsz ) min_block_length = bfrsz;
+ options.add(bufsz_minBlockLength, sizeof(int), atom_int, &min_block_length);
+ block_length = bfrsz;
options.add(bufsz_maxBlockLength, sizeof(int), atom_int, &block_length);
options.add(bufsz_sequenceSize, sizeof(int), atom_int, &midi_buf_size);
options.add(ui_updateRate, sizeof(float), atom_float, &refreshrate);
printf("lv2: lilv_plugin_instantiate failed\n");
return 1;
}
-
+
+// After instantiate, some plugins require fields to be filled in before
+// activate is called. This is done via ConnectPort, which connects a
+// port to a data structure in the host (CinGG). So these have to be
+// allocated first.
+
+ init_buffer(bfrsz);
+ connect_ports(conf, PORTS_ALL);
+
const LV2_Descriptor *lilv_desc = inst->lv2_descriptor;
worker_iface = !lilv_desc->extension_data ? 0 :
(LV2_Worker_Interface*)lilv_desc->extension_data(LV2_WORKER__interface);
(lilv_plugin_has_feature(lilv, powerOf2BlockLength) ||
lilv_plugin_has_feature(lilv, fixedBlockLength) ||
lilv_plugin_has_feature(lilv, boundedBlockLength)) ? 4096 : 0;
- return 0;
-}
-LV2_URID PluginLV2::uri_table_map(LV2_URID_Map_Handle handle, const char *uri)
-{
- return ((PluginLV2UriTable *)handle)->map(uri);
+ return 0;
}
-const char *PluginLV2::uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
+uint32_t PluginLV2::map_uri(LV2_URID_Map_Handle handle, const char *uri)
{
- return ((PluginLV2UriTable *)handle)->unmap(urid);
+ PluginLV2 *the = (PluginLV2 *)handle;
+ return the->uri_table.map(uri);
}
-uint32_t PluginLV2::uri_to_id(LV2_URI_Map_Callback_Data callback_data,
- const char *map, const char *uri)
+const char *PluginLV2::unmap_uri(LV2_URID_Unmap_Handle handle, LV2_URID urid)
{
- PluginLV2 *the = (PluginLV2 *)callback_data;
- return the->map.map(the->uri_table, uri);
+ PluginLV2 *the = (PluginLV2 *)handle;
+ return the->uri_table.unmap(urid);
}
void PluginLV2::connect_ports(PluginLV2ClientConfig &conf, int ports)
void *PluginLV2::worker_func()
{
pthread_mutex_lock(&worker_lock);
+ pthread_mutex_unlock(&startup_lock);
for(;;) {
while( !worker_done && !work_input )
pthread_cond_wait(&worker_ready, &worker_lock);
void PluginLV2::worker_start()
{
pthread_create(&worker_thread, 0, worker_func, this);
+ pthread_mutex_lock(&startup_lock);
}
void PluginLV2::worker_stop()
title[0] = 0;
memset(&uri_map, 0, sizeof(uri_map));
+ memset(&uri_unmap, 0, sizeof(uri_unmap));
memset(&extui_host, 0, sizeof(extui_host));
wgt_type = LV2_EXTERNAL_UI_URI__KX__Widget;
gtk_type = LV2_UI__GtkUI;