From 6e19a062b248de1a5de60e5782ef4a8bb2826f47 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 2 Nov 2014 07:07:53 +0000 Subject: Add gain parameter to eg-sampler. --- plugins/eg-sampler.lv2/sampler.c | 41 ++++++++++++++++++++++++++++++++------ plugins/eg-sampler.lv2/sampler.ttl | 2 ++ plugins/eg-sampler.lv2/uris.h | 5 +++++ 3 files changed, 42 insertions(+), 6 deletions(-) (limited to 'plugins/eg-sampler.lv2') diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c index 0471a90..3be9730 100644 --- a/plugins/eg-sampler.lv2/sampler.c +++ b/plugins/eg-sampler.lv2/sampler.c @@ -84,6 +84,7 @@ typedef struct { uint32_t frame_offset; // Playback state + float gain; sf_count_t frame; bool play; } Sampler; @@ -309,6 +310,9 @@ cleanup(LV2_Handle instance) free(self); } +/** Define a macro for converting a gain in dB to a coefficient. */ +#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f) + static void run(LV2_Handle instance, uint32_t sample_count) @@ -345,11 +349,36 @@ run(LV2_Handle instance, } else if (lv2_atom_forge_is_object_type(&self->forge, ev->body.type)) { const LV2_Atom_Object* obj = (const LV2_Atom_Object*)&ev->body; if (obj->body.otype == uris->patch_Set) { - // Received a set message, send it to the worker. - lv2_log_trace(&self->logger, "Queueing set message\n"); - self->schedule->schedule_work(self->schedule->handle, - lv2_atom_total_size(&ev->body), - &ev->body); + // Get the property and value of the set message + const LV2_Atom* property = NULL; + const LV2_Atom* value = NULL; + lv2_atom_object_get(obj, + uris->patch_property, &property, + uris->patch_value, &value, + 0); + if (!property) { + lv2_log_error(&self->logger, + "patch:Set message with no property\n"); + continue; + } else if (property->type != uris->atom_URID) { + lv2_log_error(&self->logger, + "patch:Set property is not a URID\n"); + continue; + } + + const uint32_t key = ((const LV2_Atom_URID*)property)->body; + if (key == uris->eg_sample) { + // Sample change, send it to the worker. + lv2_log_trace(&self->logger, "Queueing set message\n"); + self->schedule->schedule_work(self->schedule->handle, + lv2_atom_total_size(&ev->body), + &ev->body); + } else if (key == uris->param_gain) { + // Gain change + if (value->type == uris->atom_Float) { + self->gain = DB_CO(((LV2_Atom_Float*)value)->body); + } + } } else if (obj->body.otype == uris->patch_Get) { // Received a get message, emit our state (probably to UI) lv2_log_trace(&self->logger, "Responding to get request\n"); @@ -377,7 +406,7 @@ run(LV2_Handle instance, } for (; pos < sample_count && f < lf; ++pos, ++f) { - output[pos] = self->sample->data[f]; + output[pos] = self->sample->data[f] * self->gain; } self->frame = f; diff --git a/plugins/eg-sampler.lv2/sampler.ttl b/plugins/eg-sampler.lv2/sampler.ttl index 2a89dd2..197a735 100644 --- a/plugins/eg-sampler.lv2/sampler.ttl +++ b/plugins/eg-sampler.lv2/sampler.ttl @@ -7,6 +7,7 @@ @prefix ui: . @prefix urid: . @prefix work: . +@prefix param: . a lv2:Parameter ; @@ -26,6 +27,7 @@ work:interface ; ui:ui ; patch:writable ; + patch:writable param:gain ; lv2:port [ a lv2:InputPort , atom:AtomPort ; diff --git a/plugins/eg-sampler.lv2/uris.h b/plugins/eg-sampler.lv2/uris.h index c21c6c8..e7c4dcd 100644 --- a/plugins/eg-sampler.lv2/uris.h +++ b/plugins/eg-sampler.lv2/uris.h @@ -21,6 +21,7 @@ #include "lv2/lv2plug.in/ns/ext/log/log.h" #include "lv2/lv2plug.in/ns/ext/midi/midi.h" #include "lv2/lv2plug.in/ns/ext/state/state.h" +#include "lv2/lv2plug.in/ns/ext/parameters/parameters.h" #define EG_SAMPLER_URI "http://lv2plug.in/plugins/eg-sampler" #define EG_SAMPLER__sample EG_SAMPLER_URI "#sample" @@ -28,6 +29,7 @@ #define EG_SAMPLER__freeSample EG_SAMPLER_URI "#freeSample" typedef struct { + LV2_URID atom_Float; LV2_URID atom_Path; LV2_URID atom_Resource; LV2_URID atom_Sequence; @@ -37,6 +39,7 @@ typedef struct { LV2_URID eg_sample; LV2_URID eg_freeSample; LV2_URID midi_Event; + LV2_URID param_gain; LV2_URID patch_Get; LV2_URID patch_Set; LV2_URID patch_property; @@ -46,6 +49,7 @@ typedef struct { static inline void map_sampler_uris(LV2_URID_Map* map, SamplerURIs* uris) { + uris->atom_Float = map->map(map->handle, LV2_ATOM__Float); uris->atom_Path = map->map(map->handle, LV2_ATOM__Path); uris->atom_Resource = map->map(map->handle, LV2_ATOM__Resource); uris->atom_Sequence = map->map(map->handle, LV2_ATOM__Sequence); @@ -55,6 +59,7 @@ map_sampler_uris(LV2_URID_Map* map, SamplerURIs* uris) uris->eg_freeSample = map->map(map->handle, EG_SAMPLER__freeSample); uris->eg_sample = map->map(map->handle, EG_SAMPLER__sample); uris->midi_Event = map->map(map->handle, LV2_MIDI__MidiEvent); + uris->param_gain = map->map(map->handle, LV2_PARAMETERS__gain); uris->patch_Get = map->map(map->handle, LV2_PATCH__Get); uris->patch_Set = map->map(map->handle, LV2_PATCH__Set); uris->patch_property = map->map(map->handle, LV2_PATCH__property); -- cgit v1.2.1