From ff34bb5ccb03df54032ae65a07d4c3bee64da75d Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 12 Jun 2020 17:53:15 +0200 Subject: [PATCH 1/3] Fix LV2 problems with the atom sequence - pop the frame when finished writing - add safety checks in case write space is short --- lv2/sfizz.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lv2/sfizz.c b/lv2/sfizz.c index 52815295..3aa123bd 100644 --- a/lv2/sfizz.c +++ b/lv2/sfizz.c @@ -445,13 +445,17 @@ static void sfizz_lv2_send_file_path(sfizz_plugin_t *self, LV2_URID urid, const char *path) { LV2_Atom_Forge_Frame frame; - lv2_atom_forge_frame_time(&self->forge, 0); - lv2_atom_forge_object(&self->forge, &frame, 0, self->patch_set_uri); - lv2_atom_forge_key(&self->forge, self->patch_property_uri); - lv2_atom_forge_urid(&self->forge, urid); - lv2_atom_forge_key(&self->forge, self->patch_value_uri); - lv2_atom_forge_path(&self->forge, path, (uint32_t)strlen(path)); - lv2_atom_forge_pop(&self->forge, &frame); + + bool write_ok = + lv2_atom_forge_frame_time(&self->forge, 0) && + lv2_atom_forge_object(&self->forge, &frame, 0, self->patch_set_uri) && + lv2_atom_forge_key(&self->forge, self->patch_property_uri) && + lv2_atom_forge_urid(&self->forge, urid) && + lv2_atom_forge_key(&self->forge, self->patch_value_uri) && + lv2_atom_forge_path(&self->forge, path, (uint32_t)strlen(path)); + + if (write_ok) + lv2_atom_forge_pop(&self->forge, &frame); } @@ -775,6 +779,8 @@ run(LV2_Handle instance, uint32_t sample_count) { self->midnam->update(self->midnam->handle); } + + lv2_atom_forge_pop(&self->forge, &self->notify_frame); } static uint32_t From f15ed45035bf2e1b719da7b2bb3f2ddfeb7f9ca1 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 12 Jun 2020 21:40:57 +0200 Subject: [PATCH 2/3] Construct work atoms using a forge --- lv2/sfizz.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/lv2/sfizz.c b/lv2/sfizz.c index 3aa123bd..e26dbd21 100644 --- a/lv2/sfizz.c +++ b/lv2/sfizz.c @@ -114,6 +114,9 @@ typedef struct LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread LV2_Atom_Forge_Frame notify_frame; ///< Cached for worker replies + // Atom forge + LV2_Atom_Forge forge_secondary; ///< Forge for writing into other buffers + // Logger LV2_Log_Logger logger; @@ -366,6 +369,7 @@ instantiate(const LV2_Descriptor *descriptor, // Initialize the forge lv2_atom_forge_init(&self->forge, self->map); + lv2_atom_forge_init(&self->forge_secondary, self->map); // Check the options for the block size and sample rate parameters if (options) @@ -491,28 +495,28 @@ sfizz_lv2_handle_atom_object(sfizz_plugin_t *self, const LV2_Atom_Object *obj) return; } + typedef struct + { + LV2_Atom atom; + char body[MAX_PATH_SIZE]; + } sfizz_path_atom_buffer_t; + if (key == self->sfizz_sfz_file_uri) { - const uint32_t original_atom_size = lv2_atom_total_size((const LV2_Atom *)atom); - const uint32_t null_terminated_atom_size = original_atom_size + 1; - char atom_buffer[MAX_PATH_SIZE]; - memcpy(&atom_buffer, atom, original_atom_size); - atom_buffer[original_atom_size] = 0; // Null terminate the string for safety - LV2_Atom *sfz_file_path = (LV2_Atom *)&atom_buffer; - sfz_file_path->type = self->sfizz_sfz_file_uri; - self->worker->schedule_work(self->worker->handle, null_terminated_atom_size, sfz_file_path); + LV2_Atom_Forge *forge = &self->forge_secondary; + sfizz_path_atom_buffer_t buffer; + lv2_atom_forge_set_buffer(forge, (uint8_t *)&buffer, sizeof(buffer)); + if (lv2_atom_forge_typed_string(forge, self->sfizz_sfz_file_uri, LV2_ATOM_BODY_CONST(atom), strnlen(LV2_ATOM_BODY_CONST(atom), atom->size))) + self->worker->schedule_work(self->worker->handle, lv2_atom_total_size(&buffer.atom), &buffer.atom); self->check_modification = false; } else if (key == self->sfizz_scala_file_uri) { - const uint32_t original_atom_size = lv2_atom_total_size((const LV2_Atom *)atom); - const uint32_t null_terminated_atom_size = original_atom_size + 1; - char atom_buffer[MAX_PATH_SIZE]; - memcpy(&atom_buffer, atom, original_atom_size); - atom_buffer[original_atom_size] = 0; // Null terminate the string for safety - LV2_Atom *scala_file_path = (LV2_Atom *)&atom_buffer; - scala_file_path->type = self->sfizz_scala_file_uri; - self->worker->schedule_work(self->worker->handle, null_terminated_atom_size, scala_file_path); + LV2_Atom_Forge *forge = &self->forge_secondary; + sfizz_path_atom_buffer_t buffer; + lv2_atom_forge_set_buffer(forge, (uint8_t *)&buffer, sizeof(buffer)); + if (lv2_atom_forge_typed_string(forge, self->sfizz_scala_file_uri, LV2_ATOM_BODY_CONST(atom), strnlen(LV2_ATOM_BODY_CONST(atom), atom->size))) + self->worker->schedule_work(self->worker->handle, lv2_atom_total_size(&buffer.atom), &buffer.atom); self->check_modification = false; } else From ba0716e7e190db4a6b1877a08a1fc3618e756e3b Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 12 Jun 2020 21:52:45 +0200 Subject: [PATCH 3/3] Make notify_frame local to run() --- lv2/sfizz.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lv2/sfizz.c b/lv2/sfizz.c index e26dbd21..54b3f99b 100644 --- a/lv2/sfizz.c +++ b/lv2/sfizz.c @@ -112,9 +112,6 @@ typedef struct // Atom forge LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread - LV2_Atom_Forge_Frame notify_frame; ///< Cached for worker replies - - // Atom forge LV2_Atom_Forge forge_secondary; ///< Forge for writing into other buffers // Logger @@ -692,7 +689,9 @@ run(LV2_Handle instance, uint32_t sample_count) 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); + LV2_Atom_Forge_Frame notify_frame; + if (!lv2_atom_forge_sequence_head(&self->forge, ¬ify_frame, 0)) + assert(false); LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev) { @@ -784,7 +783,7 @@ run(LV2_Handle instance, uint32_t sample_count) self->midnam->update(self->midnam->handle); } - lv2_atom_forge_pop(&self->forge, &self->notify_frame); + lv2_atom_forge_pop(&self->forge, ¬ify_frame); } static uint32_t