diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2015-02-12 22:15:46 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2015-02-12 22:15:46 +0100 | 
| commit | 9cc885fe6df62f698b72e665ab47f4188db25700 (patch) | |
| tree | 30b87df59dda597e2d01007ad0ebee9e81932d85 | |
| parent | a05a820098a1bd936d4f4a7ea0746defab045c42 (diff) | |
Add new LV2 unit test.
| -rw-r--r-- | test/lv2.cc | 332 | ||||
| -rw-r--r-- | test/lv2_test_host.cc | 377 | ||||
| -rw-r--r-- | test/lv2_test_host.h | 83 | 
3 files changed, 792 insertions, 0 deletions
| diff --git a/test/lv2.cc b/test/lv2.cc new file mode 100644 index 0000000..d38aa06 --- /dev/null +++ b/test/lv2.cc @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            lv2.cc + * + *  Thu Feb 12 14:55:41 CET 2015 + *  Copyright 2015 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo 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. + * + *  DrumGizmo 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 DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include <cppunit/extensions/HelperMacros.h> + +#include <unistd.h> +#include <memory.h> +#include <stdio.h> +#include <arpa/inet.h> + +#include "lv2_test_host.h" + +#define DG_URI "http://drumgizmo.org/lv2" + +/** + * Tests that should be performed: + * ------------------------------- + * - Run without port connects (shouldn't crash) + * - Run without output ports connects (shouldn't crash) + * - Run with buffer size 0 + * - Run with VERY LARGE buffer size (>1MB?) + * - Run with buffer size a prime number (and thereby not power of 2) + * - Run with HUGE number of midi events in one buffer (10000) + */ +class test_lv2 : public CppUnit::TestFixture +{ +  CPPUNIT_TEST_SUITE(test_lv2); +	CPPUNIT_TEST(open_and_verify); +	CPPUNIT_TEST(run_no_ports_connected); +	CPPUNIT_TEST(run_no_output_ports_connected); +	CPPUNIT_TEST(test1); +	CPPUNIT_TEST_SUITE_END(); + +public: +	void setUp() {} +	void tearDown() {} + +  void open_and_verify() +  { +    int res; + +    LV2TestHost h("/home/deva/docs/c/drumgizmo/install/lib/lv2"); + +    res = h.open(DG_URI); +    CPPUNIT_ASSERT(res == 0); + +    res = h.verify(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.close(); +    CPPUNIT_ASSERT(res == 0); +  } + +  void run_no_ports_connected() +  { +    int res; + +    LV2TestHost h("/home/deva/docs/c/drumgizmo/install/lib/lv2"); + +    res = h.open(DG_URI); +    CPPUNIT_ASSERT(res == 0); + +    res = h.verify(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.createInstance(); +    CPPUNIT_ASSERT(res == 0); + +    const char config_fmt[] =  +      "<config>\n" +      "  <value name=\"drumkitfile\">%s</value>\n" +      "  <value name=\"midimapfile\">%s</value>\n" +      "  <value name=\"enable_velocity_modifier\">%s</value>\n" +      "  <value name=\"velocity_modifier_falloff\">%f</value>\n" +      "  <value name=\"velocity_modifier_weight\">%f</value>\n" +      "  <value name=\"enable_velocity_randomiser\">%s</value>\n" +      "  <value name=\"velocity_randomiser_weight\">%f</value>\n" +      "  <value name=\"enable_resampling\">%s</value>\n" +      "</config>"; + +    const char drumkitfile[] = "kit/kit1.xml"; +    const char midimapfile[] = "kit/midimap.xml"; +    bool enable_velocity_modifier = true; +    float velocity_modifier_falloff = 0.5; +    float velocity_modifier_weight = 0.25; +    bool enable_velocity_randomiser = false; +    float velocity_randomiser_weight = 0.1; +    bool enable_resampling = false; + +    char config[sizeof(config_fmt) * 2]; +    sprintf(config, config_fmt, +            drumkitfile, +            midimapfile, +            enable_velocity_modifier?"true":"false", +            velocity_modifier_falloff, +            velocity_modifier_weight, +            enable_velocity_randomiser?"true":"false", +            velocity_randomiser_weight, +            enable_resampling?"true":"false" +            ); + +    res = h.loadConfig(config, strlen(config)); +    CPPUNIT_ASSERT(res == 0); + +    // run for 1 samples to trigger kit loading +    res = h.run(1); +    CPPUNIT_ASSERT(res == 0); +    sleep(1); // wait for kit to get loaded (async), + +    res = h.run(100); +    CPPUNIT_ASSERT(res == 0); + +    res = h.destroyInstance(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.close(); +    CPPUNIT_ASSERT(res == 0); +  } + +  void run_no_output_ports_connected() +  { +    int res; + +    LV2TestHost h("/home/deva/docs/c/drumgizmo/install/lib/lv2"); + +    res = h.open(DG_URI); +    CPPUNIT_ASSERT(res == 0); + +    res = h.verify(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.createInstance(); +    CPPUNIT_ASSERT(res == 0); + +    const char config_fmt[] =  +      "<config>\n" +      "  <value name=\"drumkitfile\">%s</value>\n" +      "  <value name=\"midimapfile\">%s</value>\n" +      "  <value name=\"enable_velocity_modifier\">%s</value>\n" +      "  <value name=\"velocity_modifier_falloff\">%f</value>\n" +      "  <value name=\"velocity_modifier_weight\">%f</value>\n" +      "  <value name=\"enable_velocity_randomiser\">%s</value>\n" +      "  <value name=\"velocity_randomiser_weight\">%f</value>\n" +      "  <value name=\"enable_resampling\">%s</value>\n" +      "</config>"; + +    const char drumkitfile[] = "kit/kit1.xml"; +    const char midimapfile[] = "kit/midimap.xml"; +    bool enable_velocity_modifier = true; +    float velocity_modifier_falloff = 0.5; +    float velocity_modifier_weight = 0.25; +    bool enable_velocity_randomiser = false; +    float velocity_randomiser_weight = 0.1; +    bool enable_resampling = false; + +    char config[sizeof(config_fmt) * 2]; +    sprintf(config, config_fmt, +            drumkitfile, +            midimapfile, +            enable_velocity_modifier?"true":"false", +            velocity_modifier_falloff, +            velocity_modifier_weight, +            enable_velocity_randomiser?"true":"false", +            velocity_randomiser_weight, +            enable_resampling?"true":"false" +            ); + +    res = h.loadConfig(config, strlen(config)); +    CPPUNIT_ASSERT(res == 0); + +    // Port buffers: +    char sequence_buffer[4096]; + +    LV2TestHost::Sequence seq(sequence_buffer, sizeof(sequence_buffer)); +    res = h.connectPort(0, seq.data()); +    CPPUNIT_ASSERT(res == 0); + +    // run for 1 samples to trigger kit loading +    res = h.run(1); +    CPPUNIT_ASSERT(res == 0); +    sleep(1); // wait for kit to get loaded (async), + +    seq.addMidiNote(5, 1, 127); +    res = h.run(100); +    CPPUNIT_ASSERT(res == 0); + +    res = h.destroyInstance(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.close(); +    CPPUNIT_ASSERT(res == 0); +  } + +  void test1() +  { +    int res; + +    LV2TestHost h("/home/deva/docs/c/drumgizmo/install/lib/lv2"); + +    res = h.open(DG_URI); +    CPPUNIT_ASSERT(res == 0); + +    res = h.verify(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.createInstance(); +    CPPUNIT_ASSERT(res == 0); + +    const char config_fmt[] =  +      "<config>\n" +      "  <value name=\"drumkitfile\">%s</value>\n" +      "  <value name=\"midimapfile\">%s</value>\n" +      "  <value name=\"enable_velocity_modifier\">%s</value>\n" +      "  <value name=\"velocity_modifier_falloff\">%f</value>\n" +      "  <value name=\"velocity_modifier_weight\">%f</value>\n" +      "  <value name=\"enable_velocity_randomiser\">%s</value>\n" +      "  <value name=\"velocity_randomiser_weight\">%f</value>\n" +      "  <value name=\"enable_resampling\">%s</value>\n" +      "</config>"; + +    const char drumkitfile[] = "kit/kit1.xml"; +    const char midimapfile[] = "kit/midimap.xml"; +    bool enable_velocity_modifier = true; +    float velocity_modifier_falloff = 0.5; +    float velocity_modifier_weight = 0.25; +    bool enable_velocity_randomiser = false; +    float velocity_randomiser_weight = 0.1; +    bool enable_resampling = false; + +    char config[sizeof(config_fmt) * 2]; +    sprintf(config, config_fmt, +            drumkitfile, +            midimapfile, +            enable_velocity_modifier?"true":"false", +            velocity_modifier_falloff, +            velocity_modifier_weight, +            enable_velocity_randomiser?"true":"false", +            velocity_randomiser_weight, +            enable_resampling?"true":"false" +            ); + +    res = h.loadConfig(config, strlen(config)); +    CPPUNIT_ASSERT(res == 0); + +    // Port buffers: +    char sequence_buffer[4096]; +    float pcm_buffer[16][10]; + +    LV2TestHost::Sequence seq(sequence_buffer, sizeof(sequence_buffer)); +    res = h.connectPort(0, seq.data()); +    CPPUNIT_ASSERT(res == 0); + +    for(int i = 1; i <= 16; i++) { +      memset(pcm_buffer, 1, sizeof(pcm_buffer)); +      res += h.connectPort(i, pcm_buffer[i-1]); +    } +    CPPUNIT_ASSERT(res == 0); + +    // run for 1 samples to trigger kit loading +    res = h.run(1); +    CPPUNIT_ASSERT(res == 0); +    sleep(1); // wait for kit to get loaded (async), + +    /* +    seq.addMidiNote(5, 1, 127); +    for(int i = 0; i < 10; i++) { +      res = h.run(10); +      CPPUNIT_ASSERT(res == 0); + +      printf("Iteration:\n"); +      for(int k = 0; k < 4; k++) { +        printf("#%d ", k); +        for(int j = 0; j < 10; j++) printf("[%f]", pcm_buffer[k][j]); +        printf("\n"); +      } +      printf("\n"); + +      seq.clear(); +    } +    */ + +    seq.addMidiNote(5, 1, 127); +    res = h.run(10); +    CPPUNIT_ASSERT(res == 0); + +    union { +      float f; +      unsigned int u; +    } comp_val; + +    comp_val.u = 1040744448; + +    for(int k = 0; k < 4; k++) { +      for(int j = 0; j < 10; j++) { +        CPPUNIT_ASSERT(pcm_buffer[k][j] == ((j==4)?comp_val.f:0)); +      } +    } +    seq.clear(); + +    res = h.destroyInstance(); +    CPPUNIT_ASSERT(res == 0); + +    res = h.close(); +    CPPUNIT_ASSERT(res == 0); +  } +}; + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(test_lv2); diff --git a/test/lv2_test_host.cc b/test/lv2_test_host.cc new file mode 100644 index 0000000..5f10c6b --- /dev/null +++ b/test/lv2_test_host.cc @@ -0,0 +1,377 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            lv2_test_host.cc + * + *  Wed Feb 11 23:11:21 CET 2015 + *  Copyright 2015 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo 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. + * + *  DrumGizmo 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 DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "lv2_test_host.h" + +#include <serd/serd.h> + +#include <string.h> +#include <stdlib.h> + +#include <lv2/lv2plug.in/ns/ext/atom/forge.h> +#include <lv2/lv2plug.in/ns/ext/state/state.h> +#include <lv2/lv2plug.in/ns/ext/midi/midi.h> + +/////////////////////////////// +// Base64 encoder: +// +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <string> +class Base64 { +public: +	Base64() +	{ +		mbio = (void*)BIO_new(BIO_s_mem()); +		BIO *b64bio = BIO_new(BIO_f_base64()); +		bio = (void*)BIO_push(b64bio, (BIO*)mbio); +	} + +	~Base64() +	{ +		BIO_free_all((BIO*)bio); +	} + +	std::string write(std::string in) +	{ +		return this->write(in.data(), in.length()); +	} + +	std::string write(const char *in, size_t size) +	{ +		std::string out; +		 +		BIO_write((BIO*)bio, in, size); + +		size_t osize = BIO_ctrl_pending((BIO*)mbio); +		char *outbuf = (char*)malloc(osize); + +		int len = BIO_read((BIO*)mbio, outbuf, osize); +		if(len < 1) return ""; +		out.append(outbuf, len); + +		free(outbuf); +		 +		return out; +	} +	 +	std::string flush() +	{ +		std::string out; +		 +		(void)BIO_flush((BIO*)bio); + +		size_t size = BIO_ctrl_pending((BIO*)mbio); +		char *outbuf = (char*)malloc(size); + +		int len = BIO_read((BIO*)mbio, outbuf, size); +		if(len < 1) return ""; +		out.append(outbuf, len); + +		free(outbuf); +		 +		return out; +	} + +private: +	void *bio; +	void *mbio; +}; +// +// Base64 encoder +/////////////////////////////// + + +// TODO: Use map<int, std::string> instead +static char** uris = NULL; +static size_t n_uris = 0; + +static LV2_URID map_uri(LV2_URID_Map_Handle handle, const char* uri) +{ +	for(size_t i = 0; i < n_uris; ++i) { +		if(!strcmp(uris[i], uri)) { +			return i + 1; +		} +	} + +	uris = (char**)realloc(uris, ++n_uris * sizeof(char*)); +	uris[n_uris - 1] = strdup(uri); + +	return n_uris; +} + +static const char* unmap_uri(LV2_URID_Map_Handle handle, LV2_URID urid) +{ +	if(urid > 0 && urid <= n_uris) { +		return uris[urid - 1]; +	} +	return NULL; +} + +LV2_URID_Map       map           = { NULL, map_uri }; +LV2_Feature        map_feature   = { LV2_URID_MAP_URI, &map }; +LV2_URID_Unmap     unmap         = { NULL, unmap_uri }; +LV2_Feature        unmap_feature = { LV2_URID_UNMAP_URI, &unmap }; +const LV2_Feature* features[]    = { &map_feature, &unmap_feature, NULL }; + +LV2TestHost::Sequence::Sequence(void *buffer, size_t buffer_size) +{ +  this->buffer = buffer; +  this->buffer_size = buffer_size; + +	seq = (LV2_Atom_Sequence *)buffer; + +	seq->atom.size = sizeof(LV2_Atom_Sequence_Body); +	seq->atom.type = map.map(map.handle, LV2_ATOM__Sequence); +	seq->body.unit = 0; +	seq->body.pad = 0; +} + +void LV2TestHost::Sequence::clear() +{ +  lv2_atom_sequence_clear(seq); +} + +void LV2TestHost::Sequence::addMidiNote(uint64_t pos, +                                        uint8_t key, int8_t velocity) +{ +	typedef struct { +		LV2_Atom_Event event; +		uint8_t        msg[3]; +	} MIDINoteEvent; + +	uint8_t note_on = 0x90; + +	MIDINoteEvent ev; +	ev.event.time.frames = pos;// sample position +	ev.event.body.type = map.map(map.handle, LV2_MIDI__MidiEvent); +	ev.event.body.size = sizeof(MIDINoteEvent); +  +	ev.msg[0] = note_on; +	ev.msg[1] = key; +	ev.msg[2] = velocity; + +	LV2_Atom_Event *e = +		lv2_atom_sequence_append_event(seq, this->buffer_size, &ev.event); +  (void)e; +} + +void *LV2TestHost::Sequence::data() +{ +  return buffer; +} + +LV2TestHost::LV2TestHost(const char *lv2_path) +{ +	if(lv2_path) { +    setenv("LV2_PATH", lv2_path, 1); +  } + +	world = lilv_world_new(); +  if(world == NULL) return; + +	lilv_world_load_all(world); +} + +LV2TestHost::~LV2TestHost() +{ +	if(world) lilv_world_free(world); +} + +int LV2TestHost::open(const char *plugin_uri) +{ +  if(world == NULL) return 1; + +	plugins = lilv_world_get_all_plugins(world); +  if(plugins == NULL) return 2; + +	uri = lilv_new_uri(world, plugin_uri); +	if(uri == NULL) return 3; + +	plugin = lilv_plugins_get_by_uri(plugins, uri); +  if(plugin == NULL) return 4; + + +  return 0; +} + +int LV2TestHost::verify() +{ +	bool verify = lilv_plugin_verify(plugin); +  if(!verify) return 1; +  return 0; +} + +int LV2TestHost::close() +{ +  // plugin is a const pointer; nothing to close here. +  return 0; +} + +/* // Get metadata + +static void dumpNodes(LilvNodes *nodes) +{ +	LilvIter* iter = lilv_nodes_begin(nodes); +	while(iter) { +		const LilvNode* node = lilv_nodes_get(nodes, iter); +		printf(" - '%s'\n", lilv_node_as_uri(node)); +		iter = lilv_nodes_next(nodes, iter); +	} +} + +void getMetadata() +{ +	LilvNode* name = lilv_plugin_get_name(plugin); +	if(name) printf("Name: %s\n", lilv_node_as_uri(name)); + +	// ---> line 731 in lilv.h +	bool has_latency = lilv_plugin_has_latency(plugin); +	printf("Has latency: %d\n", has_latency); + +	if(has_latency) { +		uint32_t latency_port_index = lilv_plugin_get_latency_port_index(plugin); +		const LilvPort* port = +			lilv_plugin_get_port_by_index(plugin, latency_port_index); +		// Do something to actually get latency from port.... +	} + +	LilvNode* author = lilv_plugin_get_author_name(plugin); +	if(author) printf("Author: %s\n", lilv_node_as_uri(author)); + +	LilvNode* email = lilv_plugin_get_author_email(plugin); +	if(email) printf("Email: %s\n", lilv_node_as_uri(email)); + +	LilvNode* homepage = lilv_plugin_get_author_homepage(plugin); +	if(homepage) printf("Homepage: %s\n", lilv_node_as_uri(homepage)); + +	LilvNodes* supported = lilv_plugin_get_supported_features(plugin); +	LilvNodes* required = lilv_plugin_get_required_features(plugin); +	LilvNodes* optional = lilv_plugin_get_optional_features(plugin); + +	printf("Supported:\n"); +	dumpNodes(supported); + +	printf("Required:\n"); +	dumpNodes(required); + +	printf("Optional:\n"); +	dumpNodes(optional); + +	lilv_nodes_free(supported); +	lilv_nodes_free(required); +	lilv_nodes_free(optional); +} +*/ +/* +int LV2TestHost::getPorts() +{ +	// Iterate ports: +	const LilvPort* port; +	uint32_t portidx = 0; +	while( (port = lilv_plugin_get_port_by_index(plugin, portidx)) != 0) { +		printf("Port: %d\n", portidx); + +		LilvNode* port_name = lilv_port_get_name(plugin, port); +		if(port_name) printf("  Name: %s\n", lilv_node_as_uri(port_name)); + +		portidx++; +	} +} +*/ +int LV2TestHost::createInstance() +{ +	instance = lilv_plugin_instantiate(plugin, 48000, features); +  if(instance == NULL) return 1; +  return 0; +} + +int LV2TestHost::destroyInstance() +{ +  if(instance) lilv_instance_free(instance); +  return 0; +} + +int LV2TestHost::activate() +{ +	lilv_instance_activate(instance); +  return 0; +} + +int LV2TestHost::deactivate() +{ +	lilv_instance_deactivate(instance); +  return 0; +} + +int LV2TestHost::loadConfig(const char *config, size_t size) +{ +	Base64 b64; +	std::string b64_config = b64.write(config, size); +	b64_config += b64.flush(); + +	//printf("Base 64 config: [%s]\n", b64_config.c_str()); + +	const char ttl_config_fmt[] = +		"<http://drumgizmo.org/lv2/atom#config>\n" +		"        a pset:Preset ;\n" +		"        lv2:appliesTo <http://drumgizmo.org/lv2> ;\n" +		"        state:state [\n" +		"                <http://drumgizmo.org/lv2/atom#config> \"\"\"%s\"\"\"^^xsd:base64Binary\n" +		"        ] .\n"; + +	char ttl_config[sizeof(ttl_config_fmt) * 2 + b64_config.size()]; +	sprintf(ttl_config, ttl_config_fmt, b64_config.c_str()); + +	//printf("ttl config: [%s]\n", ttl_config); + +	{ +		LilvState* restore_state = +			lilv_state_new_from_string(world, &map, ttl_config); +		 +		lilv_state_restore(restore_state, instance, NULL, NULL, +											 LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE, +											 features); +	} + +  return 0; +} + +int LV2TestHost::connectPort(int port, void *portdata) +{ +  //  if(lilv_port_is_a(p, port, lv2_ControlPort)) ... + +	lilv_instance_connect_port(instance, port, portdata); + +  return 0; +} + +int LV2TestHost::run(int num_samples) +{ +  lilv_instance_run(instance, num_samples); +  return 0; +} diff --git a/test/lv2_test_host.h b/test/lv2_test_host.h new file mode 100644 index 0000000..04f48c6 --- /dev/null +++ b/test/lv2_test_host.h @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            lv2_test_host.h + * + *  Wed Feb 11 23:11:20 CET 2015 + *  Copyright 2015 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo 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. + * + *  DrumGizmo 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 DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#ifndef __DRUMGIZMO_LV2_TEST_HOST_H__ +#define __DRUMGIZMO_LV2_TEST_HOST_H__ + +#include <lilv/lilv.h> +#include <lv2/lv2plug.in/ns/ext/atom/atom.h> + +class LV2TestHost { +public: +  class Sequence { +  public: +    Sequence(void *buffer, size_t buffer_size); +    void clear(); +    void addMidiNote(uint64_t pos, uint8_t key, int8_t velocity); +    void *data(); + +  private: +    void *buffer; +    size_t buffer_size; +    LV2_Atom_Sequence *seq; +  }; + +  LV2TestHost(const char *lv2_path); +  ~LV2TestHost(); + +  int open(const char *plugin_uri); +  int close(); + +  int verify(); + +  //void getMetadata(); +  //int getPorts(); + +  int createInstance(); +  int destroyInstance(); + +  int connectPort(int port, void *portdata); + +  int activate(); +  int deactivate(); + +  int loadConfig(const char *config, size_t size); +  int run(int num_samples); + + + +private: +  LilvWorld* world; +  const LilvPlugins* plugins;   +	LilvNode* uri; +	const LilvPlugin* plugin; + +  LilvInstance* instance; + +  size_t buffer_size; +}; + +#endif/*__DRUMGIZMO_LV2_TEST_HOST_H__*/ | 
