aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/eg-sampler.lv2
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-12-26 19:21:17 +0100
committerDavid Robillard <d@drobilla.net>2020-12-26 19:21:17 +0100
commit882b9446cbf7316345de391188e68c2a7333da5b (patch)
tree5baf31e0a28313b380cc7e8694b09a2a517d14f3 /plugins/eg-sampler.lv2
parent8d2251749da9e0ae4254502edfc8917236a9b8c0 (diff)
downloadlv2-882b9446cbf7316345de391188e68c2a7333da5b.tar.xz
Format all code with clang-format
Diffstat (limited to 'plugins/eg-sampler.lv2')
-rw-r--r--plugins/eg-sampler.lv2/atom_sink.h12
-rw-r--r--plugins/eg-sampler.lv2/peaks.h290
-rw-r--r--plugins/eg-sampler.lv2/sampler.c904
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c586
-rw-r--r--plugins/eg-sampler.lv2/uris.h189
5 files changed, 982 insertions, 999 deletions
diff --git a/plugins/eg-sampler.lv2/atom_sink.h b/plugins/eg-sampler.lv2/atom_sink.h
index 659b767..57035e1 100644
--- a/plugins/eg-sampler.lv2/atom_sink.h
+++ b/plugins/eg-sampler.lv2/atom_sink.h
@@ -30,11 +30,11 @@
static LV2_Atom_Forge_Ref
atom_sink(LV2_Atom_Forge_Sink_Handle handle, const void* buf, uint32_t size)
{
- LV2_Atom* atom = (LV2_Atom*)handle;
- const uint32_t offset = lv2_atom_total_size(atom);
- memcpy((char*)atom + offset, buf, size);
- atom->size += size;
- return offset;
+ LV2_Atom* atom = (LV2_Atom*)handle;
+ const uint32_t offset = lv2_atom_total_size(atom);
+ memcpy((char*)atom + offset, buf, size);
+ atom->size += size;
+ return offset;
}
/**
@@ -43,5 +43,5 @@ atom_sink(LV2_Atom_Forge_Sink_Handle handle, const void* buf, uint32_t size)
static LV2_Atom*
atom_sink_deref(LV2_Atom_Forge_Sink_Handle handle, LV2_Atom_Forge_Ref ref)
{
- return (LV2_Atom*)((char*)handle + ref);
+ return (LV2_Atom*)((char*)handle + ref);
}
diff --git a/plugins/eg-sampler.lv2/peaks.h b/plugins/eg-sampler.lv2/peaks.h
index 2bf1023..ca5328d 100644
--- a/plugins/eg-sampler.lv2/peaks.h
+++ b/plugins/eg-sampler.lv2/peaks.h
@@ -39,42 +39,42 @@
#include <stdlib.h>
#include <string.h>
-#define PEAKS_URI "http://lv2plug.in/ns/peaks#"
-#define PEAKS__PeakUpdate PEAKS_URI "PeakUpdate"
-#define PEAKS__magnitudes PEAKS_URI "magnitudes"
-#define PEAKS__offset PEAKS_URI "offset"
-#define PEAKS__total PEAKS_URI "total"
+#define PEAKS_URI "http://lv2plug.in/ns/peaks#"
+#define PEAKS__PeakUpdate PEAKS_URI "PeakUpdate"
+#define PEAKS__magnitudes PEAKS_URI "magnitudes"
+#define PEAKS__offset PEAKS_URI "offset"
+#define PEAKS__total PEAKS_URI "total"
#ifndef MIN
-# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
-# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
typedef struct {
- LV2_URID atom_Float;
- LV2_URID atom_Int;
- LV2_URID atom_Vector;
- LV2_URID peaks_PeakUpdate;
- LV2_URID peaks_magnitudes;
- LV2_URID peaks_offset;
- LV2_URID peaks_total;
+ LV2_URID atom_Float;
+ LV2_URID atom_Int;
+ LV2_URID atom_Vector;
+ LV2_URID peaks_PeakUpdate;
+ LV2_URID peaks_magnitudes;
+ LV2_URID peaks_offset;
+ LV2_URID peaks_total;
} PeaksURIs;
typedef struct {
- PeaksURIs uris; ///< URIDs used in protocol
- const float* samples; ///< Sample data
- uint32_t n_samples; ///< Total number of samples
- uint32_t n_peaks; ///< Total number of peaks
- uint32_t current_offset; ///< Current peak offset
- bool sending; ///< True iff currently sending
+ PeaksURIs uris; ///< URIDs used in protocol
+ const float* samples; ///< Sample data
+ uint32_t n_samples; ///< Total number of samples
+ uint32_t n_peaks; ///< Total number of peaks
+ uint32_t current_offset; ///< Current peak offset
+ bool sending; ///< True iff currently sending
} PeaksSender;
typedef struct {
- PeaksURIs uris; ///< URIDs used in protocol
- float* peaks; ///< Received peaks, or zeroes
- uint32_t n_peaks; ///< Total number of peaks
+ PeaksURIs uris; ///< URIDs used in protocol
+ float* peaks; ///< Received peaks, or zeroes
+ uint32_t n_peaks; ///< Total number of peaks
} PeaksReceiver;
/**
@@ -83,13 +83,13 @@ typedef struct {
static inline void
peaks_map_uris(PeaksURIs* uris, LV2_URID_Map* map)
{
- uris->atom_Float = map->map(map->handle, LV2_ATOM__Float);
- uris->atom_Int = map->map(map->handle, LV2_ATOM__Int);
- uris->atom_Vector = map->map(map->handle, LV2_ATOM__Vector);
- uris->peaks_PeakUpdate = map->map(map->handle, PEAKS__PeakUpdate);
- uris->peaks_magnitudes = map->map(map->handle, PEAKS__magnitudes);
- uris->peaks_offset = map->map(map->handle, PEAKS__offset);
- uris->peaks_total = map->map(map->handle, PEAKS__total);
+ uris->atom_Float = map->map(map->handle, LV2_ATOM__Float);
+ uris->atom_Int = map->map(map->handle, LV2_ATOM__Int);
+ uris->atom_Vector = map->map(map->handle, LV2_ATOM__Vector);
+ uris->peaks_PeakUpdate = map->map(map->handle, PEAKS__PeakUpdate);
+ uris->peaks_magnitudes = map->map(map->handle, PEAKS__magnitudes);
+ uris->peaks_offset = map->map(map->handle, PEAKS__offset);
+ uris->peaks_total = map->map(map->handle, PEAKS__total);
}
/**
@@ -100,9 +100,9 @@ peaks_map_uris(PeaksURIs* uris, LV2_URID_Map* map)
static inline PeaksSender*
peaks_sender_init(PeaksSender* sender, LV2_URID_Map* map)
{
- memset(sender, 0, sizeof(*sender));
- peaks_map_uris(&sender->uris, map);
- return sender;
+ memset(sender, 0, sizeof(*sender));
+ peaks_map_uris(&sender->uris, map);
+ return sender;
}
/**
@@ -115,11 +115,11 @@ peaks_sender_start(PeaksSender* sender,
uint32_t n_samples,
uint32_t n_peaks)
{
- sender->samples = samples;
- sender->n_samples = n_samples;
- sender->n_peaks = n_peaks;
- sender->current_offset = 0;
- sender->sending = true;
+ sender->samples = samples;
+ sender->n_samples = n_samples;
+ sender->n_peaks = n_peaks;
+ sender->current_offset = 0;
+ sender->sending = true;
}
/**
@@ -129,10 +129,10 @@ peaks_sender_start(PeaksSender* sender,
[source,turtle]
----
[]
- a peaks:PeakUpdate ;
- peaks:offset 256 ;
- peaks:total 1024 ;
- peaks:magnitudes [ 0.2f, 0.3f, ... ] .
+ a peaks:PeakUpdate ;
+ peaks:offset 256 ;
+ peaks:total 1024 ;
+ peaks:magnitudes [ 0.2f, 0.3f, ... ] .
----
*/
static inline bool
@@ -141,53 +141,53 @@ peaks_sender_send(PeaksSender* sender,
uint32_t n_frames,
uint32_t offset)
{
- const PeaksURIs* uris = &sender->uris;
- if (!sender->sending || sender->current_offset >= sender->n_peaks) {
- return sender->sending = false;
- }
-
- // Start PeakUpdate object
- lv2_atom_forge_frame_time(forge, offset);
- LV2_Atom_Forge_Frame frame;
- lv2_atom_forge_object(forge, &frame, 0, uris->peaks_PeakUpdate);
-
- // eg:offset = OFFSET
- lv2_atom_forge_key(forge, uris->peaks_offset);
- lv2_atom_forge_int(forge, sender->current_offset);
-
- // eg:total = TOTAL
- lv2_atom_forge_key(forge, uris->peaks_total);
- lv2_atom_forge_int(forge, sender->n_peaks);
-
- // eg:magnitudes = Vector<Float>(PEAK, PEAK, ...)
- lv2_atom_forge_key(forge, uris->peaks_magnitudes);
- LV2_Atom_Forge_Frame vec_frame;
- lv2_atom_forge_vector_head(
- forge, &vec_frame, sizeof(float), uris->atom_Float);
-
- // Calculate how many peaks to send this update
- const uint32_t chunk_size = MAX(1u, sender->n_samples / sender->n_peaks);
- const uint32_t space = forge->size - forge->offset;
- const uint32_t remaining = sender->n_peaks - sender->current_offset;
- const uint32_t n_update = MIN(remaining,
- MIN(n_frames / 4u, space / sizeof(float)));
-
- // Calculate peak (maximum magnitude) for each chunk
- for (uint32_t i = 0; i < n_update; ++i) {
- const uint32_t start = (sender->current_offset + i) * chunk_size;
- float peak = 0.0f;
- for (uint32_t j = 0; j < chunk_size; ++j) {
- peak = fmaxf(peak, fabsf(sender->samples[start + j]));
- }
- lv2_atom_forge_float(forge, peak);
- }
-
- // Finish message
- lv2_atom_forge_pop(forge, &vec_frame);
- lv2_atom_forge_pop(forge, &frame);
-
- sender->current_offset += n_update;
- return true;
+ const PeaksURIs* uris = &sender->uris;
+ if (!sender->sending || sender->current_offset >= sender->n_peaks) {
+ return sender->sending = false;
+ }
+
+ // Start PeakUpdate object
+ lv2_atom_forge_frame_time(forge, offset);
+ LV2_Atom_Forge_Frame frame;
+ lv2_atom_forge_object(forge, &frame, 0, uris->peaks_PeakUpdate);
+
+ // eg:offset = OFFSET
+ lv2_atom_forge_key(forge, uris->peaks_offset);
+ lv2_atom_forge_int(forge, sender->current_offset);
+
+ // eg:total = TOTAL
+ lv2_atom_forge_key(forge, uris->peaks_total);
+ lv2_atom_forge_int(forge, sender->n_peaks);
+
+ // eg:magnitudes = Vector<Float>(PEAK, PEAK, ...)
+ lv2_atom_forge_key(forge, uris->peaks_magnitudes);
+ LV2_Atom_Forge_Frame vec_frame;
+ lv2_atom_forge_vector_head(
+ forge, &vec_frame, sizeof(float), uris->atom_Float);
+
+ // Calculate how many peaks to send this update
+ const uint32_t chunk_size = MAX(1u, sender->n_samples / sender->n_peaks);
+ const uint32_t space = forge->size - forge->offset;
+ const uint32_t remaining = sender->n_peaks - sender->current_offset;
+ const uint32_t n_update =
+ MIN(remaining, MIN(n_frames / 4u, space / sizeof(float)));
+
+ // Calculate peak (maximum magnitude) for each chunk
+ for (uint32_t i = 0; i < n_update; ++i) {
+ const uint32_t start = (sender->current_offset + i) * chunk_size;
+ float peak = 0.0f;
+ for (uint32_t j = 0; j < chunk_size; ++j) {
+ peak = fmaxf(peak, fabsf(sender->samples[start + j]));
+ }
+ lv2_atom_forge_float(forge, peak);
+ }
+
+ // Finish message
+ lv2_atom_forge_pop(forge, &vec_frame);
+ lv2_atom_forge_pop(forge, &frame);
+
+ sender->current_offset += n_update;
+ return true;
}
/**
@@ -197,9 +197,9 @@ peaks_sender_send(PeaksSender* sender,
static inline PeaksReceiver*
peaks_receiver_init(PeaksReceiver* receiver, LV2_URID_Map* map)
{
- memset(receiver, 0, sizeof(*receiver));
- peaks_map_uris(&receiver->uris, map);
- return receiver;
+ memset(receiver, 0, sizeof(*receiver));
+ peaks_map_uris(&receiver->uris, map);
+ return receiver;
}
/**
@@ -209,9 +209,9 @@ peaks_receiver_init(PeaksReceiver* receiver, LV2_URID_Map* map)
static inline void
peaks_receiver_clear(PeaksReceiver* receiver)
{
- free(receiver->peaks);
- receiver->peaks = NULL;
- receiver->n_peaks = 0;
+ free(receiver->peaks);
+ receiver->peaks = NULL;
+ receiver->n_peaks = 0;
}
/**
@@ -225,56 +225,56 @@ peaks_receiver_clear(PeaksReceiver* receiver)
static inline int
peaks_receiver_receive(PeaksReceiver* receiver, const LV2_Atom_Object* update)
{
- const PeaksURIs* uris = &receiver->uris;
-
- // Get properties of interest from update
- const LV2_Atom_Int* offset = NULL;
- const LV2_Atom_Int* total = NULL;
- const LV2_Atom_Vector* peaks = NULL;
-
- // clang-format off
- lv2_atom_object_get_typed(update,
- uris->peaks_offset, &offset, uris->atom_Int,
- uris->peaks_total, &total, uris->atom_Int,
- uris->peaks_magnitudes, &peaks, uris->atom_Vector,
- 0);
- // clang-format on
-
- if (!offset || !total || !peaks ||
- peaks->body.child_type != uris->atom_Float) {
- return -1; // Invalid update
- }
-
- const uint32_t n = (uint32_t)total->body;
- if (receiver->n_peaks != n) {
- // Update is for a different total number of peaks, resize
- receiver->peaks = (float*)realloc(receiver->peaks, n * sizeof(float));
- if (receiver->n_peaks > 0 && receiver->n_peaks < n) {
- /* The peaks array is being expanded. Copy the old peaks,
- duplicating each as necessary to fill the new peaks buffer.
- This preserves the current peaks so that the peaks array can be
- reasonably drawn at any time, but the resolution will increase
- as new updates arrive. */
- const int64_t n_per = n / receiver->n_peaks;
- for (int64_t i = n - 1; i >= 0; --i) {
- receiver->peaks[i] = receiver->peaks[i / n_per];
- }
- } else if (receiver->n_peaks > 0) {
- /* The peak array is being shrunk. Similar to the above. */
- const int64_t n_per = receiver->n_peaks / n;
- for (int64_t i = n - 1; i >= 0; --i) {
- receiver->peaks[i] = receiver->peaks[i * n_per];
- }
- }
- receiver->n_peaks = n;
- }
-
- // Copy vector contents to corresponding range in peaks array
- memcpy(receiver->peaks + offset->body,
- peaks + 1,
- peaks->atom.size - sizeof(LV2_Atom_Vector_Body));
-
- return 0;
+ const PeaksURIs* uris = &receiver->uris;
+
+ // Get properties of interest from update
+ const LV2_Atom_Int* offset = NULL;
+ const LV2_Atom_Int* total = NULL;
+ const LV2_Atom_Vector* peaks = NULL;
+
+ // clang-format off
+ lv2_atom_object_get_typed(update,
+ uris->peaks_offset, &offset, uris->atom_Int,
+ uris->peaks_total, &total, uris->atom_Int,
+ uris->peaks_magnitudes, &peaks, uris->atom_Vector,
+ 0);
+ // clang-format on
+
+ if (!offset || !total || !peaks ||
+ peaks->body.child_type != uris->atom_Float) {
+ return -1; // Invalid update
+ }
+
+ const uint32_t n = (uint32_t)total->body;
+ if (receiver->n_peaks != n) {
+ // Update is for a different total number of peaks, resize
+ receiver->peaks = (float*)realloc(receiver->peaks, n * sizeof(float));
+ if (receiver->n_peaks > 0 && receiver->n_peaks < n) {
+ /* The peaks array is being expanded. Copy the old peaks,
+ duplicating each as necessary to fill the new peaks buffer.
+ This preserves the current peaks so that the peaks array can be
+ reasonably drawn at any time, but the resolution will increase
+ as new updates arrive. */
+ const int64_t n_per = n / receiver->n_peaks;
+ for (int64_t i = n - 1; i >= 0; --i) {
+ receiver->peaks[i] = receiver->peaks[i / n_per];
+ }
+ } else if (receiver->n_peaks > 0) {
+ /* The peak array is being shrunk. Similar to the above. */
+ const int64_t n_per = receiver->n_peaks / n;
+ for (int64_t i = n - 1; i >= 0; --i) {
+ receiver->peaks[i] = receiver->peaks[i * n_per];
+ }
+ }
+ receiver->n_peaks = n;
+ }
+
+ // Copy vector contents to corresponding range in peaks array
+ memcpy(receiver->peaks + offset->body,
+ peaks + 1,
+ peaks->atom.size - sizeof(LV2_Atom_Vector_Body));
+
+ return 0;
}
#endif // PEAKS_H_INCLUDED
diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
index cd410d1..6c64df5 100644
--- a/plugins/eg-sampler.lv2/sampler.c
+++ b/plugins/eg-sampler.lv2/sampler.c
@@ -42,48 +42,44 @@
#include <stdlib.h>
#include <string.h>
-enum {
- SAMPLER_CONTROL = 0,
- SAMPLER_NOTIFY = 1,
- SAMPLER_OUT = 2
-};
+enum { SAMPLER_CONTROL = 0, SAMPLER_NOTIFY = 1, SAMPLER_OUT = 2 };
typedef struct {
- SF_INFO info; // Info about sample from sndfile
- float* data; // Sample data in float
- char* path; // Path of file
- uint32_t path_len; // Length of path
+ SF_INFO info; // Info about sample from sndfile
+ float* data; // Sample data in float
+ char* path; // Path of file
+ uint32_t path_len; // Length of path
} Sample;
typedef struct {
- // Features
- LV2_URID_Map* map;
- LV2_Worker_Schedule* schedule;
- LV2_Log_Logger logger;
-
- // Ports
- const LV2_Atom_Sequence* control_port;
- LV2_Atom_Sequence* notify_port;
- float* output_port;
-
- // Communication utilities
- LV2_Atom_Forge_Frame notify_frame; ///< Cached for worker replies
- LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread
- PeaksSender psend; ///< Audio peaks sender
-
- // URIs
- SamplerURIs uris;
-
- // Playback state
- Sample* sample;
- uint32_t frame_offset;
- float gain;
- float gain_dB;
- sf_count_t frame;
- bool play;
- bool activated;
- bool gain_changed;
- bool sample_changed;
+ // Features
+ LV2_URID_Map* map;
+ LV2_Worker_Schedule* schedule;
+ LV2_Log_Logger logger;
+
+ // Ports
+ const LV2_Atom_Sequence* control_port;
+ LV2_Atom_Sequence* notify_port;
+ float* output_port;
+
+ // Communication utilities
+ LV2_Atom_Forge_Frame notify_frame; ///< Cached for worker replies
+ LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread
+ PeaksSender psend; ///< Audio peaks sender
+
+ // URIs
+ SamplerURIs uris;
+
+ // Playback state
+ Sample* sample;
+ uint32_t frame_offset;
+ float gain;
+ float gain_dB;
+ sf_count_t frame;
+ bool play;
+ bool activated;
+ bool gain_changed;
+ bool sample_changed;
} Sampler;
/**
@@ -95,8 +91,8 @@ typedef struct {
ringbuffer.
*/
typedef struct {
- LV2_Atom atom;
- Sample* sample;
+ LV2_Atom atom;
+ Sample* sample;
} SampleMessage;
/**
@@ -109,53 +105,53 @@ typedef struct {
static Sample*
load_sample(LV2_Log_Logger* logger, const char* path)
{
- lv2_log_trace(logger, "Loading %s\n", path);
-
- const size_t path_len = strlen(path);
- Sample* const sample = (Sample*)calloc(1, sizeof(Sample));
- SF_INFO* const info = &sample->info;
- SNDFILE* const sndfile = sf_open(path, SFM_READ, info);
- float* data = NULL;
- bool error = true;
- if (!sndfile || !info->frames) {
- lv2_log_error(logger, "Failed to open %s\n", path);
- } else if (info->channels != 1) {
- lv2_log_error(logger, "%s has %d channels\n", path, info->channels);
- } else if (!(data = (float*)malloc(sizeof(float) * info->frames))) {
- lv2_log_error(logger, "Failed to allocate memory for sample\n");
- } else {
- error = false;
- }
-
- if (error) {
- free(sample);
- free(data);
- sf_close(sndfile);
- return NULL;
- }
-
- sf_seek(sndfile, 0ul, SEEK_SET);
- sf_read_float(sndfile, data, info->frames);
- sf_close(sndfile);
-
- // Fill sample struct and return it
- sample->data = data;
- sample->path = (char*)malloc(path_len + 1);
- sample->path_len = (uint32_t)path_len;
- memcpy(sample->path, path, path_len + 1);
-
- return sample;
+ lv2_log_trace(logger, "Loading %s\n", path);
+
+ const size_t path_len = strlen(path);
+ Sample* const sample = (Sample*)calloc(1, sizeof(Sample));
+ SF_INFO* const info = &sample->info;
+ SNDFILE* const sndfile = sf_open(path, SFM_READ, info);
+ float* data = NULL;
+ bool error = true;
+ if (!sndfile || !info->frames) {
+ lv2_log_error(logger, "Failed to open %s\n", path);
+ } else if (info->channels != 1) {
+ lv2_log_error(logger, "%s has %d channels\n", path, info->channels);
+ } else if (!(data = (float*)malloc(sizeof(float) * info->frames))) {
+ lv2_log_error(logger, "Failed to allocate memory for sample\n");
+ } else {
+ error = false;
+ }
+
+ if (error) {
+ free(sample);
+ free(data);
+ sf_close(sndfile);
+ return NULL;
+ }
+
+ sf_seek(sndfile, 0ul, SEEK_SET);
+ sf_read_float(sndfile, data, info->frames);
+ sf_close(sndfile);
+
+ // Fill sample struct and return it
+ sample->data = data;
+ sample->path = (char*)malloc(path_len + 1);
+ sample->path_len = (uint32_t)path_len;
+ memcpy(sample->path, path, path_len + 1);
+
+ return sample;
}
static void
free_sample(Sampler* self, Sample* sample)
{
- if (sample) {
- lv2_log_trace(&self->logger, "Freeing %s\n", sample->path);
- free(sample->path);
- free(sample->data);
- free(sample);
- }
+ if (sample) {
+ lv2_log_trace(&self->logger, "Freeing %s\n", sample->path);
+ free(sample->path);
+ free(sample->data);
+ free(sample);
+ }
}
/**
@@ -172,30 +168,30 @@ work(LV2_Handle instance,
uint32_t size,
const void* data)
{
- Sampler* self = (Sampler*)instance;
- const LV2_Atom* atom = (const LV2_Atom*)data;
- if (atom->type == self->uris.eg_freeSample) {
- // Free old sample
- const SampleMessage* msg = (const SampleMessage*)data;
- free_sample(self, msg->sample);
- } else if (atom->type == self->forge.Object) {
- // Handle set message (load sample).
- const LV2_Atom_Object* obj = (const LV2_Atom_Object*)data;
- const char* path = read_set_file(&self->uris, obj);
- if (!path) {
- lv2_log_error(&self->logger, "Malformed set file request\n");
- return LV2_WORKER_ERR_UNKNOWN;
- }
-
- // Load sample.
- Sample* sample = load_sample(&self->logger, path);
- if (sample) {
- // Send new sample to run() to be applied
- respond(handle, sizeof(Sample*), &sample);
- }
- }
-
- return LV2_WORKER_SUCCESS;
+ Sampler* self = (Sampler*)instance;
+ const LV2_Atom* atom = (const LV2_Atom*)data;
+ if (atom->type == self->uris.eg_freeSample) {
+ // Free old sample
+ const SampleMessage* msg = (const SampleMessage*)data;
+ free_sample(self, msg->sample);
+ } else if (atom->type == self->forge.Object) {
+ // Handle set message (load sample).
+ const LV2_Atom_Object* obj = (const LV2_Atom_Object*)data;
+ const char* path = read_set_file(&self->uris, obj);
+ if (!path) {
+ lv2_log_error(&self->logger, "Malformed set file request\n");
+ return LV2_WORKER_ERR_UNKNOWN;
+ }
+
+ // Load sample.
+ Sample* sample = load_sample(&self->logger, path);
+ if (sample) {
+ // Send new sample to run() to be applied
+ respond(handle, sizeof(Sample*), &sample);
+ }
+ }
+
+ return LV2_WORKER_SUCCESS;
}
/**
@@ -206,50 +202,44 @@ work(LV2_Handle instance,
scheduled.
*/
static LV2_Worker_Status
-work_response(LV2_Handle instance,
- uint32_t size,
- const void* data)
+work_response(LV2_Handle instance, uint32_t size, const void* data)
{
- Sampler* self = (Sampler*)instance;
- Sample* old_sample = self->sample;
- Sample* new_sample = *(Sample*const*)data;
+ Sampler* self = (Sampler*)instance;
+ Sample* old_sample = self->sample;
+ Sample* new_sample = *(Sample* const*)data;
- // Install the new sample
- self->sample = *(Sample*const*)data;
+ // Install the new sample
+ self->sample = *(Sample* const*)data;
- // Schedule work to free the old sample
- SampleMessage msg = { { sizeof(Sample*), self->uris.eg_freeSample },
- old_sample };
- self->schedule->schedule_work(self->schedule->handle, sizeof(msg), &msg);
+ // Schedule work to free the old sample
+ SampleMessage msg = {{sizeof(Sample*), self->uris.eg_freeSample}, old_sample};
+ self->schedule->schedule_work(self->schedule->handle, sizeof(msg), &msg);
- // Send a notification that we're using a new sample
- lv2_atom_forge_frame_time(&self->forge, self->frame_offset);
- write_set_file(&self->forge, &self->uris,
- new_sample->path,
- new_sample->path_len);
+ // Send a notification that we're using a new sample
+ lv2_atom_forge_frame_time(&self->forge, self->frame_offset);
+ write_set_file(
+ &self->forge, &self->uris, new_sample->path, new_sample->path_len);
- return LV2_WORKER_SUCCESS;
+ return LV2_WORKER_SUCCESS;
}
static void
-connect_port(LV2_Handle instance,
- uint32_t port,
- void* data)
+connect_port(LV2_Handle instance, uint32_t port, void* data)
{
- Sampler* self = (Sampler*)instance;
- switch (port) {
- case SAMPLER_CONTROL:
- self->control_port = (const LV2_Atom_Sequence*)data;
- break;
- case SAMPLER_NOTIFY:
- self->notify_port = (LV2_Atom_Sequence*)data;
- break;
- case SAMPLER_OUT:
- self->output_port = (float*)data;
- break;
- default:
- break;
- }
+ Sampler* self = (Sampler*)instance;
+ switch (port) {
+ case SAMPLER_CONTROL:
+ self->control_port = (const LV2_Atom_Sequence*)data;
+ break;
+ case SAMPLER_NOTIFY:
+ self->notify_port = (LV2_Atom_Sequence*)data;
+ break;
+ case SAMPLER_OUT:
+ self->output_port = (float*)data;
+ break;
+ default:
+ break;
+ }
}
static LV2_Handle
@@ -258,62 +248,62 @@ instantiate(const LV2_Descriptor* descriptor,
const char* path,
const LV2_Feature* const* features)
{
- // Allocate and initialise instance structure.
- Sampler* self = (Sampler*)calloc(1, sizeof(Sampler));
- if (!self) {
- return NULL;
- }
-
- // Get host features
- // clang-format off
- const char* missing = lv2_features_query(
- features,
- LV2_LOG__log, &self->logger.log, false,
- LV2_URID__map, &self->map, true,
- LV2_WORKER__schedule, &self->schedule, true,
- NULL);
- // clang-format on
-
- lv2_log_logger_set_map(&self->logger, self->map);
- if (missing) {
- lv2_log_error(&self->logger, "Missing feature <%s>\n", missing);
- free(self);
- return NULL;
- }
-
- // Map URIs and initialise forge
- map_sampler_uris(self->map, &self->uris);
- lv2_atom_forge_init(&self->forge, self->map);
- peaks_sender_init(&self->psend, self->map);
-
- self->gain = 1.0f;
- self->gain_dB = 0.0f;
-
- return (LV2_Handle)self;
+ // Allocate and initialise instance structure.
+ Sampler* self = (Sampler*)calloc(1, sizeof(Sampler));
+ if (!self) {
+ return NULL;
+ }
+
+ // Get host features
+ // clang-format off
+ const char* missing = lv2_features_query(
+ features,
+ LV2_LOG__log, &self->logger.log, false,
+ LV2_URID__map, &self->map, true,
+ LV2_WORKER__schedule, &self->schedule, true,
+ NULL);
+ // clang-format on
+
+ lv2_log_logger_set_map(&self->logger, self->map);
+ if (missing) {
+ lv2_log_error(&self->logger, "Missing feature <%s>\n", missing);
+ free(self);
+ return NULL;
+ }
+
+ // Map URIs and initialise forge
+ map_sampler_uris(self->map, &self->uris);
+ lv2_atom_forge_init(&self->forge, self->map);
+ peaks_sender_init(&self->psend, self->map);
+
+ self->gain = 1.0f;
+ self->gain_dB = 0.0f;
+
+ return (LV2_Handle)self;
}
static void
cleanup(LV2_Handle instance)
{
- Sampler* self = (Sampler*)instance;
- free_sample(self, self->sample);
- free(self);
+ Sampler* self = (Sampler*)instance;
+ free_sample(self, self->sample);
+ free(self);
}
static void
activate(LV2_Handle instance)
{
- ((Sampler*)instance)->activated = true;
+ ((Sampler*)instance)->activated = true;
}
static void
deactivate(LV2_Handle instance)
{
- ((Sampler*)instance)->activated = false;
+ ((Sampler*)instance)->activated = false;
}
/** 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)
+#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g)*0.05f) : 0.0f)
/**
Handle an incoming event in the audio thread.
@@ -324,88 +314,86 @@ deactivate(LV2_Handle instance)
static void
handle_event(Sampler* self, LV2_Atom_Event* ev)
{
- SamplerURIs* uris = &self->uris;
- PeaksURIs* peaks_uris = &self->psend.uris;
-
- if (ev->body.type == uris->midi_Event) {
- const uint8_t* const msg = (const uint8_t*)(ev + 1);
- switch (lv2_midi_message_type(msg)) {
- case LV2_MIDI_MSG_NOTE_ON:
- self->frame = 0;
- self->play = true;
- break;
- default:
- break;
- }
- } 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) {
- // Get the property and value of the set message
- const LV2_Atom* property = NULL;
- const LV2_Atom* value = NULL;
-
- // clang-format off
- lv2_atom_object_get(obj,
- uris->patch_property, &property,
- uris->patch_value, &value,
- 0);
- // clang-format on
-
- if (!property) {
- lv2_log_error(&self->logger, "Set message with no property\n");
- return;
- } else if (property->type != uris->atom_URID) {
- lv2_log_error(&self->logger, "Set property is not a URID\n");
- return;
- }
-
- 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, "Scheduling sample change\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 = ((LV2_Atom_Float*)value)->body;
- self->gain = DB_CO(self->gain_dB);
- }
- }
- } else if (obj->body.otype == uris->patch_Get && self->sample) {
- const LV2_Atom_URID* accept = NULL;
- const LV2_Atom_Int* n_peaks = NULL;
-
- // clang-format off
- lv2_atom_object_get_typed(
- obj,
- uris->patch_accept, &accept, uris->atom_URID,
- peaks_uris->peaks_total, &n_peaks, peaks_uris->atom_Int, 0);
- // clang-format on
-
- if (accept && accept->body == peaks_uris->peaks_PeakUpdate) {
- // Received a request for peaks, prepare for transmission
- peaks_sender_start(&self->psend,
- self->sample->data,
- self->sample->info.frames,
- n_peaks->body);
- } else {
- // Received a get message, emit our state (probably to UI)
- lv2_atom_forge_frame_time(&self->forge, self->frame_offset);
- write_set_file(&self->forge, &self->uris,
- self->sample->path,
- self->sample->path_len);
- }
- } else {
- lv2_log_trace(&self->logger,
- "Unknown object type %u\n", obj->body.otype);
- }
- } else {
- lv2_log_trace(&self->logger,
- "Unknown event type %u\n", ev->body.type);
- }
-
+ SamplerURIs* uris = &self->uris;
+ PeaksURIs* peaks_uris = &self->psend.uris;
+
+ if (ev->body.type == uris->midi_Event) {
+ const uint8_t* const msg = (const uint8_t*)(ev + 1);
+ switch (lv2_midi_message_type(msg)) {
+ case LV2_MIDI_MSG_NOTE_ON:
+ self->frame = 0;
+ self->play = true;
+ break;
+ default:
+ break;
+ }
+ } 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) {
+ // Get the property and value of the set message
+ const LV2_Atom* property = NULL;
+ const LV2_Atom* value = NULL;
+
+ // clang-format off
+ lv2_atom_object_get(obj,
+ uris->patch_property, &property,
+ uris->patch_value, &value,
+ 0);
+ // clang-format on
+
+ if (!property) {
+ lv2_log_error(&self->logger, "Set message with no property\n");
+ return;
+ } else if (property->type != uris->atom_URID) {
+ lv2_log_error(&self->logger, "Set property is not a URID\n");
+ return;
+ }
+
+ 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, "Scheduling sample change\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 = ((LV2_Atom_Float*)value)->body;
+ self->gain = DB_CO(self->gain_dB);
+ }
+ }
+ } else if (obj->body.otype == uris->patch_Get && self->sample) {
+ const LV2_Atom_URID* accept = NULL;
+ const LV2_Atom_Int* n_peaks = NULL;
+
+ // clang-format off
+ lv2_atom_object_get_typed(
+ obj,
+ uris->patch_accept, &accept, uris->atom_URID,
+ peaks_uris->peaks_total, &n_peaks, peaks_uris->atom_Int,
+ 0);
+ // clang-format on
+
+ if (accept && accept->body == peaks_uris->peaks_PeakUpdate) {
+ // Received a request for peaks, prepare for transmission
+ peaks_sender_start(&self->psend,
+ self->sample->data,
+ self->sample->info.frames,
+ n_peaks->body);
+ } else {
+ // Received a get message, emit our state (probably to UI)
+ lv2_atom_forge_frame_time(&self->forge, self->frame_offset);
+ write_set_file(&self->forge,
+ &self->uris,
+ self->sample->path,
+ self->sample->path_len);
+ }
+ } else {
+ lv2_log_trace(&self->logger, "Unknown object type %u\n", obj->body.otype);
+ }
+ } else {
+ lv2_log_trace(&self->logger, "Unknown event type %u\n", ev->body.type);
+ }
}
/**
@@ -414,78 +402,77 @@ handle_event(Sampler* self, LV2_Atom_Event* ev)
static void
render(Sampler* self, uint32_t start, uint32_t end)
{
- float* output = self->output_port;
-
- if (self->play && self->sample) {
- // Start/continue writing sample to output
- for (; start < end; ++start) {
- output[start] = self->sample->data[self->frame] * self->gain;
- if (++self->frame == self->sample->info.frames) {
- self->play = false; // Reached end of sample
- break;
- }
- }
- }
-
- // Write silence to remaining buffer
- for (; start < end; ++start) {
- output[start] = 0.0f;
- }
+ float* output = self->output_port;
+
+ if (self->play && self->sample) {
+ // Start/continue writing sample to output
+ for (; start < end; ++start) {
+ output[start] = self->sample->data[self->frame] * self->gain;
+ if (++self->frame == self->sample->info.frames) {
+ self->play = false; // Reached end of sample
+ break;
+ }
+ }
+ }
+
+ // Write silence to remaining buffer
+ for (; start < end; ++start) {
+ output[start] = 0.0f;
+ }
}
static void
run(LV2_Handle instance, uint32_t sample_count)
{
- Sampler* self = (Sampler*)instance;
-
- // Set up forge to write directly to notify output port.
- const uint32_t notify_capacity = self->notify_port->atom.size;
- lv2_atom_forge_set_buffer(&self->forge,
- (uint8_t*)self->notify_port,
- notify_capacity);
-
- // Start a sequence in the notify output port.
- lv2_atom_forge_sequence_head(&self->forge, &self->notify_frame, 0);
-
- // Send update to UI if gain or sample has changed due to state restore
- if (self->gain_changed || self->sample_changed) {
- lv2_atom_forge_frame_time(&self->forge, 0);
-
- if (self->gain_changed) {
- write_set_gain(&self->forge, &self->uris, self->gain_dB);
- self->gain_changed = false;
- }
-
- if (self->sample_changed) {
- write_set_file(&self->forge, &self->uris,
- self->sample->path,
- self->sample->path_len);
- self->sample_changed = false;
- }
- }
-
- // Iterate over incoming events, emitting audio along the way
- self->frame_offset = 0;
- LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev) {
- // Render output up to the time of this event
- render(self, self->frame_offset, ev->time.frames);
-
- /* Update current frame offset to this event's time. This is stored in
- the instance because it is used for sychronous worker event
- execution. This allows a sample load event to be executed with
- sample accuracy when running in a non-realtime context (such as
- exporting a session). */
- self->frame_offset = ev->time.frames;
-
- // Process this event
- handle_event(self, ev);
- }
-
- // Use available space after any emitted events to send peaks
- peaks_sender_send(&self->psend, &self->forge, sample_count, self->frame_offset);
-
- // Render output for the rest of the cycle past the last event
- render(self, self->frame_offset, sample_count);
+ Sampler* self = (Sampler*)instance;
+
+ // Set up forge to write directly to notify output port.
+ const uint32_t notify_capacity = self->notify_port->atom.size;
+ lv2_atom_forge_set_buffer(
+ &self->forge, (uint8_t*)self->notify_port, notify_capacity);
+
+ // Start a sequence in the notify output port.
+ lv2_atom_forge_sequence_head(&self->forge, &self->notify_frame, 0);
+
+ // Send update to UI if gain or sample has changed due to state restore
+ if (self->gain_changed || self->sample_changed) {
+ lv2_atom_forge_frame_time(&self->forge, 0);
+
+ if (self->gain_changed) {
+ write_set_gain(&self->forge, &self->uris, self->gain_dB);
+ self->gain_changed = false;
+ }
+
+ if (self->sample_changed) {
+ write_set_file(
+ &self->forge, &self->uris, self->sample->path, self->sample->path_len);
+ self->sample_changed = false;
+ }
+ }
+
+ // Iterate over incoming events, emitting audio along the way
+ self->frame_offset = 0;
+ LV2_ATOM_SEQUENCE_FOREACH (self->control_port, ev) {
+ // Render output up to the time of this event
+ render(self, self->frame_offset, ev->time.frames);
+
+ /* Update current frame offset to this event's time. This is stored in
+ the instance because it is used for sychronous worker event
+ execution. This allows a sample load event to be executed with
+ sample accuracy when running in a non-realtime context (such as
+ exporting a session). */
+ self->frame_offset = ev->time.frames;
+
+ // Process this event
+ handle_event(self, ev);
+ }
+
+ // Use available space after any emitted events to send peaks
+ peaks_sender_send(
+ &self->psend, &self->forge, sample_count, self->frame_offset);
+
+ // Render output for the rest of the cycle past the last event
+ render(self, self->frame_offset, sample_count);
}
static LV2_State_Status
@@ -495,39 +482,39 @@ save(LV2_Handle instance,
uint32_t flags,
const LV2_Feature* const* features)
{
- Sampler* self = (Sampler*)instance;
- if (!self->sample) {
- return LV2_STATE_SUCCESS;
- }
-
- LV2_State_Map_Path* map_path = (LV2_State_Map_Path*)lv2_features_data(
- features, LV2_STATE__mapPath);
- if (!map_path) {
- return LV2_STATE_ERR_NO_FEATURE;
- }
-
- // Map absolute sample path to an abstract state path
- char* apath = map_path->abstract_path(map_path->handle, self->sample->path);
-
- // Store eg:sample = abstract path
- store(handle,
- self->uris.eg_sample,
- apath,
- strlen(apath) + 1,
- self->uris.atom_Path,
- LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
-
- free(apath);
-
- // Store the gain value
- store(handle,
- self->uris.param_gain,
- &self->gain_dB,
- sizeof(self->gain_dB),
- self->uris.atom_Float,
- LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
-
- return LV2_STATE_SUCCESS;
+ Sampler* self = (Sampler*)instance;
+ if (!self->sample) {
+ return LV2_STATE_SUCCESS;
+ }
+
+ LV2_State_Map_Path* map_path =
+ (LV2_State_Map_Path*)lv2_features_data(features, LV2_STATE__mapPath);
+ if (!map_path) {
+ return LV2_STATE_ERR_NO_FEATURE;
+ }
+
+ // Map absolute sample path to an abstract state path
+ char* apath = map_path->abstract_path(map_path->handle, self->sample->path);
+
+ // Store eg:sample = abstract path
+ store(handle,
+ self->uris.eg_sample,
+ apath,
+ strlen(apath) + 1,
+ self->uris.atom_Path,
+ LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
+
+ free(apath);
+
+ // Store the gain value
+ store(handle,
+ self->uris.param_gain,
+ &self->gain_dB,
+ sizeof(self->gain_dB),
+ self->uris.atom_Float,
+ LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
+
+ return LV2_STATE_SUCCESS;
}
static LV2_State_Status
@@ -537,113 +524,112 @@ restore(LV2_Handle instance,
uint32_t flags,
const LV2_Feature* const* features)
{
- Sampler* self = (Sampler*)instance;
-
- // Get host features
- LV2_Worker_Schedule* schedule = NULL;
- LV2_State_Map_Path* paths = NULL;
-
- // clang-format off
- const char* missing = lv2_features_query(
- features,
- LV2_STATE__mapPath, &paths, true,
- LV2_WORKER__schedule, &schedule, false,
- NULL);
- // clang-format on
-
- if (missing) {
- lv2_log_error(&self->logger, "Missing feature <%s>\n", missing);
- return LV2_STATE_ERR_NO_FEATURE;
- }
-
- // Get eg:sample from state
- size_t size = 0;
- uint32_t type = 0;
- uint32_t valflags = 0;
- const void* value = retrieve(handle, self->uris.eg_sample,
- &size, &type, &valflags);
- if (!value) {
- lv2_log_error(&self->logger, "Missing eg:sample\n");
- return LV2_STATE_ERR_NO_PROPERTY;
- } else if (type != self->uris.atom_Path) {
- lv2_log_error(&self->logger, "Non-path eg:sample\n");
- return LV2_STATE_ERR_BAD_TYPE;
- }
-
- // Map abstract state path to absolute path
- const char* apath = (const char*)value;
- char* path = paths->absolute_path(paths->handle, apath);
-
- // Replace current sample with the new one
- if (!self->activated || !schedule) {
- // No scheduling available, load sample immediately
- lv2_log_trace(&self->logger, "Synchronous restore\n");
- Sample* sample = load_sample(&self->logger, path);
- if (sample) {
- free_sample(self, self->sample);
- self->sample = sample;
- self->sample_changed = true;
- }
- } else {
- // Schedule sample to be loaded by the provided worker
- lv2_log_trace(&self->logger, "Scheduling restore\n");
- LV2_Atom_Forge forge;
- LV2_Atom* buf = (LV2_Atom*)calloc(1, strlen(path) + 128);
- lv2_atom_forge_init(&forge, self->map);
- lv2_atom_forge_set_sink(&forge, atom_sink, atom_sink_deref, buf);
- write_set_file(&forge, &self->uris, path, strlen(path));
-
- const uint32_t msg_size = lv2_atom_pad_size(buf->size);
- schedule->schedule_work(self->schedule->handle, msg_size, buf + 1);
- free(buf);
- }
-
- free(path);
-
- // Get param:gain from state
- value = retrieve(handle, self->uris.param_gain, &size, &type, &valflags);
- if (!value) {
- // Not an error, since older versions did not save this property
- lv2_log_note(&self->logger, "Missing param:gain\n");
- return LV2_STATE_SUCCESS;
- } else if (type != self->uris.atom_Float) {
- lv2_log_error(&self->logger, "Non-float param:gain\n");
- return LV2_STATE_ERR_BAD_TYPE;
- }
-
- self->gain_dB = *(const float*)value;
- self->gain = DB_CO(self->gain_dB);
- self->gain_changed = true;
-
- return LV2_STATE_SUCCESS;
+ Sampler* self = (Sampler*)instance;
+
+ // Get host features
+ LV2_Worker_Schedule* schedule = NULL;
+ LV2_State_Map_Path* paths = NULL;
+
+ // clang-format off
+ const char* missing = lv2_features_query(
+ features,
+ LV2_STATE__mapPath, &paths, true,
+ LV2_WORKER__schedule, &schedule, false,
+ NULL);
+ // clang-format on
+
+ if (missing) {
+ lv2_log_error(&self->logger, "Missing feature <%s>\n", missing);
+ return LV2_STATE_ERR_NO_FEATURE;
+ }
+
+ // Get eg:sample from state
+ size_t size = 0;
+ uint32_t type = 0;
+ uint32_t valflags = 0;
+ const void* value =
+ retrieve(handle, self->uris.eg_sample, &size, &type, &valflags);
+ if (!value) {
+ lv2_log_error(&self->logger, "Missing eg:sample\n");
+ return LV2_STATE_ERR_NO_PROPERTY;
+ } else if (type != self->uris.atom_Path) {
+ lv2_log_error(&self->logger, "Non-path eg:sample\n");
+ return LV2_STATE_ERR_BAD_TYPE;
+ }
+
+ // Map abstract state path to absolute path
+ const char* apath = (const char*)value;
+ char* path = paths->absolute_path(paths->handle, apath);
+
+ // Replace current sample with the new one
+ if (!self->activated || !schedule) {
+ // No scheduling available, load sample immediately
+ lv2_log_trace(&self->logger, "Synchronous restore\n");
+ Sample* sample = load_sample(&self->logger, path);
+ if (sample) {
+ free_sample(self, self->sample);
+ self->sample = sample;
+ self->sample_changed = true;
+ }
+ } else {
+ // Schedule sample to be loaded by the provided worker
+ lv2_log_trace(&self->logger, "Scheduling restore\n");
+ LV2_Atom_Forge forge;
+ LV2_Atom* buf = (LV2_Atom*)calloc(1, strlen(path) + 128);
+ lv2_atom_forge_init(&forge, self->map);
+ lv2_atom_forge_set_sink(&forge, atom_sink, atom_sink_deref, buf);
+ write_set_file(&forge, &self->uris, path, strlen(path));
+
+ const uint32_t msg_size = lv2_atom_pad_size(buf->size);
+ schedule->schedule_work(self->schedule->handle, msg_size, buf + 1);
+ free(buf);
+ }
+
+ free(path);
+
+ // Get param:gain from state
+ value = retrieve(handle, self->uris.param_gain, &size, &type, &valflags);
+ if (!value) {
+ // Not an error, since older versions did not save this property
+ lv2_log_note(&self->logger, "Missing param:gain\n");
+ return LV2_STATE_SUCCESS;
+ } else if (type != self->uris.atom_Float) {
+ lv2_log_error(&self->logger, "Non-float param:gain\n");
+ return LV2_STATE_ERR_BAD_TYPE;
+ }
+
+ self->gain_dB = *(const float*)value;
+ self->gain = DB_CO(self->gain_dB);
+ self->gain_changed = true;
+
+ return LV2_STATE_SUCCESS;
}
static const void*
extension_data(const char* uri)
{
- static const LV2_State_Interface state = { save, restore };
- static const LV2_Worker_Interface worker = { work, work_response, NULL };
- if (!strcmp(uri, LV2_STATE__interface)) {
- return &state;
- } else if (!strcmp(uri, LV2_WORKER__interface)) {
- return &worker;
- }
- return NULL;
+ static const LV2_State_Interface state = {save, restore};
+ static const LV2_Worker_Interface worker = {work, work_response, NULL};
+ if (!strcmp(uri, LV2_STATE__interface)) {
+ return &state;
+ } else if (!strcmp(uri, LV2_WORKER__interface)) {
+ return &worker;
+ }
+ return NULL;
}
-static const LV2_Descriptor descriptor = {
- EG_SAMPLER_URI,
- instantiate,
- connect_port,
- activate,
- run,
- deactivate,
- cleanup,
- extension_data
-};
+static const LV2_Descriptor descriptor = {EG_SAMPLER_URI,
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ extension_data};
LV2_SYMBOL_EXPORT
-const LV2_Descriptor* lv2_descriptor(uint32_t index)
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
{
- return index == 0 ? &descriptor : NULL;
+ return index == 0 ? &descriptor : NULL;
}
diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c
index f733216..533e720 100644
--- a/plugins/eg-sampler.lv2/sampler_ui.c
+++ b/plugins/eg-sampler.lv2/sampler_ui.c
@@ -48,195 +48,198 @@
#define MIN_CANVAS_H 80
typedef struct {
- LV2_Atom_Forge forge;
- LV2_URID_Map* map;
- LV2UI_Request_Value* request_value;
- LV2_Log_Logger logger;
- SamplerURIs uris;
- PeaksReceiver precv;
-
- LV2UI_Write_Function write;
- LV2UI_Controller controller;
-
- GtkWidget* box;
- GtkWidget* play_button;
- GtkWidget* file_button;
- GtkWidget* request_file_button;
- GtkWidget* button_box;
- GtkWidget* canvas;
-
- uint32_t width;
- uint32_t requested_n_peaks;
- char* filename;
-
- uint8_t forge_buf[1024];
-
- // Optional show/hide interface
- GtkWidget* window;
- bool did_init;
+ LV2_Atom_Forge forge;
+ LV2_URID_Map* map;
+ LV2UI_Request_Value* request_value;
+ LV2_Log_Logger logger;
+ SamplerURIs uris;
+ PeaksReceiver precv;
+
+ LV2UI_Write_Function write;
+ LV2UI_Controller controller;
+
+ GtkWidget* box;
+ GtkWidget* play_button;
+ GtkWidget* file_button;
+ GtkWidget* request_file_button;
+ GtkWidget* button_box;
+ GtkWidget* canvas;
+
+ uint32_t width;
+ uint32_t requested_n_peaks;
+ char* filename;
+
+ uint8_t forge_buf[1024];
+
+ // Optional show/hide interface
+ GtkWidget* window;
+ bool did_init;
} SamplerUI;
static void
on_file_set(GtkFileChooserButton* widget, void* handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
+ SamplerUI* ui = (SamplerUI*)handle;
- // Get the filename from the file chooser
- char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
+ // Get the filename from the file chooser
+ char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
- // Write a set message to the plugin to load new file
- lv2_atom_forge_set_buffer(&ui->forge, ui->forge_buf, sizeof(ui->forge_buf));
- LV2_Atom* msg = (LV2_Atom*)write_set_file(&ui->forge, &ui->uris,
- filename, strlen(filename));
+ // Write a set message to the plugin to load new file
+ lv2_atom_forge_set_buffer(&ui->forge, ui->forge_buf, sizeof(ui->forge_buf));
+ LV2_Atom* msg = (LV2_Atom*)write_set_file(
+ &ui->forge, &ui->uris, filename, strlen(filename));
- assert(msg);
+ assert(msg);
- ui->write(ui->controller, 0, lv2_atom_total_size(msg),
- ui->uris.atom_eventTransfer,
- msg);
+ ui->write(ui->controller,
+ 0,
+ lv2_atom_total_size(msg),
+ ui->uris.atom_eventTransfer,
+ msg);
- g_free(filename);
+ g_free(filename);
}
static void
on_request_file(GtkButton* widget, void* handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
+ SamplerUI* ui = (SamplerUI*)handle;
- ui->request_value->request(ui->request_value->handle,
- ui->uris.eg_sample,
- 0,
- NULL);
+ ui->request_value->request(
+ ui->request_value->handle, ui->uris.eg_sample, 0, NULL);
}
static void
on_play_clicked(GtkFileChooserButton* widget, void* handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
- struct {
- LV2_Atom atom;
- uint8_t msg[3];
- } note_on;
-
- note_on.atom.type = ui->uris.midi_Event;
- note_on.atom.size = 3;
- note_on.msg[0] = LV2_MIDI_MSG_NOTE_ON;
- note_on.msg[1] = 60;
- note_on.msg[2] = 60;
- ui->write(ui->controller, 0, sizeof(LV2_Atom) + 3,
- ui->uris.atom_eventTransfer,
- &note_on);
+ SamplerUI* ui = (SamplerUI*)handle;
+ struct {
+ LV2_Atom atom;
+ uint8_t msg[3];
+ } note_on;
+
+ note_on.atom.type = ui->uris.midi_Event;
+ note_on.atom.size = 3;
+ note_on.msg[0] = LV2_MIDI_MSG_NOTE_ON;
+ note_on.msg[1] = 60;
+ note_on.msg[2] = 60;
+ ui->write(ui->controller,
+ 0,
+ sizeof(LV2_Atom) + 3,
+ ui->uris.atom_eventTransfer,
+ &note_on);
}
static void
request_peaks(SamplerUI* ui, uint32_t n_peaks)
{
- if (n_peaks == ui->requested_n_peaks) {
- return;
- }
-
- lv2_atom_forge_set_buffer(&ui->forge, ui->forge_buf, sizeof(ui->forge_buf));
-
- LV2_Atom_Forge_Frame frame;
- lv2_atom_forge_object(&ui->forge, &frame, 0, ui->uris.patch_Get);
- lv2_atom_forge_key(&ui->forge, ui->uris.patch_accept);
- lv2_atom_forge_urid(&ui->forge, ui->precv.uris.peaks_PeakUpdate);
- lv2_atom_forge_key(&ui->forge, ui->precv.uris.peaks_total);
- lv2_atom_forge_int(&ui->forge, n_peaks);
- lv2_atom_forge_pop(&ui->forge, &frame);
-
- LV2_Atom* msg = lv2_atom_forge_deref(&ui->forge, frame.ref);
- ui->write(ui->controller, 0, lv2_atom_total_size(msg),
- ui->uris.atom_eventTransfer,
- msg);
-
- ui->requested_n_peaks = n_peaks;
+ if (n_peaks == ui->requested_n_peaks) {
+ return;
+ }
+
+ lv2_atom_forge_set_buffer(&ui->forge, ui->forge_buf, sizeof(ui->forge_buf));
+
+ LV2_Atom_Forge_Frame frame;
+ lv2_atom_forge_object(&ui->forge, &frame, 0, ui->uris.patch_Get);
+ lv2_atom_forge_key(&ui->forge, ui->uris.patch_accept);
+ lv2_atom_forge_urid(&ui->forge, ui->precv.uris.peaks_PeakUpdate);
+ lv2_atom_forge_key(&ui->forge, ui->precv.uris.peaks_total);
+ lv2_atom_forge_int(&ui->forge, n_peaks);
+ lv2_atom_forge_pop(&ui->forge, &frame);
+
+ LV2_Atom* msg = lv2_atom_forge_deref(&ui->forge, frame.ref);
+ ui->write(ui->controller,
+ 0,
+ lv2_atom_total_size(msg),
+ ui->uris.atom_eventTransfer,
+ msg);
+
+ ui->requested_n_peaks = n_peaks;
}
/** Set Cairo color to a GDK color (to follow Gtk theme). */
static void
cairo_set_source_gdk(cairo_t* cr, const GdkColor* color)
{
- cairo_set_source_rgb(
- cr, color->red / 65535.0, color->green / 65535.0, color->blue / 65535.0);
-
+ cairo_set_source_rgb(
+ cr, color->red / 65535.0, color->green / 65535.0, color->blue / 65535.0);
}
static gboolean
on_canvas_expose(GtkWidget* widget, GdkEventExpose* event, gpointer data)
{
- SamplerUI* ui = (SamplerUI*)data;
+ SamplerUI* ui = (SamplerUI*)data;
- GtkAllocation size;
- gtk_widget_get_allocation(widget, &size);
+ GtkAllocation size;
+ gtk_widget_get_allocation(widget, &size);
- ui->width = size.width;
- if (ui->width > 2 * ui->requested_n_peaks) {
- request_peaks(ui, 2 * ui->requested_n_peaks);
- }
+ ui->width = size.width;
+ if (ui->width > 2 * ui->requested_n_peaks) {
+ request_peaks(ui, 2 * ui->requested_n_peaks);
+ }
- cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget));
+ cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget));
- cairo_set_line_width(cr, 1.0);
- cairo_translate(cr, 0.5, 0.5);
+ cairo_set_line_width(cr, 1.0);
+ cairo_translate(cr, 0.5, 0.5);
- const double mid_y = size.height / 2.0;
+ const double mid_y = size.height / 2.0;
- const float* const peaks = ui->precv.peaks;
- const int32_t n_peaks = ui->precv.n_peaks;
- if (peaks) {
- // Draw waveform
- const double scale = size.width / ((double)n_peaks - 1.0f);
+ const float* const peaks = ui->precv.peaks;
+ const int32_t n_peaks = ui->precv.n_peaks;
+ if (peaks) {
+ // Draw waveform
+ const double scale = size.width / ((double)n_peaks - 1.0f);
- // Start at left origin
- cairo_move_to(cr, 0, mid_y);
+ // Start at left origin
+ cairo_move_to(cr, 0, mid_y);
- // Draw line through top peaks
- for (int i = 0; i < n_peaks; ++i) {
- const float peak = peaks[i];
- cairo_line_to(cr, i * scale, mid_y + (peak / 2.0f) * size.height);
- }
+ // Draw line through top peaks
+ for (int i = 0; i < n_peaks; ++i) {
+ const float peak = peaks[i];
+ cairo_line_to(cr, i * scale, mid_y + (peak / 2.0f) * size.height);
+ }
- // Continue through bottom peaks
- for (int i = n_peaks - 1; i >= 0; --i) {
- const float peak = peaks[i];
- cairo_line_to(cr, i * scale, mid_y - (peak / 2.0f) * size.height);
- }
+ // Continue through bottom peaks
+ for (int i = n_peaks - 1; i >= 0; --i) {
+ const float peak = peaks[i];
+ cairo_line_to(cr, i * scale, mid_y - (peak / 2.0f) * size.height);
+ }
- // Close shape
- cairo_line_to(cr, 0, mid_y);
+ // Close shape
+ cairo_line_to(cr, 0, mid_y);
- cairo_set_source_gdk(cr, widget->style->mid);
- cairo_fill_preserve(cr);
+ cairo_set_source_gdk(cr, widget->style->mid);
+ cairo_fill_preserve(cr);
- cairo_set_source_gdk(cr, widget->style->fg);
- cairo_stroke(cr);
- }
+ cairo_set_source_gdk(cr, widget->style->fg);
+ cairo_stroke(cr);
+ }
- cairo_destroy(cr);
- return TRUE;
+ cairo_destroy(cr);
+ return TRUE;
}
static void
destroy_window(SamplerUI* ui)
{
- if (ui->window) {
- gtk_container_remove(GTK_CONTAINER(ui->window), ui->box);
- gtk_widget_destroy(ui->window);
- ui->window = NULL;
- }
+ if (ui->window) {
+ gtk_container_remove(GTK_CONTAINER(ui->window), ui->box);
+ gtk_widget_destroy(ui->window);
+ ui->window = NULL;
+ }
}
static gboolean
on_window_closed(GtkWidget* widget, GdkEvent* event, gpointer data)
{
- SamplerUI* ui = (SamplerUI*)data;
+ SamplerUI* ui = (SamplerUI*)data;
- // Remove widget so Gtk doesn't delete it when the window is closed
- gtk_container_remove(GTK_CONTAINER(ui->window), ui->box);
- ui->window = NULL;
+ // Remove widget so Gtk doesn't delete it when the window is closed
+ gtk_container_remove(GTK_CONTAINER(ui->window), ui->box);
+ ui->window = NULL;
- return FALSE;
+ return FALSE;
}
static LV2UI_Handle
@@ -248,103 +251,104 @@ instantiate(const LV2UI_Descriptor* descriptor,
LV2UI_Widget* widget,
const LV2_Feature* const* features)
{
- SamplerUI* ui = (SamplerUI*)calloc(1, sizeof(SamplerUI));
- if (!ui) {
- return NULL;
- }
-
- ui->write = write_function;
- ui->controller = controller;
- ui->width = MIN_CANVAS_W;
- *widget = NULL;
- ui->window = NULL;
- ui->did_init = false;
-
- // Get host features
- // clang-format off
- const char* missing = lv2_features_query(
- features,
- LV2_LOG__log, &ui->logger.log , false,
- LV2_URID__map, &ui->map, true,
- LV2_UI__requestValue, &ui->request_value, false,
- NULL);
- // clang-format on
-
- lv2_log_logger_set_map(&ui->logger, ui->map);
- if (missing) {
- lv2_log_error(&ui->logger, "Missing feature <%s>\n", missing);
- free(ui);
- return NULL;
- }
-
- // Map URIs and initialise forge
- map_sampler_uris(ui->map, &ui->uris);
- lv2_atom_forge_init(&ui->forge, ui->map);
- peaks_receiver_init(&ui->precv, ui->map);
-
- // Construct Gtk UI
- ui->box = gtk_vbox_new(FALSE, 4);
- ui->play_button = gtk_button_new_with_label("▶");
- ui->canvas = gtk_drawing_area_new();
- ui->button_box = gtk_hbox_new(FALSE, 4);
- ui->file_button = gtk_file_chooser_button_new(
- "Load Sample", GTK_FILE_CHOOSER_ACTION_OPEN);
- ui->request_file_button = gtk_button_new_with_label("Request Sample");
- gtk_widget_set_size_request(ui->canvas, MIN_CANVAS_W, MIN_CANVAS_H);
- gtk_container_set_border_width(GTK_CONTAINER(ui->box), 4);
- gtk_box_pack_start(GTK_BOX(ui->box), ui->canvas, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(ui->box), ui->button_box, FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(ui->button_box), ui->play_button, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(ui->button_box), ui->request_file_button, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(ui->button_box), ui->file_button, TRUE, TRUE, 0);
-
- g_signal_connect(ui->file_button, "file-set",
- G_CALLBACK(on_file_set), ui);
-
- g_signal_connect(ui->request_file_button, "clicked",
- G_CALLBACK(on_request_file), ui);
-
- g_signal_connect(ui->play_button, "clicked",
- G_CALLBACK(on_play_clicked), ui);
-
- g_signal_connect(G_OBJECT(ui->canvas), "expose_event",
- G_CALLBACK(on_canvas_expose), ui);
-
- // Request state (filename) from plugin
- lv2_atom_forge_set_buffer(&ui->forge, ui->forge_buf, sizeof(ui->forge_buf));
- LV2_Atom_Forge_Frame frame;
- LV2_Atom* msg = (LV2_Atom*)lv2_atom_forge_object(
- &ui->forge, &frame, 0, ui->uris.patch_Get);
-
- assert(msg);
-
- lv2_atom_forge_pop(&ui->forge, &frame);
-
- ui->write(ui->controller, 0, lv2_atom_total_size(msg),
- ui->uris.atom_eventTransfer,
- msg);
-
- *widget = ui->box;
-
- return ui;
+ SamplerUI* ui = (SamplerUI*)calloc(1, sizeof(SamplerUI));
+ if (!ui) {
+ return NULL;
+ }
+
+ ui->write = write_function;
+ ui->controller = controller;
+ ui->width = MIN_CANVAS_W;
+ *widget = NULL;
+ ui->window = NULL;
+ ui->did_init = false;
+
+ // Get host features
+ // clang-format off
+ const char* missing = lv2_features_query(
+ features,
+ LV2_LOG__log, &ui->logger.log, false,
+ LV2_URID__map, &ui->map, true,
+ LV2_UI__requestValue, &ui->request_value, false,
+ NULL);
+ // clang-format on
+
+ lv2_log_logger_set_map(&ui->logger, ui->map);
+ if (missing) {
+ lv2_log_error(&ui->logger, "Missing feature <%s>\n", missing);
+ free(ui);
+ return NULL;
+ }
+
+ // Map URIs and initialise forge
+ map_sampler_uris(ui->map, &ui->uris);
+ lv2_atom_forge_init(&ui->forge, ui->map);
+ peaks_receiver_init(&ui->precv, ui->map);
+
+ // Construct Gtk UI
+ ui->box = gtk_vbox_new(FALSE, 4);
+ ui->play_button = gtk_button_new_with_label("▶");
+ ui->canvas = gtk_drawing_area_new();
+ ui->button_box = gtk_hbox_new(FALSE, 4);
+ ui->file_button =
+ gtk_file_chooser_button_new("Load Sample", GTK_FILE_CHOOSER_ACTION_OPEN);
+ ui->request_file_button = gtk_button_new_with_label("Request Sample");
+ gtk_widget_set_size_request(ui->canvas, MIN_CANVAS_W, MIN_CANVAS_H);
+ gtk_container_set_border_width(GTK_CONTAINER(ui->box), 4);
+ gtk_box_pack_start(GTK_BOX(ui->box), ui->canvas, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(ui->box), ui->button_box, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(ui->button_box), ui->play_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(
+ GTK_BOX(ui->button_box), ui->request_file_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ui->button_box), ui->file_button, TRUE, TRUE, 0);
+
+ g_signal_connect(ui->file_button, "file-set", G_CALLBACK(on_file_set), ui);
+
+ g_signal_connect(
+ ui->request_file_button, "clicked", G_CALLBACK(on_request_file), ui);
+
+ g_signal_connect(ui->play_button, "clicked", G_CALLBACK(on_play_clicked), ui);
+
+ g_signal_connect(
+ G_OBJECT(ui->canvas), "expose_event", G_CALLBACK(on_canvas_expose), ui);
+
+ // Request state (filename) from plugin
+ lv2_atom_forge_set_buffer(&ui->forge, ui->forge_buf, sizeof(ui->forge_buf));
+ LV2_Atom_Forge_Frame frame;
+ LV2_Atom* msg =
+ (LV2_Atom*)lv2_atom_forge_object(&ui->forge, &frame, 0, ui->uris.patch_Get);
+
+ assert(msg);
+
+ lv2_atom_forge_pop(&ui->forge, &frame);
+
+ ui->write(ui->controller,
+ 0,
+ lv2_atom_total_size(msg),
+ ui->uris.atom_eventTransfer,
+ msg);
+
+ *widget = ui->box;
+
+ return ui;
}
static void
cleanup(LV2UI_Handle handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
-
- if (ui->window) {
- destroy_window(ui);
- }
-
- gtk_widget_destroy(ui->canvas);
- gtk_widget_destroy(ui->play_button);
- gtk_widget_destroy(ui->file_button);
- gtk_widget_destroy(ui->request_file_button);
- gtk_widget_destroy(ui->button_box);
- gtk_widget_destroy(ui->box);
- free(ui);
+ SamplerUI* ui = (SamplerUI*)handle;
+
+ if (ui->window) {
+ destroy_window(ui);
+ }
+
+ gtk_widget_destroy(ui->canvas);
+ gtk_widget_destroy(ui->play_button);
+ gtk_widget_destroy(ui->file_button);
+ gtk_widget_destroy(ui->request_file_button);
+ gtk_widget_destroy(ui->button_box);
+ gtk_widget_destroy(ui->box);
+ free(ui);
}
static void
@@ -354,116 +358,112 @@ port_event(LV2UI_Handle handle,
uint32_t format,
const void* buffer)
{
- SamplerUI* ui = (SamplerUI*)handle;
- if (format == ui->uris.atom_eventTransfer) {
- const LV2_Atom* atom = (const LV2_Atom*)buffer;
- if (lv2_atom_forge_is_object_type(&ui->forge, atom->type)) {
- const LV2_Atom_Object* obj = (const LV2_Atom_Object*)atom;
- if (obj->body.otype == ui->uris.patch_Set) {
- const char* path = read_set_file(&ui->uris, obj);
- if (path && (!ui->filename || strcmp(path, ui->filename))) {
- g_free(ui->filename);
- ui->filename = g_strdup(path);
- gtk_file_chooser_set_filename(
- GTK_FILE_CHOOSER(ui->file_button), path);
- peaks_receiver_clear(&ui->precv);
- ui->requested_n_peaks = 0;
- request_peaks(ui, ui->width / 2 * 2);
- } else if (!path) {
- lv2_log_warning(&ui->logger, "Set message has no path\n");
- }
- } else if (obj->body.otype == ui->precv.uris.peaks_PeakUpdate) {
- if (!peaks_receiver_receive(&ui->precv, obj)) {
- gtk_widget_queue_draw(ui->canvas);
- }
- }
- } else {
- lv2_log_error(&ui->logger, "Unknown message type\n");
- }
- } else {
- lv2_log_warning(&ui->logger, "Unknown port event format\n");
- }
+ SamplerUI* ui = (SamplerUI*)handle;
+ if (format == ui->uris.atom_eventTransfer) {
+ const LV2_Atom* atom = (const LV2_Atom*)buffer;
+ if (lv2_atom_forge_is_object_type(&ui->forge, atom->type)) {
+ const LV2_Atom_Object* obj = (const LV2_Atom_Object*)atom;
+ if (obj->body.otype == ui->uris.patch_Set) {
+ const char* path = read_set_file(&ui->uris, obj);
+ if (path && (!ui->filename || strcmp(path, ui->filename))) {
+ g_free(ui->filename);
+ ui->filename = g_strdup(path);
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(ui->file_button),
+ path);
+ peaks_receiver_clear(&ui->precv);
+ ui->requested_n_peaks = 0;
+ request_peaks(ui, ui->width / 2 * 2);
+ } else if (!path) {
+ lv2_log_warning(&ui->logger, "Set message has no path\n");
+ }
+ } else if (obj->body.otype == ui->precv.uris.peaks_PeakUpdate) {
+ if (!peaks_receiver_receive(&ui->precv, obj)) {
+ gtk_widget_queue_draw(ui->canvas);
+ }
+ }
+ } else {
+ lv2_log_error(&ui->logger, "Unknown message type\n");
+ }
+ } else {
+ lv2_log_warning(&ui->logger, "Unknown port event format\n");
+ }
}
/* Optional non-embedded UI show interface. */
static int
ui_show(LV2UI_Handle handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
+ SamplerUI* ui = (SamplerUI*)handle;
- if (ui->window) {
- return 0;
- }
+ if (ui->window) {
+ return 0;
+ }
- if (!ui->did_init) {
- int argc = 0;
- gtk_init_check(&argc, NULL);
- g_object_ref(ui->box);
- ui->did_init = true;
- }
+ if (!ui->did_init) {
+ int argc = 0;
+ gtk_init_check(&argc, NULL);
+ g_object_ref(ui->box);
+ ui->did_init = true;
+ }
- ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_container_add(GTK_CONTAINER(ui->window), ui->box);
+ ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_container_add(GTK_CONTAINER(ui->window), ui->box);
- g_signal_connect(G_OBJECT(ui->window),
- "delete-event",
- G_CALLBACK(on_window_closed),
- handle);
+ g_signal_connect(
+ G_OBJECT(ui->window), "delete-event", G_CALLBACK(on_window_closed), handle);
- gtk_widget_show_all(ui->window);
- gtk_window_present(GTK_WINDOW(ui->window));
+ gtk_widget_show_all(ui->window);
+ gtk_window_present(GTK_WINDOW(ui->window));
- return 0;
+ return 0;
}
/* Optional non-embedded UI hide interface. */
static int
ui_hide(LV2UI_Handle handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
+ SamplerUI* ui = (SamplerUI*)handle;
- if (ui->window) {
- destroy_window(ui);
- }
+ if (ui->window) {
+ destroy_window(ui);
+ }
- return 0;
+ return 0;
}
/* Idle interface for optional non-embedded UI. */
static int
ui_idle(LV2UI_Handle handle)
{
- SamplerUI* ui = (SamplerUI*)handle;
- if (ui->window) {
- gtk_main_iteration_do(false);
- }
- return 0;
+ SamplerUI* ui = (SamplerUI*)handle;
+ if (ui->window) {
+ gtk_main_iteration_do(false);
+ }
+ return 0;
}
static const void*
extension_data(const char* uri)
{
- static const LV2UI_Show_Interface show = { ui_show, ui_hide };
- static const LV2UI_Idle_Interface idle = { ui_idle };
- if (!strcmp(uri, LV2_UI__showInterface)) {
- return &show;
- } else if (!strcmp(uri, LV2_UI__idleInterface)) {
- return &idle;
- }
- return NULL;
+ static const LV2UI_Show_Interface show = {ui_show, ui_hide};
+ static const LV2UI_Idle_Interface idle = {ui_idle};
+ if (!strcmp(uri, LV2_UI__showInterface)) {
+ return &show;
+ } else if (!strcmp(uri, LV2_UI__idleInterface)) {
+ return &idle;
+ }
+ return NULL;
}
-static const LV2UI_Descriptor descriptor = {
- SAMPLER_UI_URI,
- instantiate,
- cleanup,
- port_event,
- extension_data
-};
+static const LV2UI_Descriptor descriptor = {SAMPLER_UI_URI,
+ instantiate,
+ cleanup,
+ port_event,
+ extension_data};
LV2_SYMBOL_EXPORT
const LV2UI_Descriptor*
lv2ui_descriptor(uint32_t index)
{
- return index == 0 ? &descriptor : NULL;
+ return index == 0 ? &descriptor : NULL;
}
diff --git a/plugins/eg-sampler.lv2/uris.h b/plugins/eg-sampler.lv2/uris.h
index 8a0eb6f..d7201fa 100644
--- a/plugins/eg-sampler.lv2/uris.h
+++ b/plugins/eg-sampler.lv2/uris.h
@@ -29,49 +29,49 @@
#include <stdint.h>
#include <stdio.h>
-#define EG_SAMPLER_URI "http://lv2plug.in/plugins/eg-sampler"
+#define EG_SAMPLER_URI "http://lv2plug.in/plugins/eg-sampler"
#define EG_SAMPLER__applySample EG_SAMPLER_URI "#applySample"
-#define EG_SAMPLER__freeSample EG_SAMPLER_URI "#freeSample"
-#define EG_SAMPLER__sample EG_SAMPLER_URI "#sample"
+#define EG_SAMPLER__freeSample EG_SAMPLER_URI "#freeSample"
+#define EG_SAMPLER__sample EG_SAMPLER_URI "#sample"
typedef struct {
- LV2_URID atom_Float;
- LV2_URID atom_Path;
- LV2_URID atom_Resource;
- LV2_URID atom_Sequence;
- LV2_URID atom_URID;
- LV2_URID atom_eventTransfer;
- LV2_URID eg_applySample;
- LV2_URID eg_freeSample;
- LV2_URID eg_sample;
- LV2_URID midi_Event;
- LV2_URID param_gain;
- LV2_URID patch_Get;
- LV2_URID patch_Set;
- LV2_URID patch_accept;
- LV2_URID patch_property;
- LV2_URID patch_value;
+ LV2_URID atom_Float;
+ LV2_URID atom_Path;
+ LV2_URID atom_Resource;
+ LV2_URID atom_Sequence;
+ LV2_URID atom_URID;
+ LV2_URID atom_eventTransfer;
+ LV2_URID eg_applySample;
+ LV2_URID eg_freeSample;
+ LV2_URID eg_sample;
+ LV2_URID midi_Event;
+ LV2_URID param_gain;
+ LV2_URID patch_Get;
+ LV2_URID patch_Set;
+ LV2_URID patch_accept;
+ LV2_URID patch_property;
+ LV2_URID patch_value;
} SamplerURIs;
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);
- uris->atom_URID = map->map(map->handle, LV2_ATOM__URID);
- uris->atom_eventTransfer = map->map(map->handle, LV2_ATOM__eventTransfer);
- uris->eg_applySample = map->map(map->handle, EG_SAMPLER__applySample);
- 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_accept = map->map(map->handle, LV2_PATCH__accept);
- uris->patch_property = map->map(map->handle, LV2_PATCH__property);
- uris->patch_value = map->map(map->handle, LV2_PATCH__value);
+ 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);
+ uris->atom_URID = map->map(map->handle, LV2_ATOM__URID);
+ uris->atom_eventTransfer = map->map(map->handle, LV2_ATOM__eventTransfer);
+ uris->eg_applySample = map->map(map->handle, EG_SAMPLER__applySample);
+ 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_accept = map->map(map->handle, LV2_PATCH__accept);
+ uris->patch_property = map->map(map->handle, LV2_PATCH__property);
+ uris->patch_value = map->map(map->handle, LV2_PATCH__value);
}
/**
@@ -85,21 +85,19 @@ map_sampler_uris(LV2_URID_Map* map, SamplerURIs* uris)
----
*/
static inline LV2_Atom_Forge_Ref
-write_set_gain(LV2_Atom_Forge* forge,
- const SamplerURIs* uris,
- const float gain)
+write_set_gain(LV2_Atom_Forge* forge, const SamplerURIs* uris, const float gain)
{
- LV2_Atom_Forge_Frame frame;
- LV2_Atom_Forge_Ref set = lv2_atom_forge_object(
- forge, &frame, 0, uris->patch_Set);
+ LV2_Atom_Forge_Frame frame;
+ LV2_Atom_Forge_Ref set =
+ lv2_atom_forge_object(forge, &frame, 0, uris->patch_Set);
- lv2_atom_forge_key(forge, uris->patch_property);
- lv2_atom_forge_urid(forge, uris->param_gain);
- lv2_atom_forge_key(forge, uris->patch_value);
- lv2_atom_forge_float(forge, gain);
+ lv2_atom_forge_key(forge, uris->patch_property);
+ lv2_atom_forge_urid(forge, uris->param_gain);
+ lv2_atom_forge_key(forge, uris->patch_value);
+ lv2_atom_forge_float(forge, gain);
- lv2_atom_forge_pop(forge, &frame);
- return set;
+ lv2_atom_forge_pop(forge, &frame);
+ return set;
}
/**
@@ -118,17 +116,17 @@ write_set_file(LV2_Atom_Forge* forge,
const char* filename,
const uint32_t filename_len)
{
- LV2_Atom_Forge_Frame frame;
- LV2_Atom_Forge_Ref set = lv2_atom_forge_object(
- forge, &frame, 0, uris->patch_Set);
+ LV2_Atom_Forge_Frame frame;
+ LV2_Atom_Forge_Ref set =
+ lv2_atom_forge_object(forge, &frame, 0, uris->patch_Set);
- lv2_atom_forge_key(forge, uris->patch_property);
- lv2_atom_forge_urid(forge, uris->eg_sample);
- lv2_atom_forge_key(forge, uris->patch_value);
- lv2_atom_forge_path(forge, filename, filename_len);
+ lv2_atom_forge_key(forge, uris->patch_property);
+ lv2_atom_forge_urid(forge, uris->eg_sample);
+ lv2_atom_forge_key(forge, uris->patch_value);
+ lv2_atom_forge_path(forge, filename, filename_len);
- lv2_atom_forge_pop(forge, &frame);
- return set;
+ lv2_atom_forge_pop(forge, &frame);
+ return set;
}
/**
@@ -142,46 +140,45 @@ write_set_file(LV2_Atom_Forge* forge,
----
*/
static inline const char*
-read_set_file(const SamplerURIs* uris,
- const LV2_Atom_Object* obj)
+read_set_file(const SamplerURIs* uris, const LV2_Atom_Object* obj)
{
- if (obj->body.otype != uris->patch_Set) {
- fprintf(stderr, "Ignoring unknown message type %u\n", obj->body.otype);
- return NULL;
- }
-
- /* Get property URI. */
- const LV2_Atom* property = NULL;
- lv2_atom_object_get(obj, uris->patch_property, &property, 0);
- if (!property) {
- fprintf(stderr, "Malformed set message has no body.\n");
- return NULL;
- }
-
- if (property->type != uris->atom_URID) {
- fprintf(stderr, "Malformed set message has non-URID property.\n");
- return NULL;
- }
-
- if (((const LV2_Atom_URID*)property)->body != uris->eg_sample) {
- fprintf(stderr, "Set message for unknown property.\n");
- return NULL;
- }
-
- /* Get value. */
- const LV2_Atom* value = NULL;
- lv2_atom_object_get(obj, uris->patch_value, &value, 0);
- if (!value) {
- fprintf(stderr, "Malformed set message has no value.\n");
- return NULL;
- }
-
- if (value->type != uris->atom_Path) {
- fprintf(stderr, "Set message value is not a Path.\n");
- return NULL;
- }
-
- return (const char*)LV2_ATOM_BODY_CONST(value);
+ if (obj->body.otype != uris->patch_Set) {
+ fprintf(stderr, "Ignoring unknown message type %u\n", obj->body.otype);
+ return NULL;
+ }
+
+ /* Get property URI. */
+ const LV2_Atom* property = NULL;
+ lv2_atom_object_get(obj, uris->patch_property, &property, 0);
+ if (!property) {
+ fprintf(stderr, "Malformed set message has no body.\n");
+ return NULL;
+ }
+
+ if (property->type != uris->atom_URID) {
+ fprintf(stderr, "Malformed set message has non-URID property.\n");
+ return NULL;
+ }
+
+ if (((const LV2_Atom_URID*)property)->body != uris->eg_sample) {
+ fprintf(stderr, "Set message for unknown property.\n");
+ return NULL;
+ }
+
+ /* Get value. */
+ const LV2_Atom* value = NULL;
+ lv2_atom_object_get(obj, uris->patch_value, &value, 0);
+ if (!value) {
+ fprintf(stderr, "Malformed set message has no value.\n");
+ return NULL;
+ }
+
+ if (value->type != uris->atom_Path) {
+ fprintf(stderr, "Set message value is not a Path.\n");
+ return NULL;
+ }
+
+ return (const char*)LV2_ATOM_BODY_CONST(value);
}
-#endif /* SAMPLER_URIS_H */
+#endif /* SAMPLER_URIS_H */