New C++ implementation of URID mapper.

looper
Ben Niemann 6 years ago
parent 9bc0317e77
commit b55c2af8ba

@ -2,8 +2,6 @@
* VM-based pipeline engine :FR:
- playback becomes slower over time...
- C++ implementation of URID mapper
- currently calls into python from audio thread.
- reimplement sample_player
- Better handling of partial blocks in player
- control/sample tracks should always produce complete blocks, padded with zeros

@ -17,6 +17,7 @@ add_subdirectory(devices)
add_subdirectory(importers)
add_subdirectory(instr)
add_subdirectory(instrument_db)
add_subdirectory(lv2)
add_subdirectory(music)
add_subdirectory(node_db)
add_subdirectory(ui)

@ -3,19 +3,20 @@ add_python_package(
sratom_test.py
)
add_cython_module(ladspa C)
add_cython_module(ladspa CXX)
add_cython_module(lilv C)
add_cython_module(lilv CXX)
target_include_directories(${lilv.so} PRIVATE ${LIBLILV_INCLUDE_DIRS})
target_link_libraries(${lilv.so} PRIVATE ${LIBLILV_LIBRARIES})
add_cython_module(sndfile C)
add_cython_module(sndfile CXX)
target_include_directories(${sndfile.so} PRIVATE ${LIBSNDFILE_INCLUDE_DIRS})
target_link_libraries(${sndfile.so} PRIVATE ${LIBSNDFILE_LIBRARIES})
add_cython_module(sratom C)
add_cython_module(sratom CXX)
target_include_directories(${sratom.so} PRIVATE ${LIBSRATOM_INCLUDE_DIRS})
target_link_libraries(${sratom.so} PRIVATE ${LIBSRATOM_LIBRARIES})
file(COPY testdata DESTINATION .)
add_subdirectory(lv2)

@ -15,8 +15,7 @@ from .lv2.core cimport (
from .lv2.urid cimport (
LV2_URID_Map,
LV2_URID_Unmap,
# URID_Mapper,
URID_DynamicMapper,
URIDMapper,
# URID_Map_Feature,
# URID_Unmap_Feature,
)
@ -433,7 +432,7 @@ cdef class World(object):
cdef LilvWorld* world
cdef readonly Namespaces ns
cdef readonly URID_DynamicMapper urid_mapper
cdef readonly URIDMapper urid_mapper
cdef class Instance(object):

@ -15,10 +15,9 @@ from .lv2.core cimport (
from .lv2.urid cimport (
LV2_URID_Map,
LV2_URID_Unmap,
URID_Mapper,
URID_DynamicMapper,
URID_Map_Feature,
URID_Unmap_Feature,
DynamicURIDMapper,
)
from .lv2.options cimport Options_Feature
from .lv2.bufsize cimport (
@ -866,7 +865,7 @@ cdef class World(object):
self.world = NULL
def __init__(self):
self.urid_mapper = URID_DynamicMapper()
self.urid_mapper = DynamicURIDMapper()
self.world = lilv_world_new()
assert self.world != NULL

@ -2,9 +2,10 @@ add_python_package(
atom_test.py
)
add_cython_module(atom C)
add_cython_module(core C)
add_cython_module(urid C)
add_cython_module(worker C)
add_cython_module(bufsize C)
add_cython_module(options C)
add_cython_module(atom CXX)
add_cython_module(core CXX)
add_cython_module(urid CXX)
target_link_libraries(${urid.so} PRIVATE noisicaa-lv2)
add_cython_module(worker CXX)
add_cython_module(bufsize CXX)
add_cython_module(options CXX)

@ -1,5 +1,5 @@
from .urid import (
URID_DynamicMapper,
DynamicURIDMapper,
static_mapper,
)
from .atom import (

@ -3,8 +3,8 @@ from libc.stdint cimport uint32_t, int32_t, int64_t, uint8_t, intptr_t
from .urid cimport (
LV2_URID,
LV2_URID_Map,
URID_Mapper,
URID_Map_Feature,
URIDMapper,
)
cdef extern from "stdbool.h" nogil:
@ -472,10 +472,10 @@ cdef class AtomForge(object):
cdef class Atom(object):
cdef LV2_Atom* atom
cdef URID_Mapper mapper
cdef URIDMapper mapper
cdef init(self, LV2_Atom* atom)
@staticmethod
cdef Atom wrap(URID_Mapper mapper, uint8_t* buf)
cdef Atom wrap(URIDMapper mapper, uint8_t* buf)
cdef class MidiEvent(Atom):

@ -9,7 +9,7 @@ logger = logging.getLogger(__name__)
cdef class AtomForge(object):
def __cinit__(self, URID_Mapper mapper):
def __cinit__(self, URIDMapper mapper):
self.map = URID_Map_Feature(mapper)
self.midi_event = mapper.map(
@ -80,7 +80,7 @@ cdef class AtomForge(object):
cdef class Atom(object):
def __cinit__(self, URID_Mapper mapper):
def __cinit__(self, URIDMapper mapper):
self.mapper = mapper
self.atom = NULL
@ -89,18 +89,18 @@ cdef class Atom(object):
return self
@staticmethod
cdef Atom wrap(URID_Mapper mapper, uint8_t* buf):
cdef Atom wrap(URIDMapper mapper, uint8_t* buf):
cdef LV2_Atom* atom = <LV2_Atom*>buf
type_uri = mapper.unmap(atom.type)
if type_uri == b'http://lv2plug.in/ns/ext/atom#Sequence':
if type_uri == 'http://lv2plug.in/ns/ext/atom#Sequence':
return Sequence(mapper).init(atom)
elif type_uri == b'http://lv2plug.in/ns/ext/midi#MidiEvent':
elif type_uri == 'http://lv2plug.in/ns/ext/midi#MidiEvent':
return MidiEvent(mapper).init(atom)
else:
return Atom(mapper).init(atom)
def __str__(self):
return '<Atom type="%s" size=%d>' % (self.type_uri.decode('utf-8'), self.size)
return '<Atom type="%s" size=%d>' % (self.type_uri, self.size)
__repr__ = __str__
@property

@ -1,7 +1,7 @@
from libc.stdint cimport uint32_t, int32_t, int64_t, uint8_t, intptr_t
from .core cimport Feature, LV2_Handle
from .urid cimport LV2_URID, URID_Mapper
from .urid cimport LV2_URID, URIDMapper
cdef extern from "lv2/lv2plug.in/ns/ext/options/options.h" nogil:
@ -78,7 +78,7 @@ cdef extern from "lv2/lv2plug.in/ns/ext/options/options.h" nogil:
cdef class Options_Feature(Feature):
cdef URID_Mapper mapper
cdef URIDMapper mapper
cdef LV2_Options_Option[5] options
cdef float sample_rate

@ -1,7 +1,6 @@
from libc cimport stdlib
from libc cimport string
cdef char* allocstr(str s):
cdef char* r
b = s.encode('utf-8')
@ -13,7 +12,7 @@ cdef char* allocstr(str s):
cdef class Options_Feature(Feature):
uri = 'http://lv2plug.in/ns/ext/options#options'
def __cinit__(self, URID_Mapper mapper):
def __cinit__(self, URIDMapper mapper):
self.mapper = mapper
self.sample_rate = 44100

@ -1,5 +1,7 @@
from libc.stdint cimport uint32_t, int32_t, int64_t, uint8_t, intptr_t
from libcpp.memory cimport unique_ptr
from noisicaa.lv2 cimport urid_mapper
from .core cimport Feature
@ -23,6 +25,7 @@ cdef extern from "lv2/lv2plug.in/ns/ext/urid/urid.h" nogil:
cdef class URID_Map_Feature(Feature):
cdef URIDMapper mapper
cdef LV2_URID_Map data
@staticmethod
@ -30,32 +33,24 @@ cdef class URID_Map_Feature(Feature):
cdef class URID_Unmap_Feature(Feature):
cdef URIDMapper mapper
cdef LV2_URID_Unmap data
@staticmethod
cdef const char* urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid) except <const char*>-1 with gil
cdef class URID_Mapper(object):
cpdef LV2_URID map(self, const char* uri) except -1
cpdef const char* unmap(self, LV2_URID urid) except <const char*>-1
cdef class URIDMapper(object):
cdef unique_ptr[urid_mapper.URIDMapper] __mapper_ptr
cdef urid_mapper.URIDMapper* __mapper
cdef urid_mapper.URIDMapper* get(self)
cdef urid_mapper.URIDMapper* release(self)
cdef class URID_StaticMapper(URID_Mapper):
cdef dict url_map
cdef dict url_reverse_map
cdef LV2_URID __next_urid
cdef class StaticURIDMapper(URIDMapper):
pass
cdef LV2_URID __insert(self, const char* uri) except -1
cpdef LV2_URID map(self, const char* uri) except -1
cpdef const char* unmap(self, LV2_URID urid) except <const char*>-1
cdef URID_Mapper get_static_mapper()
cdef class URID_DynamicMapper(URID_StaticMapper):
cdef LV2_URID next_urid
cpdef LV2_URID map(self, const char* uri) except -1
cdef class DynamicURIDMapper(URIDMapper):
pass
cdef URIDMapper get_static_mapper()

@ -2,7 +2,6 @@ from cpython.ref cimport PyObject
from libc cimport stdlib
from libc cimport string
cdef char* allocstr(str s):
cdef char* r
b = s.encode('utf-8')
@ -14,8 +13,10 @@ cdef char* allocstr(str s):
cdef class URID_Map_Feature(Feature):
uri = 'http://lv2plug.in/ns/ext/urid#map'
def __cinit__(self, URID_Mapper mapper):
self.data.handle = <PyObject*>mapper
def __cinit__(self, URIDMapper mapper):
self.mapper = mapper
self.data.handle = self.mapper.get()
self.data.map = self.urid_map
self.lv2_feature.URI = allocstr(self.uri)
@ -23,15 +24,17 @@ cdef class URID_Map_Feature(Feature):
@staticmethod
cdef LV2_URID urid_map(LV2_URID_Map_Handle handle, const char* uri) except -1 with gil:
cdef URID_Mapper mapper = <URID_Mapper>handle
cdef urid_mapper.URIDMapper* mapper = <urid_mapper.URIDMapper*>handle
return mapper.map(uri)
cdef class URID_Unmap_Feature(Feature):
uri = 'http://lv2plug.in/ns/ext/urid#unmap'
def __cinit__(self, URID_Mapper mapper):
self.data.handle = <PyObject*>mapper
def __cinit__(self, URIDMapper mapper):
self.mapper = mapper
self.data.handle = self.mapper.get()
self.data.unmap = self.urid_unmap
self.lv2_feature.URI = allocstr(self.uri)
@ -39,82 +42,47 @@ cdef class URID_Unmap_Feature(Feature):
@staticmethod
cdef const char* urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid) except <const char*>-1 with gil:
cdef URID_Mapper mapper = <URID_Mapper>handle
cdef urid_mapper.URIDMapper* mapper = <urid_mapper.URIDMapper*>handle
return mapper.unmap(urid)
cdef class URID_Mapper(object):
cdef class URIDMapper(object):
def __init__(self):
pass
cpdef LV2_URID map(self, const char* uri) except -1:
raise NotImplementedError
cdef urid_mapper.URIDMapper* get(self):
return self.__mapper
cdef urid_mapper.URIDMapper* release(self):
return self.__mapper_ptr.release()
cdef const char* unmap(self, LV2_URID urid) except <const char*>-1:
raise NotImplementedError
def map(self, uri):
if isinstance(uri, str):
uri = uri.encode('ascii')
cdef LV2_URID urid = self.__mapper.map(uri)
if urid == 0:
raise ValueError("Failed to map uri '%s'" % uri)
return int(urid)
def unmap(self, urid):
cdef const char* uri = self.__mapper.unmap(urid)
if uri == NULL:
raise ValueError("Failed to unmap urid %d" % urid)
return bytes(uri).decode('ascii')
cdef class URID_StaticMapper(URID_Mapper):
cdef class StaticURIDMapper(URIDMapper):
def __init__(self):
URID_Mapper.__init__(self)
self.url_map = {}
self.url_reverse_map = {}
self.__next_urid = 100
self.__insert(b'http://lv2plug.in/ns/ext/midi#MidiEvent')
self.__insert(b'http://lv2plug.in/ns/ext/atom#frameTime')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Blank')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Bool')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Chunk')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Double')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Float')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Int')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Long')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Literal')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Object')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Path')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Property')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Resource')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Sequence')
self.__insert(b'http://lv2plug.in/ns/ext/atom#String')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Tuple')
self.__insert(b'http://lv2plug.in/ns/ext/atom#URI')
self.__insert(b'http://lv2plug.in/ns/ext/atom#URID')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Vector')
self.__insert(b'http://lv2plug.in/ns/ext/atom#Event')
cdef LV2_URID __insert(self, const char* uri) except -1:
assert bytes(uri) not in self.url_map
urid = self.url_map[uri] = self.__next_urid
self.url_reverse_map[urid] = bytes(uri)
self.__next_urid += 1
return urid
cpdef LV2_URID map(self, const char* uri) except -1:
return self.url_map[uri]
cpdef const char* unmap(self, LV2_URID urid) except <const char*>-1:
try:
return self.url_reverse_map[urid]
except KeyError:
return NULL
static_mapper = URID_StaticMapper()
cdef URID_Mapper get_static_mapper():
self.__mapper_ptr.reset(new urid_mapper.StaticURIDMapper())
self.__mapper = self.__mapper_ptr.get()
static_mapper = StaticURIDMapper()
cdef URIDMapper get_static_mapper():
return static_mapper
cdef class URID_DynamicMapper(URID_StaticMapper):
cdef class DynamicURIDMapper(URIDMapper):
def __init__(self):
URID_StaticMapper.__init__(self)
self.next_urid = 1000
cpdef LV2_URID map(self, const char* uri) except -1:
try:
urid = URID_StaticMapper.map(self, uri)
except KeyError:
urid = self.url_map[uri] = self.next_urid
self.url_reverse_map[urid] = bytes(uri)
self.next_urid += 1
return urid
self.__mapper_ptr.reset(new urid_mapper.DynamicURIDMapper())
self.__mapper = self.__mapper_ptr.get()

@ -6,12 +6,12 @@ from . cimport urid
class DynamicMapperTest(unittest.TestCase):
def test_map(self):
cdef urid.URID_Mapper mapper
cdef urid.URIDMapper mapper
cdef urid.URID_Map_Feature feature
cdef core.LV2_Feature* lv2_feature
cdef urid.LV2_URID_Map* map_feature
mapper = urid.URID_DynamicMapper()
mapper = urid.DynamicURIDMapper()
feature = urid.URID_Map_Feature(mapper)
lv2_feature = &feature.lv2_feature
@ -25,7 +25,7 @@ class DynamicMapperTest(unittest.TestCase):
self.assertNotEqual(urid1, urid2)
def test_unmap(self):
cdef urid.URID_Mapper mapper
cdef urid.URIDMapper mapper
cdef urid.URID_Map_Feature map_feature
cdef core.LV2_Feature* map_lv2_feature
cdef urid.LV2_URID_Map* map
@ -33,7 +33,7 @@ class DynamicMapperTest(unittest.TestCase):
cdef core.LV2_Feature* unmap_lv2_feature
cdef urid.LV2_URID_Unmap* unmap
mapper = urid.URID_DynamicMapper()
mapper = urid.DynamicURIDMapper()
map_feature = urid.URID_Map_Feature(mapper)
map_lv2_feature = &map_feature.lv2_feature

@ -1,7 +1,6 @@
from libc.stdint cimport uint32_t, int32_t, int64_t, uint8_t, intptr_t
from .core cimport Feature, LV2_Handle
from .urid cimport LV2_URID, URID_Mapper
cdef extern from "lv2/lv2plug.in/ns/ext/worker/worker.h" nogil:

@ -34,5 +34,5 @@ cdef class Worker_Feature(Feature):
cdef LV2_Worker_Status schedule_work(
LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data):
cdef Worker_Feature self = <Worker_Feature>handle
logger.info("schedule_work(%d, %d)", size, <int>data)
logger.info("schedule_work(%d, %d)", size, <long>data)
return LV2_WORKER_ERR_UNKNOWN

@ -1,11 +1,11 @@
from libc.stdint cimport uint8_t
from libc cimport stdlib
from .lv2.urid cimport URID_Mapper, URID_Map_Feature, URID_Unmap_Feature
from .lv2.urid cimport URID_Map_Feature, URID_Unmap_Feature, URIDMapper
from .lv2.atom cimport LV2_Atom
def atom_to_turtle(URID_Mapper mapper, const uint8_t* atom):
def atom_to_turtle(URIDMapper mapper, const uint8_t* atom):
cdef URID_Map_Feature map = URID_Map_Feature(mapper)
cdef URID_Unmap_Feature unmap = URID_Unmap_Feature(mapper)

@ -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

@ -10,6 +10,7 @@ set(LIB_SRCS
backend_portaudio.cpp
buffers.cpp
host_data.cpp
host_system_lv2.cpp
misc.cpp
opcodes.cpp
processor_spec.cpp
@ -45,6 +46,7 @@ add_py_capnp(block_data.capnp)
add_library(noisicore SHARED ${LIB_SRCS} block_data.capnp.c++)
target_compile_options(noisicore PRIVATE -fPIC -std=c++11 -Wall -Werror -pedantic -DHAVE_PTHREAD_SPIN_LOCK)
target_link_libraries(noisicore PRIVATE noisicaa-core)
target_link_libraries(noisicore PRIVATE noisicaa-lv2)
target_link_libraries(noisicore PRIVATE capnp)
target_link_libraries(noisicore PRIVATE pthread)
target_link_libraries(noisicore PRIVATE portaudio)

@ -68,7 +68,7 @@ Status AtomData::clear_buffer(HostData* host_data, uint32_t block_size, BufferPt
memset(buf, 0, 10240);
LV2_Atom_Forge forge;
lv2_atom_forge_init(&forge, host_data->lv2->urid_map);
lv2_atom_forge_init(&forge, &host_data->lv2->urid_map);
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_set_buffer(&forge, buf, 10240);
@ -93,7 +93,7 @@ Status AtomData::mix_buffers(HostData* host_data, uint32_t block_size, const Buf
LV2_Atom_Event* event2 = lv2_atom_sequence_begin(&seq2->body);
LV2_Atom_Forge forge;
lv2_atom_forge_init(&forge, host_data->lv2->urid_map);
lv2_atom_forge_init(&forge, &host_data->lv2->urid_map);
uint8_t merged[10240];
memset(merged, 0, 10240);

@ -4,7 +4,7 @@ from .buffers cimport *
from .host_data cimport *
from noisicaa.bindings.lv2 cimport atom
from noisicaa.bindings.lv2 cimport urid
from noisicaa.bindings.lv2 import urid
import struct
import sys
@ -194,12 +194,10 @@ class TestFloatAudioBlock(unittest.TestCase):
cdef _fill_atom_buffer(Buffer* buf, data):
cdef urid.URID_Mapper mapper = urid.get_static_mapper()
cdef atom.AtomForge forge = atom.AtomForge(mapper)
cdef atom.AtomForge forge = atom.AtomForge(urid.static_mapper)
forge.set_buffer(buf.data(), buf.size())
string_urid = mapper.map(b'http://lv2plug.in/ns/ext/atom#String')
string_urid = urid.static_mapper.map('http://lv2plug.in/ns/ext/atom#String')
with forge.sequence():
for frames, item in data:
forge.write_atom_event(frames, string_urid, item, len(item))
@ -207,10 +205,10 @@ cdef _fill_atom_buffer(Buffer* buf, data):
cdef _read_atom_buffer(Buffer* buf):
result = []
cdef urid.URID_Mapper mapper = urid.get_static_mapper()
seq = atom.Atom.wrap(mapper, buf.data())
seq = atom.Atom.wrap(urid.static_mapper, buf.data())
assert isinstance(seq, atom.Sequence), type(seq)
for event in seq.events:
assert event.atom.type_uri == b'http://lv2plug.in/ns/ext/atom#String'
assert event.atom.type_uri == 'http://lv2plug.in/ns/ext/atom#String'
result.append((event.frames, event.atom.data))
return result
@ -221,7 +219,6 @@ class TestAtomData(unittest.TestCase):
Status status
unique_ptr[Buffer] bufptr
Buffer* buf
urid.URID_Map_Feature mapper
cdef PyHostData host_data = PyHostData()
host_data.setup()
@ -240,7 +237,6 @@ class TestAtomData(unittest.TestCase):
Status status
unique_ptr[Buffer] bufptr
Buffer* buf
urid.URID_Map_Feature mapper
cdef PyHostData host_data = PyHostData()
host_data.setup()
@ -260,7 +256,6 @@ class TestAtomData(unittest.TestCase):
Status status
unique_ptr[Buffer] bufptr
Buffer* buf
urid.URID_Map_Feature mapper
cdef PyHostData host_data = PyHostData()
host_data.setup()
@ -280,7 +275,6 @@ class TestAtomData(unittest.TestCase):
unique_ptr[Buffer] bufptr2
Buffer* buf1
Buffer* buf2
urid.URID_Map_Feature mapper
cdef PyHostData host_data = PyHostData()
host_data.setup()

@ -3,60 +3,6 @@
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.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::map(const string& uri) {
return urid_map->map(urid_map->handle, uri.c_str());
}
string LV2SubSystem::unmap(LV2_URID urid) {
return urid_unmap->unmap(urid_unmap->handle, urid);
}
HostData::HostData()
: lv2(new LV2SubSystem()) {}

@ -4,52 +4,11 @@
#define _NOISICORE_HOST_DATA_H
#include <memory>
#include "lilv/lilv.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#include "noisicore/host_system_lv2.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;
LV2_URID_Unmap* urid_unmap = nullptr;
LV2_URID map(const string& uri);
string unmap(LV2_URID 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;
};
class HostData {
public:
HostData();

@ -1,5 +1,4 @@
from libcpp.memory cimport unique_ptr
from noisicaa.bindings.lv2.urid cimport *
from .status cimport *
cdef extern from "noisicore/host_data.h" namespace "noisicaa" nogil:
@ -7,9 +6,6 @@ cdef extern from "noisicore/host_data.h" namespace "noisicaa" nogil:
Status setup()
void cleanup()
LV2_URID_Map* urid_map;
LV2_URID_Unmap* urid_unmap;
cppclass HostData:
Status setup()
void cleanup()
@ -20,8 +16,5 @@ cdef extern from "noisicore/host_data.h" namespace "noisicaa" nogil:
cdef class PyHostData(object):
cdef unique_ptr[HostData] __host_data_ptr
cdef HostData* __host_data
cdef URID_Mapper __mapper
cdef URID_Map_Feature __map_feature
cdef URID_Unmap_Feature __unmap_feature
cdef HostData* ptr(self)

@ -6,15 +6,6 @@ cdef class PyHostData(object):
self.__host_data = self.__host_data_ptr.get()
def setup(self):
# TODO: move this to C++ code
self.__mapper = get_static_mapper()
self.__map_feature = URID_Map_Feature(self.__mapper)
self.__unmap_feature = URID_Unmap_Feature(self.__mapper)
cdef LV2SubSystem* lv2 = self.__host_data.lv2.get()
lv2.urid_map = &self.__map_feature.data
lv2.urid_unmap = &self.__unmap_feature.data
check(self.__host_data.setup())
def cleanup(self):

@ -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

@ -134,7 +134,7 @@ Status run_MIDI_MONKEY(BlockContext* ctxt, ProgramState* state, const vector<OpA
Buffer* buf = state->program->buffers[idx].get();
LV2_Atom_Forge forge;
lv2_atom_forge_init(&forge, state->host_data->lv2->urid_map);
lv2_atom_forge_init(&forge, &state->host_data->lv2->urid_map);
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_set_buffer(&forge, buf->data(), buf->size());

@ -3,8 +3,7 @@ from libcpp.string cimport string
from libcpp.memory cimport unique_ptr
from noisicaa.bindings.lv2 cimport atom
from noisicaa.bindings.lv2 cimport urid
from noisicaa.bindings.lv2 import urid
from .status cimport *
from .block_context cimport *
from .buffers cimport *
@ -129,7 +128,7 @@ class TestProcessorCSound(unittest.TestCase):
processor.connect_port(0, <BufferPtr>inbuf)
processor.connect_port(1, <BufferPtr>outbuf)
cdef atom.AtomForge forge = atom.AtomForge(urid.get_static_mapper())
cdef atom.AtomForge forge = atom.AtomForge(urid.static_mapper)
forge.set_buffer(inbuf, 10240)
with forge.sequence():
forge.write_midi_event(0, bytes([0x90, 60, 100]), 3)

@ -9,13 +9,14 @@ from .processor_spec cimport *
from .host_data cimport *
from noisicaa.bindings.lv2 cimport atom
from noisicaa.bindings.lv2 import urid
import unittest
import sys
class TestProcessorFluidSynth(unittest.TestCase):
def test_ladspa(self):
def test_fluidsynth(self):
cdef Status status
cdef PyHostData host_data = PyHostData()
@ -47,7 +48,7 @@ class TestProcessorFluidSynth(unittest.TestCase):
check(processor.connect_port(1, <BufferPtr>outleftbuf))
check(processor.connect_port(2, <BufferPtr>outrightbuf))
cdef atom.AtomForge forge = atom.AtomForge(urid.get_static_mapper())
cdef atom.AtomForge forge = atom.AtomForge(urid.static_mapper)
forge.set_buffer(inbuf, 10240)
with forge.sequence():
forge.write_midi_event(0, bytes([0x90, 60, 100]), 3)

Loading…
Cancel
Save