diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/LV2Features.cpp | 35 | ||||
-rw-r--r-- | src/shared/LV2Features.hpp | 46 | ||||
-rw-r--r-- | src/shared/LV2Object.cpp | 96 | ||||
-rw-r--r-- | src/shared/LV2Object.hpp | 39 | ||||
-rw-r--r-- | src/shared/LV2URIMap.cpp | 12 | ||||
-rw-r--r-- | src/shared/LV2URIMap.hpp | 20 | ||||
-rw-r--r-- | src/shared/ResourceImpl.cpp | 6 | ||||
-rw-r--r-- | src/shared/wscript | 3 |
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 ' |