diff options
Diffstat (limited to 'props.lv2/test')
-rw-r--r-- | props.lv2/test/chunk.bin | bin | 0 -> 16 bytes | |||
-rw-r--r-- | props.lv2/test/manifest.ttl.in | 28 | ||||
-rw-r--r-- | props.lv2/test/props.c | 321 | ||||
-rw-r--r-- | props.lv2/test/props.ttl | 152 |
4 files changed, 501 insertions, 0 deletions
diff --git a/props.lv2/test/chunk.bin b/props.lv2/test/chunk.bin Binary files differnew file mode 100644 index 0000000..b66efb8 --- /dev/null +++ b/props.lv2/test/chunk.bin diff --git a/props.lv2/test/manifest.ttl.in b/props.lv2/test/manifest.ttl.in new file mode 100644 index 0000000..c477aeb --- /dev/null +++ b/props.lv2/test/manifest.ttl.in @@ -0,0 +1,28 @@ +# Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch) +# +# This is free software: you can redistribute it and/or modify +# it under the terms of the Artistic License 2.0 as published by +# The Perl Foundation. +# +# This source 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 +# Artistic License 2.0 for more details. +# +# You should have received a copy of the Artistic License 2.0 +# along the source as a COPYING file. If not, obtain it from +# http://www.perlfoundation.org/artistic_license_2_0. + +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . + +@prefix props: <http://open-music-kontrollers.ch/lv2/props#> . + +# Orbit Looper +props:test + a lv2:Plugin ; + lv2:minorVersion @PROPS_MINOR_VERSION@ ; + lv2:microVersion @PROPS_MICRO_VERSION@ ; + lv2:binary <props@LIB_EXT@> ; + rdfs:seeAlso <props.ttl> . diff --git a/props.lv2/test/props.c b/props.lv2/test/props.c new file mode 100644 index 0000000..edeac6a --- /dev/null +++ b/props.lv2/test/props.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch) + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the Artistic License 2.0 as published by + * The Perl Foundation. + * + * This source 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 + * Artistic License 2.0 for more details. + * + * You should have received a copy of the Artistic License 2.0 + * along the source as a COPYING file. If not, obtain it from + * http://www.perlfoundation.org/artistic_license_2_0. + */ + +#include <stdio.h> + +#include <props.h> + +#include <lv2/lv2plug.in/ns/ext/log/log.h> +#include <lv2/lv2plug.in/ns/ext/log/logger.h> + +#define PROPS_PREFIX "http://open-music-kontrollers.ch/lv2/props#" +#define PROPS_TEST_URI PROPS_PREFIX"test" + +#define MAX_NPROPS 7 +#define MAX_STRLEN 256 + +typedef struct _plugstate_t plugstate_t; +typedef struct _plughandle_t plughandle_t; + +struct _plugstate_t { + int32_t val1; + int64_t val2; + float val3; + double val4; + char val5 [MAX_STRLEN]; + char val6 [MAX_STRLEN]; + uint8_t val7 [MAX_STRLEN]; +}; + +struct _plughandle_t { + LV2_URID_Map *map; + LV2_Log_Log *log; + LV2_Log_Logger logger; + LV2_Atom_Forge forge; + LV2_Atom_Forge_Ref ref; + + PROPS_T(props, MAX_NPROPS); + plugstate_t state; + plugstate_t stash; + + struct { + LV2_URID val2; + LV2_URID val4; + } urid; + + const LV2_Atom_Sequence *event_in; + LV2_Atom_Sequence *event_out; +}; + +static void +_intercept(void *data, int64_t frames, props_impl_t *impl) +{ + plughandle_t *handle = data; + + lv2_log_trace(&handle->logger, "SET : %s\n", impl->def->property); +} + +static void +_intercept_stat1(void *data, int64_t frames, props_impl_t *impl) +{ + plughandle_t *handle = data; + + _intercept(data, frames, impl); + + handle->state.val2 = handle->state.val1 * 2; + + props_set(&handle->props, &handle->forge, frames, handle->urid.val2, &handle->ref); +} + +static void +_intercept_stat3(void *data, int64_t frames, props_impl_t *impl) +{ + plughandle_t *handle = data; + + _intercept(data, frames, impl); + + handle->state.val4 = handle->state.val3 * 2; + + props_set(&handle->props, &handle->forge, frames, handle->urid.val4, &handle->ref); +} + +static void +_intercept_stat6(void *data, int64_t frames, props_impl_t *impl) +{ + plughandle_t *handle = data; + + _intercept(data, frames, impl); + + const char *path = strstr(handle->state.val6, "file://") + ? handle->state.val6 + 7 // skip "file://" + : handle->state.val6; + FILE *f = fopen(path, "wb"); // create empty file + if(f) + fclose(f); +} + +static const props_def_t defs [MAX_NPROPS] = { + { + .property = PROPS_PREFIX"statInt", + .offset = offsetof(plugstate_t, val1), + .type = LV2_ATOM__Int, + .event_cb = _intercept_stat1, + }, + { + .property = PROPS_PREFIX"statLong", + .access = LV2_PATCH__readable, + .offset = offsetof(plugstate_t, val2), + .type = LV2_ATOM__Long, + .event_cb = _intercept, + }, + { + .property = PROPS_PREFIX"statFloat", + .offset = offsetof(plugstate_t, val3), + .type = LV2_ATOM__Float, + .event_cb = _intercept_stat3, + }, + { + .property = PROPS_PREFIX"statDouble", + .access = LV2_PATCH__readable, + .offset = offsetof(plugstate_t, val4), + .type = LV2_ATOM__Double, + .event_cb = _intercept, + }, + { + .property = PROPS_PREFIX"statString", + .offset = offsetof(plugstate_t, val5), + .type = LV2_ATOM__String, + .event_cb = _intercept, + .max_size = MAX_STRLEN // strlen + }, + { + .property = PROPS_PREFIX"statPath", + .offset = offsetof(plugstate_t, val6), + .type = LV2_ATOM__Path, + .event_cb = _intercept_stat6, + .max_size = MAX_STRLEN // strlen + }, + { + .property = PROPS_PREFIX"statChunk", + .offset = offsetof(plugstate_t, val7), + .type = LV2_ATOM__Chunk, + .event_cb = _intercept, + .max_size = MAX_STRLEN // strlen + } +}; + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, double rate, + const char *bundle_path, const LV2_Feature *const *features) +{ + plughandle_t *handle = calloc(1, sizeof(plughandle_t)); + if(!handle) + return NULL; + + for(unsigned i=0; features[i]; i++) + { + if(!strcmp(features[i]->URI, LV2_URID__map)) + handle->map = features[i]->data; + else if(!strcmp(features[i]->URI, LV2_LOG__log)) + handle->log = features[i]->data; + } + + if(!handle->map) + { + fprintf(stderr, + "%s: Host does not support urid:map\n", descriptor->URI); + free(handle); + return NULL; + } + if(!handle->log) + { + fprintf(stderr, + "%s: Host does not support log:log\n", descriptor->URI); + free(handle); + return NULL; + } + + lv2_log_logger_init(&handle->logger, handle->map, handle->log); + lv2_atom_forge_init(&handle->forge, handle->map); + + if(!props_init(&handle->props, descriptor->URI, + defs, MAX_NPROPS, &handle->state, &handle->stash, + handle->map, handle)) + { + lv2_log_error(&handle->logger, "failed to initialize property structure\n"); + free(handle); + return NULL; + } + + handle->urid.val2 = props_map(&handle->props, PROPS_PREFIX"statLong"); + handle->urid.val4 = props_map(&handle->props, PROPS_PREFIX"statDouble"); + + return handle; +} + +static void +connect_port(LV2_Handle instance, uint32_t port, void *data) +{ + plughandle_t *handle = (plughandle_t *)instance; + + switch(port) + { + case 0: + handle->event_in = (const LV2_Atom_Sequence *)data; + break; + case 1: + handle->event_out = (LV2_Atom_Sequence *)data; + break; + default: + break; + } +} + +static void +run(LV2_Handle instance, uint32_t nsamples) +{ + plughandle_t *handle = instance; + + uint32_t capacity = handle->event_out->atom.size; + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_set_buffer(&handle->forge, (uint8_t *)handle->event_out, capacity); + handle->ref = lv2_atom_forge_sequence_head(&handle->forge, &frame, 0); + + props_idle(&handle->props, &handle->forge, 0, &handle->ref); + + LV2_ATOM_SEQUENCE_FOREACH(handle->event_in, ev) + { + const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body; + + if(handle->ref) + props_advance(&handle->props, &handle->forge, ev->time.frames, obj, &handle->ref); + } + + if(handle->ref) + lv2_atom_forge_pop(&handle->forge, &frame); + else + lv2_atom_sequence_clear(handle->event_out); +} + +static void +cleanup(LV2_Handle instance) +{ + plughandle_t *handle = instance; + + free(handle); +} + +static LV2_State_Status +_state_save(LV2_Handle instance, LV2_State_Store_Function store, + LV2_State_Handle state, uint32_t flags, + const LV2_Feature *const *features) +{ + plughandle_t *handle = (plughandle_t *)instance; + + return props_save(&handle->props, store, state, flags, features); +} + +static LV2_State_Status +_state_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, + LV2_State_Handle state, uint32_t flags, + const LV2_Feature *const *features) +{ + plughandle_t *handle = (plughandle_t *)instance; + + return props_restore(&handle->props, retrieve, state, flags, features); +} + +LV2_State_Interface state_iface = { + .save = _state_save, + .restore = _state_restore +}; + +static const void * +extension_data(const char *uri) +{ + if(!strcmp(uri, LV2_STATE__interface)) + return &state_iface; + return NULL; +} + +const LV2_Descriptor props_test = { + .URI = PROPS_TEST_URI, + .instantiate = instantiate, + .connect_port = connect_port, + .activate = NULL, + .run = run, + .deactivate = NULL, + .cleanup = cleanup, + .extension_data = extension_data +}; + +#ifdef _WIN32 +__declspec(dllexport) +#else +__attribute__((visibility("default"))) +#endif +const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch(index) + { + case 0: + return &props_test; + default: + return NULL; + } +} diff --git a/props.lv2/test/props.ttl b/props.lv2/test/props.ttl new file mode 100644 index 0000000..0ce45d6 --- /dev/null +++ b/props.lv2/test/props.ttl @@ -0,0 +1,152 @@ +# Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch) +# +# This is free software: you can redistribute it and/or modify +# it under the terms of the Artistic License 2.0 as published by +# The Perl Foundation. +# +# This source 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 +# Artistic License 2.0 for more details. +# +# You should have received a copy of the Artistic License 2.0 +# along the source as a COPYING file. If not, obtain it from +# http://www.perlfoundation.org/artistic_license_2_0. + +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix atom: <http://lv2plug.in/ns/ext/atom#> . +@prefix urid: <http://lv2plug.in/ns/ext/urid#> . +@prefix state: <http://lv2plug.in/ns/ext/state#> . +@prefix patch: <http://lv2plug.in/ns/ext/patch#> . +@prefix log: <http://lv2plug.in/ns/ext/log#> . +@prefix units: <http://lv2plug.in/ns/extensions/units#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +@prefix lic: <http://opensource.org/licenses/> . +@prefix omk: <http://open-music-kontrollers.ch/ventosus#> . +@prefix proj: <http://open-music-kontrollers.ch/lv2/> . +@prefix props: <http://open-music-kontrollers.ch/lv2/props#> . + +# Maintainer +omk:me + a foaf:Person ; + foaf:name "Hanspeter Portner" ; + foaf:mbox <mailto:dev@open-music-kontrollers.ch> ; + foaf:homepage <http://open-music-kontrollers.ch> . + +# Project +proj:props + a doap:Project ; + doap:maintainer omk:me ; + doap:name "Props Bundle" . + +props:statInt + a lv2:Parameter ; + rdfs:range atom:Int ; + rdfs:label "statInt" ; + rdfs:comment "This is a 32-bit integer" ; + units:unit units:hz ; + lv2:minimum 0 ; + lv2:maximum 10 . + +props:statLong + a lv2:Parameter ; + rdfs:range atom:Long ; + rdfs:label "statLong" ; + rdfs:comment "This is a 64-bit integer" ; + units:unit units:khz ; + lv2:minimum 0 ; + lv2:maximum 20 . + +props:statFloat + a lv2:Parameter ; + rdfs:range atom:Float ; + rdfs:label "statFloat" ; + rdfs:comment "This is a 32-bit float" ; + units:unit units:mhz ; + lv2:minimum -0.5 ; + lv2:maximum 0.5 . + +props:statDouble + a lv2:Parameter ; + rdfs:range atom:Double ; + rdfs:label "statDouble" ; + rdfs:comment "This is a 64-bit double" ; + units:unit units:db ; + lv2:minimum -1.0 ; + lv2:maximum 1.0 . + +props:statString + a lv2:Parameter ; + rdfs:range atom:String ; + rdfs:label "statString" ; + rdfs:comment "This is a string" . + +props:statPath + a lv2:Parameter ; + rdfs:range atom:Path ; + rdfs:label "statPath" ; + rdfs:comment "This is a path" . + +props:statChunk + a lv2:Parameter ; + rdfs:range atom:Chunk; + rdfs:label "statChunk" ; + rdfs:comment "This is a chunk" . + +# Looper Test +props:test + a lv2:Plugin , + lv2:ConverterPlugin ; + doap:name "Props Test" ; + doap:license lic:Artistic-2.0 ; + lv2:project proj:props ; + lv2:requiredFeature urid:map, log:log, state:loadDefaultState ; + lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, state:threadSafeRestore ; + lv2:extensionData state:interface ; + + lv2:port [ + # sink event port + a lv2:InputPort , + atom:AtomPort ; + atom:bufferType atom:Sequence ; + atom:supports patch:Message ; + lv2:index 0 ; + lv2:symbol "event_in" ; + lv2:name "Event Input" ; + lv2:designation lv2:control ; + ] , [ + # source event port + a lv2:OutputPort , + atom:AtomPort ; + atom:bufferType atom:Sequence ; + atom:supports patch:Message ; + lv2:index 1 ; + lv2:symbol "event_out" ; + lv2:name "Event Output" ; + lv2:designation lv2:control ; + ] ; + + patch:writable + props:statInt , + props:statFloat , + props:statString , + props:statPath , + props:statChunk ; + + patch:readable + props:statLong , + props:statDouble ; + + state:state [ + props:statInt 4 ; + props:statFloat "0.4"^^xsd:float ; + props:statString "Hello world" ; + props:statPath <props.ttl> ; + props:statChunk "AQIDBAUGBw=="^^xsd:base64Binary ; + ] . |