From e667c861ce6c22a055c9afdf01d80247df18ae9b Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 7 Feb 2015 15:39:56 +0100 Subject: LV2: Port to new urid map extension. Major cleanup. --- lv2/input_lv2.cc | 22 ---- lv2/lv2.cc | 313 +++++------------------------------------------------ lv2/lv2_instance.h | 5 +- lv2/output_lv2.cc | 2 - lv2/output_lv2.h | 1 - 5 files changed, 29 insertions(+), 314 deletions(-) diff --git a/lv2/input_lv2.cc b/lv2/input_lv2.cc index d995e75..7c3c6ec 100644 --- a/lv2/input_lv2.cc +++ b/lv2/input_lv2.cc @@ -99,11 +99,6 @@ event_t *InputLV2::run(size_t pos, size_t len, size_t *nevents) list[listsize].offset = ev->time.frames; listsize++; } - /* - start_frame = ev->frames; - plugin->frame = 0; - plugin->play = true; - */ } ev = lv2_atom_sequence_next(ev); } @@ -115,20 +110,3 @@ event_t *InputLV2::run(size_t pos, size_t len, size_t *nevents) void InputLV2::post() { } - -#ifdef TEST_INPUT_LV2 -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: -#include "test.h" - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). - -TEST_END; - -#endif/*TEST_INPUT_LV2*/ diff --git a/lv2/lv2.cc b/lv2/lv2.cc index 3aeb5f0..41a5d48 100644 --- a/lv2/lv2.cc +++ b/lv2/lv2.cc @@ -25,24 +25,20 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include +#include #include #include #include "lv2_gui.h" - #include "lv2_instance.h" #include -#include - -#define NS_ATOM "http://lv2plug.in/ns/ext/atom#" -#define NS_DG "http://drumgizmo.org/lv2/atom#" +#define DRUMGIZMO_URI "http://drumgizmo.org/lv2" +#define NS_DG DRUMGIZMO_URI "/atom#" -/* - * Stuff to handle DrumGizmo* transmission from instance to GUI. - */ +// Stuff to handle DrumGizmo* transmission from instance to GUI. static LV2_DrumGizmo_Descriptor dg_descriptor; static DrumGizmo *dg_get_pci(LV2_Handle instance) @@ -51,56 +47,6 @@ static DrumGizmo *dg_get_pci(LV2_Handle instance) return dglv2->dg; } -/* - * Stuff to save/restore plugin state. - */ -/* -void dg_save(LV2_Handle instance, - LV2_State_Store_Function store, - void* callback_data, - uint32_t flags, - const LV2_Feature *const * features) -{ - DGLV2 *dglv2 = (DGLV2 *)instance; - printf("dg_save\n"); - - std::string config = dglv2->dg->configString(); - printf("%s\n", config.c_str()); - - store(callback_data, - dglv2->urimap->uri_to_id(dglv2->urimap->callback_data, - NULL, NS_DG "config"), - config.data(), config.length(), - dglv2->urimap->uri_to_id(dglv2->urimap->callback_data, - NULL, NS_ATOM "String"), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); -} - -void dg_restore(LV2_Handle instance, - LV2_State_Retrieve_Function retrieve, - void* callback_data, - uint32_t flags, - const LV2_Feature *const * features) -{ - DGLV2 *dglv2 = (DGLV2 *)instance; - printf("dg_restore\n"); - - size_t size; - uint32_t type; - // uint32_t flags; - - const char* data = - (const char*)retrieve(callback_data, - dglv2->urimap->uri_to_id(dglv2->urimap->callback_data, - NULL, NS_DG "config"), - &size, &type, &flags); - std::string config; - config.append(data, size); - dglv2->dg->setConfigString(config); - - dglv2->in->loadMidiMap(dglv2->dg->midimapfile); -} -*/ LV2_State_Status dg_save(LV2_Handle instance, LV2_State_Store_Function store, @@ -109,32 +55,22 @@ dg_save(LV2_Handle instance, const LV2_Feature *const * features) { DGLV2 *dglv2 = (DGLV2 *)instance; - printf("dg_save\n"); + + if(!dglv2 || !dglv2->map || !dglv2->map->map) { + // Missing urid feature? + return LV2_STATE_ERR_NO_FEATURE; + } std::string config = dglv2->dg->configString(); - printf("%s\n", config.c_str()); store(handle, - dglv2->urimap->uri_to_id(dglv2->urimap->callback_data, - NULL, NS_DG "config"), + dglv2->map->map(dglv2->map->handle, NS_DG "config"), config.c_str(), config.length() + 1, // Careful! Need space for terminator - dglv2->urimap->uri_to_id(dglv2->urimap->callback_data, - NULL, NS_ATOM "chunk"), + dglv2->map->map(dglv2->map->handle, LV2_ATOM__Chunk), LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); -/* - MyPlugin* plugin = (MyPlugin*)instance; - const char* greeting = plugin->state.greeting; - - store(handle, - plugin->uris.my_greeting, - greeting, - strlen(greeting) + 1, // Careful! Need space for terminator - plugin->uris.atom_String, - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); -*/ - printf("dg_save\n"); - return LV2_STATE_SUCCESS; + + return LV2_STATE_SUCCESS; } LV2_State_Status @@ -145,43 +81,27 @@ dg_restore(LV2_Handle instance, const LV2_Feature *const * features) { DGLV2 *dglv2 = (DGLV2 *)instance; - DEBUG(lv2, "dg_restore begin\n"); - size_t size; - uint32_t type; - // uint32_t flags; + if(!dglv2 || !dglv2->map || !dglv2->map->map) { + // Missing urid feature? + return LV2_STATE_ERR_NO_FEATURE; + } + + size_t size; + uint32_t type; const char* data = (const char*)retrieve(handle, - dglv2->urimap->uri_to_id(dglv2->urimap->callback_data, - NULL, NS_DG "config"), + dglv2->map->map(dglv2->map->handle, NS_DG "config"), &size, &type, &flags); + DEBUG(lv2, "Config string size: %d, data*: %p\n", (int)size, data); if(data && size) { std::string config; config.append(data, size - 1); dglv2->dg->setConfigString(config); - //dglv2->in->loadMidiMap(dglv2->dg->midimapfile); } - - /* - MyPlugin* plugin = (MyPlugin*)instance; - - size_t size; - uint32_t type; - uint32_t flags; - const char* greeting = retrieve( - handle, plugin->uris.my_greeting, &size, &type, &flags); - - if (greeting) { - free(plugin->state->greeting); - plugin->state->greeting = strdup(greeting); - } else { - plugin->state->greeting = strdup(DEFAULT_GREETING); - } - */ - DEBUG(lv2, "dg_restore done\n"); return LV2_STATE_SUCCESS; } @@ -191,42 +111,6 @@ static LV2_State_Interface dg_persist = { dg_restore }; -/** A globally unique, case-sensitive identifier for this plugin type. - * - * All plugins with the same URI MUST be compatible in terms of 'port - * signature', meaning they have the same number of ports, same port - * shortnames, and roughly the same functionality. URIs should - * probably contain a version number (or similar) for this reason. - * - * Rationale: When serializing session/patch/etc files, hosts MUST - * refer to a loaded plugin by the plugin URI only. In the future - * loading a plugin with this URI MUST yield a plugin with the - * same ports (etc) which is 100% compatible. */ -#define DRUMGIZMO_URI "http://drumgizmo.org/lv2" - -/** Function pointer that instantiates a plugin. - * - * A handle is returned indicating the new plugin instance. The - * instantiation function accepts a sample rate as a parameter as well - * as the plugin descriptor from which this instantiate function was - * found. This function must return NULL if instantiation fails. - * - * bundle_path is a string of the path to the LV2 bundle which contains - * this plugin binary. It MUST include the trailing directory separator - * (e.g. '/') so that BundlePath + filename gives the path to a file - * in the bundle. - * - * features is a NULL terminated array of LV2_Feature structs which - * represent the features the host supports. Plugins may refuse to - * instantiate if required features are not found here (however hosts - * SHOULD NOT use this as a discovery mechanism, instead reading the - * data file before attempting to instantiate the plugin). This array - * must always exist; if a host has no features, it MUST pass a single - * element array containing NULL (to simplify plugins). - * - * Note that instance initialisation should generally occur in - * activate() rather than here. If a host calls instantiate, it MUST - * call cleanup() at some point in the future. */ LV2_Handle instantiate(const struct _LV2_Descriptor *descriptor, double sample_rate, const char *bundle_path, @@ -234,14 +118,10 @@ LV2_Handle instantiate(const struct _LV2_Descriptor *descriptor, { DGLV2 *dglv2 = new DGLV2; - dglv2->urimap = NULL; + dglv2->map = NULL; for (int i = 0 ; features[i] ; i++) { - printf("DG: feature: %s\n", features[i]->URI); - if (!strcmp(features[i]->URI, LV2_URI_MAP_URI)) { - dglv2->urimap = (LV2_URI_Map_Feature*)features[i]->data; - } - if (!strcmp(features[i]->URI, LV2_STATE__makePath)) { - dglv2->makepath = (LV2_State_Make_Path*)features[i]->data; + if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) { + dglv2->map = (LV2_URID_Map*)features[i]->data; } } @@ -253,57 +133,12 @@ LV2_Handle instantiate(const struct _LV2_Descriptor *descriptor, dglv2->buffer = NULL; dglv2->buffer_size = 0; - /* - char* path = dglv2->makepath->path(dglv2->makepath->handle, - "hello.txt"); - FILE* myfile = fopen(path, "w"); - fprintf(myfile, "world"); - fclose(myfile); - */ - dglv2->dg = new DrumGizmo(dglv2->out, dglv2->in); dglv2->dg->setSamplerate(sample_rate); - // dglv2->dg->loadkit(getenv("DRUMGIZMO_DRUMKIT")); - // dglv2->dg->init(true); return (LV2_Handle)dglv2; } -/** Function pointer that connects a port on a plugin instance to a memory - * location where the block of data for the port will be read/written. - * - * The data location is expected to be of the type defined in the - * plugin's data file (e.g. an array of float for an lv2:AudioPort). - * Memory issues are managed by the host. The plugin must read/write - * the data at these locations every time run() is called, data - * present at the time of this connection call MUST NOT be - * considered meaningful. - * - * The host MUST NOT try to connect a data buffer to a port index - * that is not defined in the RDF data for the plugin. If it does, - * the plugin's behaviour is undefined. - * - * connect_port() may be called more than once for a plugin instance - * to allow the host to change the buffers that the plugin is reading - * or writing. These calls may be made before or after activate() - * or deactivate() calls. Note that there may be realtime constraints - * on connect_port (see lv2:hardRTCapable in lv2.ttl). - * - * connect_port() MUST be called at least once for each port before - * run() is called. The plugin must pay careful attention to the block - * size passed to the run function as the block allocated may only just - * be large enough to contain the block of data (typically samples), and - * is not guaranteed to be constant. - * - * Plugin writers should be aware that the host may elect to use the - * same buffer for more than one port and even use the same buffer for - * both input and output (see lv2:inPlaceBroken in lv2.ttl). - * However, overlapped buffers or use of a single buffer for both - * audio and control data may result in unexpected behaviour. - * - * If the plugin has the feature lv2:hardRTCapable then there are - * various things that the plugin MUST NOT do within the connect_port() - * function (see lv2.ttl). */ void connect_port(LV2_Handle instance, uint32_t port, void *data_location) @@ -320,99 +155,31 @@ void connect_port(LV2_Handle instance, } } -/** Function pointer that initialises a plugin instance and activates - * it for use. - * - * This is separated from instantiate() to aid real-time support and so - * that hosts can reinitialise a plugin instance by calling deactivate() - * and then activate(). In this case the plugin instance must reset all - * state information dependent on the history of the plugin instance - * except for any data locations provided by connect_port(). If there - * is nothing for activate() to do then the plugin writer may provide - * a NULL rather than an empty function. - * - * When present, hosts MUST call this function once before run() - * is called for the first time. This call SHOULD be made as close - * to the run() call as possible and indicates to real-time plugins - * that they are now live, however plugins MUST NOT rely on a prompt - * call to run() after activate(). activate() may not be called again - * unless deactivate() is called first (after which activate() may be - * called again, followed by deactivate, etc. etc.). If a host calls - * activate, it MUST call deactivate at some point in the future. - * - * Note that connect_port() may be called before or after a call to - * activate(). */ void activate(LV2_Handle instance) { + // We don't really need to do anything here. DGLV2 *dglv2 = (DGLV2 *)instance; - //dglv2->dg->run(); (void)dglv2; } -/** Function pointer that runs a plugin instance for a block. - * - * Two parameters are required: the first is a handle to the particular - * instance to be run and the second indicates the block size (in - * samples) for which the plugin instance may run. - * - * Note that if an activate() function exists then it must be called - * before run(). If deactivate() is called for a plugin instance then - * the plugin instance may not be reused until activate() has been - * called again. - * - * If the plugin has the feature lv2:hardRTCapable then there are - * various things that the plugin MUST NOT do within the run() - * function (see lv2.ttl). */ void run(LV2_Handle instance, uint32_t sample_count) { static size_t pos = 0; DGLV2 *dglv2 = (DGLV2 *)instance; - // The buffer is not used anymore - declared NULL in 'instantiate'. - /* - if(dglv2->buffer_size != sample_count) { - if(dglv2->buffer) free(dglv2->buffer); - dglv2->buffer_size = sample_count; - dglv2->buffer = (sample_t*)malloc(sizeof(sample_t) * dglv2->buffer_size); - printf("(Re)allocate buffer: %d samples\n", dglv2->buffer_size); - } - */ dglv2->dg->run(pos, dglv2->buffer, sample_count); pos += sample_count; } -/** This is the counterpart to activate() (see above). If there is - * nothing for deactivate() to do then the plugin writer may provide - * a NULL rather than an empty function. - * - * Hosts must deactivate all activated units after they have been run() - * for the last time. This call SHOULD be made as close to the last - * run() call as possible and indicates to real-time plugins that - * they are no longer live, however plugins MUST NOT rely on prompt - * deactivation. Note that connect_port() may be called before or - * after a call to deactivate(). - * - * Note that deactivation is not similar to pausing as the plugin - * instance will be reinitialised when activate() is called to reuse it. - * Hosts MUST NOT call deactivate() unless activate() was previously - * called. */ void deactivate(LV2_Handle instance) { + // We don't really need to do anything here. DGLV2 *dglv2 = (DGLV2 *)instance; dglv2->dg->stop(); } -/** This is the counterpart to instantiate() (see above). Once an instance - * of a plugin has been finished with it can be deleted using this - * function. The instance handle passed ceases to be valid after - * this call. - * - * If activate() was called for a plugin instance then a corresponding - * call to deactivate() MUST be made before cleanup() is called. - * Hosts MUST NOT call cleanup() unless instantiate() was previously - * called. */ void cleanup(LV2_Handle instance) { DGLV2 *dglv2 = (DGLV2 *)instance; @@ -421,34 +188,8 @@ void cleanup(LV2_Handle instance) delete dglv2->out; } -/** Function pointer that can be used to return additional instance data for - * a plugin defined by some extenion (e.g. a struct containing additional - * function pointers). - * - * The actual type and meaning of the returned object MUST be specified - * precisely by the extension if it defines any extra data. If a particular - * extension does not define extra instance data, this function MUST return - * NULL for that extension's URI. If a plugin does not support any - * extensions that define extra instance data, this function pointer may be - * set to NULL rather than providing an empty function. - * - * The only parameter is the URI of the extension. The plugin MUST return - * NULL if it does not support the extension, but hosts SHOULD NOT use this - * as a discovery method (e.g. hosts should only call this function for - * extensions known to be supported by the plugin from the data file). - * - * The host is never responsible for freeing the returned value. - * - * NOTE: This function should return a struct (likely containing function - * pointers) and NOT a direct function pointer. Standard C and C++ do not - * allow type casts from void* to a function pointer type. To provide - * additional functions a struct should be returned containing the extra - * function pointers (which is valid standard code, and a much better idea - * for extensibility anyway). */ const void* extension_data(const char *uri) { - printf("extension_data(%s)\n", uri); - if(!strcmp(uri, PLUGIN_INSTANCE_URI)) return &dg_descriptor; if(!strcmp(uri, LV2_STATE__interface)) return &dg_persist; return NULL; diff --git a/lv2/lv2_instance.h b/lv2/lv2_instance.h index b4772f6..e050e22 100644 --- a/lv2/lv2_instance.h +++ b/lv2/lv2_instance.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include "input_lv2.h" #include "output_lv2.h" @@ -42,8 +42,7 @@ typedef struct { DrumGizmo *dg; sample_t *buffer; size_t buffer_size; - LV2_URI_Map_Feature *urimap; - LV2_State_Make_Path *makepath; + LV2_URID_Map* map; } DGLV2; #endif/*__DRUMGIZMO_LV2_INSTANCE_H__*/ diff --git a/lv2/output_lv2.cc b/lv2/output_lv2.cc index ef2500b..09999cb 100644 --- a/lv2/output_lv2.cc +++ b/lv2/output_lv2.cc @@ -62,11 +62,9 @@ void OutputLV2::pre(size_t nsamples) { } -#include void OutputLV2::run(int ch, sample_t *samples, size_t nsamples) { if(ch < NUM_OUTPUTS) { - // if(outputPorts[ch].size != nsamples) printf("port.%d nsamples.%d\n", outputPorts[ch].size, nsamples); if(outputPorts[ch].samples) { memcpy(outputPorts[ch].samples, samples, nsamples * sizeof(sample_t)); } diff --git a/lv2/output_lv2.h b/lv2/output_lv2.h index 1b4e8c9..a3a2555 100644 --- a/lv2/output_lv2.h +++ b/lv2/output_lv2.h @@ -55,7 +55,6 @@ public: sample_t *getBuffer(int c); - // sample_t *outputPort[NUM_OUTPUTS]; OutputPort outputPorts[NUM_OUTPUTS]; }; -- cgit v1.2.3