parent
9bc0317e77
commit
b55c2af8ba
@ -0,0 +1,5 @@
|
||||
set(LIB_SRCS
|
||||
urid_mapper.cpp
|
||||
)
|
||||
|
||||
add_library(noisicaa-lv2 SHARED ${LIB_SRCS})
|
@ -0,0 +1,83 @@
|
||||
#include <assert.h>
|
||||
#include "noisicaa/lv2/urid_mapper.h"
|
||||
|
||||
namespace noisicaa {
|
||||
|
||||
StaticURIDMapper::StaticURIDMapper() {
|
||||
LV2_URID urid = 0;
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/midi#MidiEvent";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#frameTime";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Blank";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Bool";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Chunk";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Double";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Float";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Int";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Long";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Literal";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Object";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Path";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Property";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Resource";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Sequence";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#String";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Tuple";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#URI";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#URID";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Vector";
|
||||
_rmap[urid++] = "http://lv2plug.in/ns/ext/atom#Event";
|
||||
assert(urid == _num_urids);
|
||||
|
||||
urid = _first_urid;
|
||||
for (const auto& uri : _rmap) {
|
||||
_map[uri] = urid++;
|
||||
}
|
||||
}
|
||||
|
||||
LV2_URID StaticURIDMapper::map(const char* uri) {
|
||||
const auto& it = _map.find(uri);
|
||||
if (it == _map.end()) {
|
||||
return 0;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const char* StaticURIDMapper::unmap(LV2_URID urid) const {
|
||||
if (urid < _first_urid || urid >= _first_urid + _num_urids) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _rmap[urid - _first_urid];
|
||||
}
|
||||
|
||||
|
||||
LV2_URID DynamicURIDMapper::map(const char* uri) {
|
||||
LV2_URID urid = StaticURIDMapper::map(uri);
|
||||
if (urid != 0) {
|
||||
return urid;
|
||||
}
|
||||
|
||||
const auto& it = _map.find(uri);
|
||||
if (it == _map.end()) {
|
||||
urid = _next_urid++;
|
||||
_map.emplace(uri, urid);
|
||||
_rmap.emplace(urid, uri);
|
||||
return urid;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const char* DynamicURIDMapper::unmap(LV2_URID urid) const {
|
||||
const char* uri = StaticURIDMapper::unmap(urid);
|
||||
if (uri != nullptr) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
const auto& it = _rmap.find(urid);
|
||||
if (it == _rmap.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second.c_str();
|
||||
}
|
||||
|
||||
} // namespace noisicaa
|
@ -0,0 +1,60 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
#ifndef _NOISICAA_LV2_URID_MAPPER_H
|
||||
#define _NOISICAA_LV2_URID_MAPPER_H
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "string.h"
|
||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
||||
|
||||
namespace noisicaa {
|
||||
|
||||
struct cmp_str;
|
||||
|
||||
using namespace std;
|
||||
|
||||
class URIDMapper {
|
||||
public:
|
||||
virtual ~URIDMapper() {}
|
||||
|
||||
virtual LV2_URID map(const char* uri) = 0;
|
||||
virtual const char* unmap(LV2_URID urid) const = 0;
|
||||
};
|
||||
|
||||
class StaticURIDMapper : public URIDMapper {
|
||||
public:
|
||||
StaticURIDMapper();
|
||||
|
||||
LV2_URID map(const char* uri) override;
|
||||
const char* unmap(LV2_URID urid) const override;
|
||||
|
||||
private:
|
||||
static const LV2_URID _first_urid = 100;
|
||||
static const int _num_urids = 21;
|
||||
|
||||
struct cmp_cstr {
|
||||
bool operator()(const char *a, const char *b) {
|
||||
return strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
std::map<const char*, LV2_URID, cmp_cstr> _map;
|
||||
const char* _rmap[_num_urids];
|
||||
};
|
||||
|
||||
class DynamicURIDMapper : public StaticURIDMapper {
|
||||
public:
|
||||
LV2_URID map(const char* uri) override;
|
||||
const char* unmap(LV2_URID urid) const override;
|
||||
|
||||
private:
|
||||
unordered_map<string, LV2_URID> _map;
|
||||
unordered_map<LV2_URID, string> _rmap;
|
||||
LV2_URID _next_urid = 1000;
|
||||
};
|
||||
|
||||
} // namespace noisicaa
|
||||
|
||||
#endif
|
@ -0,0 +1,15 @@
|
||||
from libc.stdint cimport uint32_t
|
||||
|
||||
cdef extern from "lv2/lv2plug.in/ns/ext/urid/urid.h" nogil:
|
||||
ctypedef uint32_t LV2_URID
|
||||
|
||||
cdef extern from "noisicaa/lv2/urid_mapper.h" namespace "noisicaa" nogil:
|
||||
cppclass URIDMapper:
|
||||
LV2_URID map(const char* uri)
|
||||
const char* unmap(LV2_URID urid) const
|
||||
|
||||
cppclass StaticURIDMapper(URIDMapper):
|
||||
pass
|
||||
|
||||
cppclass DynamicURIDMapper(URIDMapper):
|
||||
pass
|
@ -0,0 +1,65 @@
|
||||
#include <assert.h>
|
||||
#include "noisicore/host_system_lv2.h"
|
||||
|
||||
namespace noisicaa {
|
||||
|
||||
LV2SubSystem::~LV2SubSystem() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
Status LV2SubSystem::setup() {
|
||||
assert(lilv_world == nullptr);
|
||||
|
||||
lilv_world = lilv_world_new();
|
||||
if (lilv_world == nullptr) {
|
||||
return Status::Error("Failed to create lilv world.");
|
||||
}
|
||||
|
||||
lilv_world_load_all(lilv_world);
|
||||
|
||||
urid_map.handle = &_urid_mapper;
|
||||
urid_map.map = LV2SubSystem::_urid_map_proxy;
|
||||
urid_unmap.handle = &_urid_mapper;
|
||||
urid_unmap.unmap = LV2SubSystem::_urid_unmap_proxy;
|
||||
|
||||
urid.midi_event = map("http://lv2plug.in/ns/ext/midi#MidiEvent");
|
||||
urid.atom_frame_time = map("http://lv2plug.in/ns/ext/atom#frameTime");
|
||||
urid.atom_blank = map("http://lv2plug.in/ns/ext/atom#Blank");
|
||||
urid.atom_bool = map("http://lv2plug.in/ns/ext/atom#Bool");
|
||||
urid.atom_chunk = map("http://lv2plug.in/ns/ext/atom#Chunk");
|
||||
urid.atom_double = map("http://lv2plug.in/ns/ext/atom#Double");
|
||||
urid.atom_float = map("http://lv2plug.in/ns/ext/atom#Float");
|
||||
urid.atom_int = map("http://lv2plug.in/ns/ext/atom#Int");
|
||||
urid.atom_long = map("http://lv2plug.in/ns/ext/atom#Long");
|
||||
urid.atom_literal = map("http://lv2plug.in/ns/ext/atom#Literal");
|
||||
urid.atom_object = map("http://lv2plug.in/ns/ext/atom#Object");
|
||||
urid.atom_path = map("http://lv2plug.in/ns/ext/atom#Path");
|
||||
urid.atom_property = map("http://lv2plug.in/ns/ext/atom#Property");
|
||||
urid.atom_resource = map("http://lv2plug.in/ns/ext/atom#Resource");
|
||||
urid.atom_sequence = map("http://lv2plug.in/ns/ext/atom#Sequence");
|
||||
urid.atom_string = map("http://lv2plug.in/ns/ext/atom#String");
|
||||
urid.atom_tuple = map("http://lv2plug.in/ns/ext/atom#Tuple");
|
||||
urid.atom_uri = map("http://lv2plug.in/ns/ext/atom#URI");
|
||||
urid.atom_urid = map("http://lv2plug.in/ns/ext/atom#URID");
|
||||
urid.atom_vector = map("http://lv2plug.in/ns/ext/atom#Vector");
|
||||
urid.atom_event = map("http://lv2plug.in/ns/ext/atom#Event");
|
||||
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
void LV2SubSystem::cleanup() {
|
||||
if (lilv_world != nullptr) {
|
||||
lilv_world_free(lilv_world);
|
||||
lilv_world = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LV2_URID LV2SubSystem::_urid_map_proxy(LV2_URID_Map_Handle handle, const char* uri) {
|
||||
return ((URIDMapper*)handle)->map(uri);
|
||||
}
|
||||
|
||||
const char* LV2SubSystem::_urid_unmap_proxy(LV2_URID_Unmap_Handle handle, LV2_URID urid) {
|
||||
return ((URIDMapper*)handle)->unmap(urid);
|
||||
}
|
||||
|
||||
} // namespace noisicaa
|
@ -0,0 +1,62 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
#ifndef _NOISICORE_HOST_SYSTEM_LV2_H
|
||||
#define _NOISICORE_HOST_SYSTEM_LV2_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include "lilv/lilv.h"
|
||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
||||
#include "noisicaa/lv2/urid_mapper.h"
|
||||
#include "noisicore/status.h"
|
||||
|
||||
namespace noisicaa {
|
||||
|
||||
class LV2SubSystem {
|
||||
public:
|
||||
~LV2SubSystem();
|
||||
|
||||
Status setup();
|
||||
void cleanup();
|
||||
|
||||
LilvWorld* lilv_world = nullptr;
|
||||
|
||||
LV2_URID_Map urid_map = { nullptr, nullptr };
|
||||
LV2_URID_Unmap urid_unmap = { nullptr, nullptr };
|
||||
|
||||
LV2_URID map(const char* uri) { return _urid_mapper.map(uri); }
|
||||
const char* unmap(LV2_URID urid) { return _urid_mapper.unmap(urid); }
|
||||
|
||||
struct {
|
||||
LV2_URID midi_event;
|
||||
LV2_URID atom_frame_time;
|
||||
LV2_URID atom_blank;
|
||||
LV2_URID atom_bool;
|
||||
LV2_URID atom_chunk;
|
||||
LV2_URID atom_double;
|
||||
LV2_URID atom_float;
|
||||
LV2_URID atom_int;
|
||||
LV2_URID atom_long;
|
||||
LV2_URID atom_literal;
|
||||
LV2_URID atom_object;
|
||||
LV2_URID atom_path;
|
||||
LV2_URID atom_property;
|
||||
LV2_URID atom_resource;
|
||||
LV2_URID atom_sequence;
|
||||
LV2_URID atom_string;
|
||||
LV2_URID atom_tuple;
|
||||
LV2_URID atom_uri;
|
||||
LV2_URID atom_urid;
|
||||
LV2_URID atom_vector;
|
||||
LV2_URID atom_event;
|
||||
} urid;
|
||||
|
||||
private:
|
||||
DynamicURIDMapper _urid_mapper;
|
||||
|
||||
static LV2_URID _urid_map_proxy(LV2_URID_Map_Handle handle, const char* uri);
|
||||
static const char* _urid_unmap_proxy(LV2_URID_Unmap_Handle handle, LV2_URID urid);
|
||||
};
|
||||
|
||||
} // namespace noisicaa
|
||||
|
||||
#endif
|
Loading…
Reference in new issue