summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-11-14 20:44:40 +0000
committerDavid Robillard <d@drobilla.net>2009-11-14 20:44:40 +0000
commit6ae2018e81e7e81e4906e62dc6224ad34298d9c2 (patch)
tree11286438977c4f975b5148dc93b5f4dfafabdbdc /src/shared
parentcfec427867f42d7aa7bea6dfbb0736b5ce99e9e2 (diff)
downloadingen-6ae2018e81e7e81e4906e62dc6224ad34298d9c2.tar.gz
ingen-6ae2018e81e7e81e4906e62dc6224ad34298d9c2.tar.bz2
ingen-6ae2018e81e7e81e4906e62dc6224ad34298d9c2.zip
Object extension.
Port resize extension. Sensible extension(s) implementation design for Ingen. Replace string port extension support in Ingen with Object port extension. Implement port resize extension in Ingen. Some test plugins for this stuff. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2260 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/LV2Features.cpp35
-rw-r--r--src/shared/LV2Features.hpp46
-rw-r--r--src/shared/LV2Object.cpp96
-rw-r--r--src/shared/LV2Object.hpp39
-rw-r--r--src/shared/LV2URIMap.cpp12
-rw-r--r--src/shared/LV2URIMap.hpp20
-rw-r--r--src/shared/ResourceImpl.cpp6
-rw-r--r--src/shared/wscript3
8 files changed, 220 insertions, 37 deletions
diff --git a/src/shared/LV2Features.cpp b/src/shared/LV2Features.cpp
index d21462c9..b57f1117 100644
--- a/src/shared/LV2Features.cpp
+++ b/src/shared/LV2Features.cpp
@@ -16,6 +16,7 @@
*/
#include <cstdlib>
+#include <cstring>
#include "LV2Features.hpp"
#include "LV2URIMap.hpp"
@@ -26,39 +27,39 @@ namespace Shared {
LV2Features::LV2Features()
- : _lv2_features((LV2_Feature**)malloc(sizeof(LV2_Feature*)))
+// : _lv2_features((LV2_Feature**)malloc(sizeof(LV2_Feature*)))
{
- _lv2_features[0] = NULL;
+// _lv2_features[0] = NULL;
- LV2URIMap* controller = new LV2URIMap();
- add_feature(LV2_URI_MAP_URI, controller->feature(), controller);
+ add_feature(LV2_URI_MAP_URI, SharedPtr<Feature>(new LV2URIMap()));
}
-const LV2Features::Feature*
+SharedPtr<LV2Features::Feature>
LV2Features::feature(const std::string& uri)
{
Features::const_iterator i = _features.find(uri);
if (i != _features.end())
- return &i->second;
+ return i->second;
else
- return NULL;
+ return SharedPtr<Feature>();
}
void
-LV2Features::add_feature(const std::string& uri, LV2_Feature* feature, void* controller)
+LV2Features::add_feature(const std::string& uri, SharedPtr<Feature> feature)
{
-#ifndef NDEBUG
- Features::const_iterator i = _features.find(uri);
- assert(i == _features.end());
- assert(_lv2_features[_features.size()] == NULL);
-#endif
- _features.insert(make_pair(uri, Feature(feature, controller)));
+ _features.insert(make_pair(uri, feature));
+}
- _lv2_features = (LV2_Feature**)realloc(_lv2_features, sizeof(LV2_Feature*) * (_features.size() + 1));
- _lv2_features[_features.size()-1] = feature;
- _lv2_features[_features.size()] = NULL;
+
+SharedPtr<LV2Features::FeatureArray>
+LV2Features::lv2_features(Node* node) const
+{
+ FeatureArray::FeatureVector vec;
+ for (Features::const_iterator f = _features.begin(); f != _features.end(); ++f)
+ vec.push_back(f->second->feature(node));
+ return SharedPtr<FeatureArray>(new FeatureArray(vec));
}
diff --git a/src/shared/LV2Features.hpp b/src/shared/LV2Features.hpp
index f2299c5c..78d467a5 100644
--- a/src/shared/LV2Features.hpp
+++ b/src/shared/LV2Features.hpp
@@ -25,11 +25,14 @@
#include <map>
#include <string>
+#include <vector>
#include "slv2/slv2.h"
+#include "raul/SharedPtr.hpp"
namespace Ingen {
namespace Shared {
+class Node;
/** Stuff that may need to be passed to an LV2 plugin (i.e. LV2 features).
*/
@@ -37,26 +40,47 @@ class LV2Features {
public:
LV2Features();
- struct Feature {
- Feature(LV2_Feature* f, void* c=NULL) : feature(f), controller(c) {}
- LV2_Feature* feature; ///< LV2 feature struct (plugin exposed)
- void* controller; ///< Ingen internals, not exposed to plugin
+ class Feature {
+ public:
+ virtual ~Feature() {}
+ virtual SharedPtr<LV2_Feature> feature(Node* node) = 0;
};
- typedef std::map<std::string, Feature> Features;
+ class FeatureArray {
+ public:
+ typedef std::vector< SharedPtr<LV2_Feature> > FeatureVector;
- const Feature* feature(const std::string& uri);
+ FeatureArray(FeatureVector& features)
+ : _features(features)
+ {
+ _array = (LV2_Feature**)malloc(sizeof(LV2_Feature) * (features.size() + 1));
+ _array[features.size()] = NULL;
+ for (size_t i = 0; i < features.size(); ++i)
+ _array[i] = features[i].get();
+ }
- void add_feature(const std::string& uri, LV2_Feature* feature, void* controller);
+ ~FeatureArray() {
+ free(_array);
+ }
- LV2_Feature** lv2_features() const { return _lv2_features; }
+ LV2_Feature** array() { return _array; }
+
+ private:
+ FeatureVector _features;
+ LV2_Feature** _array;
+ };
+
+ SharedPtr<Feature> feature(const std::string& uri);
+
+ void add_feature(const std::string& uri, SharedPtr<Feature> feature);
+
+ SharedPtr<LV2Features::FeatureArray> lv2_features(Node* node) const;
private:
- Features _features;
- LV2_Feature** _lv2_features;
+ typedef std::map< std::string, SharedPtr<Feature> > Features;
+ Features _features;
};
-
} // namespace Shared
} // namespace Ingen
diff --git a/src/shared/LV2Object.cpp b/src/shared/LV2Object.cpp
new file mode 100644
index 00000000..3442c004
--- /dev/null
+++ b/src/shared/LV2Object.cpp
@@ -0,0 +1,96 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2009 Dave Robillard <http://drobilla.net>
+ *
+ * Ingen 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.
+ *
+ * Ingen 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 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <iostream>
+#include "raul/Atom.hpp"
+#include "module/World.hpp"
+#include "uri-map.lv2/uri-map.h"
+#include "object.lv2/object.h"
+#include "LV2Features.hpp"
+#include "LV2Object.hpp"
+#include "LV2URIMap.hpp"
+
+using namespace std;
+
+namespace Ingen {
+namespace Shared {
+namespace LV2Object {
+
+
+bool
+to_atom(World* world, LV2_Object* object, Raul::Atom& atom)
+{
+ SharedPtr<LV2URIMap> map = PtrCast<LV2URIMap>(world->lv2_features->feature(LV2_URI_MAP_URI));
+
+ if (object->type == map->object_class_string) {
+ atom = Raul::Atom((char*)(object + 1));
+ return true;
+ } else if (object->type == map->object_class_int32) {
+ atom = Raul::Atom((int32_t*)(object + 1));
+ return true;
+ } else if (object->type == map->object_class_float32) {
+ atom = Raul::Atom((float*)(object + 1));
+ return true;
+ }
+ return false;
+}
+
+
+/** Convert an atom to an LV2 object, if possible.
+ * object->size should be the capacity of the object (not including header)
+ */
+bool
+from_atom(World* world, const Raul::Atom& atom, LV2_Object* object)
+{
+ SharedPtr<LV2URIMap> map = PtrCast<LV2URIMap>(world->lv2_features->feature(LV2_URI_MAP_URI));
+
+ char* str;
+ switch (atom.type()) {
+ case Raul::Atom::FLOAT:
+ object->type = map->object_class_float32;
+ object->size = sizeof(float);
+ *(float*)(object + 1) = atom.get_float();
+ break;
+ case Raul::Atom::INT:
+ object->type = map->object_class_int32;
+ object->size = sizeof(int32_t);
+ *(int32_t*)(object + 1) = atom.get_int32();
+ break;
+ case Raul::Atom::STRING:
+ object->type = map->object_class_string;
+ object->size = std::min(object->size, (uint32_t)strlen(atom.get_string()) + 1);
+ str = ((char*)(object + 1));
+ str[object->size - 1] = '\0';
+ strncpy(str, atom.get_string(), object->size);
+ break;
+ case Raul::Atom::BLOB:
+ object->type = map->object_class_string;
+ *(uint32_t*)(object + 1) = map->uri_to_id(NULL, atom.get_blob_type());
+ memcpy(((char*)(object + 1) + sizeof(uint32_t)), atom.get_blob(),
+ std::min(atom.data_size(), (size_t)object->size));
+ default:
+ cerr << "Unsupported value type for toggle control" << endl;
+ return false;
+ }
+ return true;
+}
+
+
+} // namespace LV2Object
+
+} // namespace Shared
+} // namespace Ingen
diff --git a/src/shared/LV2Object.hpp b/src/shared/LV2Object.hpp
new file mode 100644
index 00000000..1e72c4e0
--- /dev/null
+++ b/src/shared/LV2Object.hpp
@@ -0,0 +1,39 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2009 Dave Robillard <http://drobilla.net>
+ *
+ * Ingen 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.
+ *
+ * Ingen 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 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LV2_OBJECT_HPP
+#define LV2_OBJECT_HPP
+
+namespace Raul { class Atom; }
+typedef struct _LV2_Object LV2_Object;
+
+namespace Ingen {
+namespace Shared {
+
+class World;
+
+namespace LV2Object {
+
+ bool to_atom(World* world, const LV2_Object* object, Raul::Atom& atom);
+ bool from_atom(World* word, const Raul::Atom& atom, LV2_Object* object);
+
+} // namespace LV2Object
+
+} // namespace Shared
+} // namespace Ingen
+
+#endif // LV2_OBJECT_HPP
diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp
index e3ab6a48..65e3aa30 100644
--- a/src/shared/LV2URIMap.cpp
+++ b/src/shared/LV2URIMap.cpp
@@ -19,6 +19,7 @@
#include <cassert>
#include <iostream>
#include <stdint.h>
+#include "object.lv2/object.h"
#include "LV2URIMap.hpp"
using namespace std;
@@ -28,7 +29,16 @@ namespace Shared {
LV2URIMap::LV2URIMap()
- : next_uri_id(1)
+ : uri_map()
+ , next_uri_id(1)
+ , object_class_bool(uri_to_id(NULL, LV2_OBJECT_URI "#Bool"))
+ , object_class_string(uri_to_id(NULL, LV2_OBJECT_URI "#String"))
+ , object_class_int32(uri_to_id(NULL, LV2_OBJECT_URI "#Int32"))
+ , object_class_float32(uri_to_id(NULL, LV2_OBJECT_URI "#Float32"))
+ , ui_format_events(uri_to_id(NULL, "http://lv2plug.in/ns/extensions/ui#Events"))
+ , midi_event(uri_to_id(NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent"))
+ , string_transfer(uri_to_id(NULL, "http://lv2plug.in/ns/dev/string-port#StringTransfer"))
+ , object_transfer(uri_to_id(NULL, LV2_OBJECT_URI "#ObjectTransfer"))
{
uri_map_feature_data.uri_to_id = &LV2URIMap::uri_map_uri_to_id;
uri_map_feature_data.callback_data = this;
diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp
index f1b9c919..0dd6b0cb 100644
--- a/src/shared/LV2URIMap.hpp
+++ b/src/shared/LV2URIMap.hpp
@@ -28,6 +28,7 @@
#include <boost/utility.hpp>
#include "slv2/slv2.h"
#include "uri-map.lv2/uri-map.h"
+#include "LV2Features.hpp"
namespace Ingen {
namespace Shared {
@@ -35,14 +36,15 @@ namespace Shared {
/** Implementation of the LV2 URI Map extension
*/
-class LV2URIMap : public boost::noncopyable {
+class LV2URIMap : public boost::noncopyable, public LV2Features::Feature {
public:
LV2URIMap();
- LV2_Feature* feature() { return &uri_map_feature; }
+ SharedPtr<LV2_Feature> feature(Node*) {
+ return SharedPtr<LV2_Feature>(&uri_map_feature, NullDeleter<LV2_Feature>);
+ }
- uint32_t uri_to_id(const char* map,
- const char* uri);
+ uint32_t uri_to_id(const char* map, const char* uri);
private:
typedef std::map<std::string, uint32_t> URIMap;
@@ -55,6 +57,16 @@ private:
LV2_URI_Map_Feature uri_map_feature_data;
URIMap uri_map;
uint32_t next_uri_id;
+
+public:
+ const uint32_t object_class_bool;
+ const uint32_t object_class_string;
+ const uint32_t object_class_int32;
+ const uint32_t object_class_float32;
+ const uint32_t ui_format_events;
+ const uint32_t midi_event;
+ const uint32_t string_transfer;
+ const uint32_t object_transfer;
};
diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp
index b4b40116..6d028a13 100644
--- a/src/shared/ResourceImpl.cpp
+++ b/src/shared/ResourceImpl.cpp
@@ -110,10 +110,10 @@ ResourceImpl::type(
port = true;
}
} else if (!strcmp(atom.get_uri(), "lv2ev:EventPort")) {
- data_type = DataType::EVENT;
+ data_type = DataType::EVENTS;
port = true;
- } else if (!strcmp(atom.get_uri(), "sp:StringPort")) {
- data_type = DataType::STRING;
+ } else if (!strcmp(atom.get_uri(), "obj:ObjectPort")) {
+ data_type = DataType::OBJECT;
port = true;
}
}
diff --git a/src/shared/wscript b/src/shared/wscript
index 50fb7320..3f60752c 100644
--- a/src/shared/wscript
+++ b/src/shared/wscript
@@ -7,10 +7,11 @@ def build(bld):
Builder.cpp
ClashAvoider.cpp
LV2Features.cpp
+ LV2Object.cpp
LV2URIMap.cpp
ResourceImpl.cpp
- runtime_paths.cpp
Store.cpp
+ runtime_paths.cpp
'''
if bld.env['HAVE_LIBLO'] == 1:
obj.source += ' OSCSender.cpp '