summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
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 '