From 2cca5c31f3233037483a6e7ba0fded7f458a4517 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Tue, 6 Apr 2021 00:22:25 +0200 Subject: [PATCH] Have distinct output port for notifying and automating --- plugins/lv2/sfizz.cpp | 79 +++++++++++++++++++--------------- plugins/lv2/sfizz.ttl.in | 43 ++++++++++-------- plugins/lv2/sfizz_lv2.h | 33 +++++++------- plugins/lv2/sfizz_lv2_plugin.h | 4 +- 4 files changed, 91 insertions(+), 68 deletions(-) diff --git a/plugins/lv2/sfizz.cpp b/plugins/lv2/sfizz.cpp index e5afaa05..ed335d0b 100644 --- a/plugins/lv2/sfizz.cpp +++ b/plugins/lv2/sfizz.cpp @@ -203,6 +203,9 @@ connect_port(LV2_Handle instance, case SFIZZ_NOTIFY: self->notify_port = (LV2_Atom_Sequence *)data; break; + case SFIZZ_AUTOMATE: + self->automate_port = (LV2_Atom_Sequence *)data; + break; case SFIZZ_LEFT: self->output_buffers[0] = (float *)data; break; @@ -322,11 +325,12 @@ sfizz_lv2_receive_message(void* data, int delay, const char* path, const char* s if (osc_size > OSC_TEMP_SIZE) return; + LV2_Atom_Forge* forge = &self->forge_notify; bool write_ok = - lv2_atom_forge_frame_time(&self->forge, 0) && - lv2_atom_forge_atom(&self->forge, osc_size, self->sfizz_osc_blob_uri) && - lv2_atom_forge_raw(&self->forge, osc_temp, osc_size); - lv2_atom_forge_pad(&self->forge, osc_size); + lv2_atom_forge_frame_time(forge, 0) && + lv2_atom_forge_atom(forge, osc_size, self->sfizz_osc_blob_uri) && + lv2_atom_forge_raw(forge, osc_temp, osc_size); + lv2_atom_forge_pad(forge, osc_size); (void)write_ok; } @@ -428,7 +432,8 @@ instantiate(const LV2_Descriptor *descriptor, sfizz_lv2_map_required_uris(self); // Initialize the forge - lv2_atom_forge_init(&self->forge, self->map); + lv2_atom_forge_init(&self->forge_notify, self->map); + lv2_atom_forge_init(&self->forge_automate, self->map); lv2_atom_forge_init(&self->forge_secondary, self->map); // Check the options for the block size and sample rate parameters @@ -530,38 +535,38 @@ deactivate(LV2_Handle instance) } static void -sfizz_lv2_send_file_path(sfizz_plugin_t *self, LV2_URID urid, const char *path) +sfizz_lv2_send_file_path(sfizz_plugin_t *self, LV2_Atom_Forge* forge, LV2_URID urid, const char *path) { LV2_Atom_Forge_Frame 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)); + lv2_atom_forge_frame_time(forge, 0) && + lv2_atom_forge_object(forge, &frame, 0, self->patch_set_uri) && + lv2_atom_forge_key(forge, self->patch_property_uri) && + lv2_atom_forge_urid(forge, urid) && + lv2_atom_forge_key(forge, self->patch_value_uri) && + lv2_atom_forge_path(forge, path, (uint32_t)strlen(path)); if (write_ok) - lv2_atom_forge_pop(&self->forge, &frame); + lv2_atom_forge_pop(forge, &frame); } static void -sfizz_lv2_send_controller(sfizz_plugin_t *self, unsigned cc, float value) +sfizz_lv2_send_controller(sfizz_plugin_t *self, LV2_Atom_Forge* forge, unsigned cc, float value) { LV2_URID urid = sfizz_lv2_ccmap_map(self->ccmap, int(cc)); LV2_Atom_Forge_Frame 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_float(&self->forge, value); + lv2_atom_forge_frame_time(forge, 0) && + lv2_atom_forge_object(forge, &frame, 0, self->patch_set_uri) && + lv2_atom_forge_key(forge, self->patch_property_uri) && + lv2_atom_forge_urid(forge, urid) && + lv2_atom_forge_key(forge, self->patch_value_uri) && + lv2_atom_forge_float(forge, value); if (write_ok) - lv2_atom_forge_pop(&self->forge, &frame); + lv2_atom_forge_pop(forge, &frame); } static void @@ -807,7 +812,7 @@ static void run(LV2_Handle instance, uint32_t sample_count) { sfizz_plugin_t *self = (sfizz_plugin_t *)instance; - assert(self->control_port && self->notify_port); + assert(self->control_port && self->notify_port && self->automate_port); if (!spin_mutex_trylock(self->synth_mutex)) { @@ -816,13 +821,18 @@ run(LV2_Handle instance, uint32_t sample_count) return; } - // Set up forge to write directly to notify output port. + // Set up dedicated forges to write on their respective ports. const size_t notify_capacity = self->notify_port->atom.size; - lv2_atom_forge_set_buffer(&self->forge, (uint8_t *)self->notify_port, notify_capacity); + lv2_atom_forge_set_buffer(&self->forge_notify, (uint8_t *)self->notify_port, notify_capacity); + const size_t automate_capacity = self->automate_port->atom.size; + lv2_atom_forge_set_buffer(&self->forge_automate, (uint8_t *)self->automate_port, automate_capacity); - // Start a sequence in the notify output port. + // Start sequences in the respective output ports. LV2_Atom_Forge_Frame notify_frame; - if (!lv2_atom_forge_sequence_head(&self->forge, ¬ify_frame, 0)) + if (!lv2_atom_forge_sequence_head(&self->forge_notify, ¬ify_frame, 0)) + assert(false); + LV2_Atom_Forge_Frame automate_frame; + if (!lv2_atom_forge_sequence_head(&self->forge_automate, &automate_frame, 0)) assert(false); LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev) @@ -844,25 +854,25 @@ run(LV2_Handle instance, uint32_t sample_count) lv2_atom_object_get(obj, self->patch_property_uri, &property, 0); if (!property) // Send the full state { - sfizz_lv2_send_file_path(self, self->sfizz_sfz_file_uri, self->sfz_file_path); - sfizz_lv2_send_file_path(self, self->sfizz_scala_file_uri, self->scala_file_path); + sfizz_lv2_send_file_path(self, &self->forge_notify, self->sfizz_sfz_file_uri, self->sfz_file_path); + sfizz_lv2_send_file_path(self, &self->forge_notify, self->sfizz_scala_file_uri, self->scala_file_path); for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) - sfizz_lv2_send_controller(self, cc, self->cc_current[cc]); + sfizz_lv2_send_controller(self, &self->forge_notify, cc, self->cc_current[cc]); } else if (property->body == self->sfizz_sfz_file_uri) { - sfizz_lv2_send_file_path(self, self->sfizz_sfz_file_uri, self->sfz_file_path); + sfizz_lv2_send_file_path(self, &self->forge_notify, self->sfizz_sfz_file_uri, self->sfz_file_path); } else if (property->body == self->sfizz_scala_file_uri) { - sfizz_lv2_send_file_path(self, self->sfizz_scala_file_uri, self->scala_file_path); + sfizz_lv2_send_file_path(self, &self->forge_notify, self->sfizz_scala_file_uri, self->scala_file_path); } else { int cc = sfizz_lv2_ccmap_unmap(self->ccmap, property->body); if (cc != -1) - sfizz_lv2_send_controller(self, unsigned(cc), self->cc_current[cc]); + sfizz_lv2_send_controller(self, &self->forge_notify, unsigned(cc), self->cc_current[cc]); } } else if (obj->body.otype == self->time_position_uri) @@ -1008,7 +1018,7 @@ run(LV2_Handle instance, uint32_t sample_count) for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) { absl::optional value = self->ccauto[cc]; if (value) { - sfizz_lv2_send_controller(self, cc, *value); + sfizz_lv2_send_controller(self, &self->forge_automate, cc, *value); self->ccauto[cc] = absl::nullopt; } } @@ -1017,7 +1027,8 @@ run(LV2_Handle instance, uint32_t sample_count) spin_mutex_unlock(self->synth_mutex); - lv2_atom_forge_pop(&self->forge, ¬ify_frame); + lv2_atom_forge_pop(&self->forge_notify, ¬ify_frame); + lv2_atom_forge_pop(&self->forge_automate, &automate_frame); } static uint32_t diff --git a/plugins/lv2/sfizz.ttl.in b/plugins/lv2/sfizz.ttl.in index 38e67814..112a970c 100644 --- a/plugins/lv2/sfizz.ttl.in +++ b/plugins/lv2/sfizz.ttl.in @@ -104,29 +104,38 @@ midnam:update a lv2:Feature . a lv2:OutputPort, atom:AtomPort ; atom:bufferType atom:Sequence ; atom:supports patch:Message, <@LV2PLUGIN_URI@:OSCBlob> ; - lv2:designation lv2:control ; lv2:index 1 ; lv2:symbol "notify" ; lv2:name "Notify", "Notification"@fr ; rsz:minimumSize 65536 ; ] , [ - a lv2:AudioPort, lv2:OutputPort ; + a lv2:OutputPort, atom:AtomPort ; + atom:bufferType atom:Sequence ; + atom:supports patch:Message ; + lv2:designation lv2:control ; lv2:index 2 ; + lv2:symbol "automate" ; + lv2:name "Automate", + "Automatisation"@fr ; + rsz:minimumSize 65536 ; + ] , [ + a lv2:AudioPort, lv2:OutputPort ; + lv2:index 3 ; lv2:symbol "out_left" ; lv2:name "Left Output", "Sortie gauche"@fr , "Uscita Sinistra"@it ] , [ a lv2:AudioPort, lv2:OutputPort ; - lv2:index 3 ; + lv2:index 4 ; lv2:symbol "out_right" ; lv2:name "Right Output", "Sortie droite"@fr , "Uscita Destra"@it ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 4 ; + lv2:index 5 ; lv2:symbol "volume" ; lv2:name "Volume" ; lv2:default 0.0 ; @@ -135,7 +144,7 @@ midnam:update a lv2:Feature . units:unit units:db ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 5 ; + lv2:index 6 ; lv2:symbol "num_voices" ; lv2:name "Polyphony", "Polyphonie"@fr , @@ -180,7 +189,7 @@ midnam:update a lv2:Feature . ] ; ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 6 ; + lv2:index 7 ; lv2:symbol "oversampling" ; lv2:name "Internal oversampling factor", "Facteur de suréchantillonnage interne"@fr , @@ -215,7 +224,7 @@ midnam:update a lv2:Feature . ] ; ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 7 ; + lv2:index 8 ; lv2:symbol "preload_size" ; lv2:name "Preload size", "Taille préchargée"@fr , @@ -258,7 +267,7 @@ midnam:update a lv2:Feature . ] ; ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 8 ; + lv2:index 9 ; lv2:symbol "freewheeling" ; lv2:name "Freewheeling", "En roue libre (freewheeling)"@fr , @@ -270,7 +279,7 @@ midnam:update a lv2:Feature . lv2:maximum 1 ; ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 9 ; + lv2:index 10 ; lv2:symbol "scala_root_key" ; lv2:name "Scala root key", "Tonalité de base Scala"@fr , @@ -283,7 +292,7 @@ midnam:update a lv2:Feature . units:unit units:midiNote ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 10 ; + lv2:index 11 ; lv2:symbol "tuning_frequency" ; lv2:name "Tuning frequency", "Fréquence d'accordage"@fr , @@ -295,7 +304,7 @@ midnam:update a lv2:Feature . units:unit units:hz ] , [ a lv2:InputPort, lv2:ControlPort ; - lv2:index 11 ; + lv2:index 12 ; lv2:symbol "stretched_tuning" ; lv2:name "Stretched tuning", "Accordage étiré"@fr , @@ -307,7 +316,7 @@ midnam:update a lv2:Feature . units:unit units:coef ] , [ a lv2:OutputPort, lv2:ControlPort ; - lv2:index 12 ; + lv2:index 13 ; lv2:symbol "active_voices" ; lv2:name "Active voices", "Voix utilisées"@fr ; @@ -318,7 +327,7 @@ midnam:update a lv2:Feature . lv2:maximum 256 ; ] , [ a lv2:OutputPort, lv2:ControlPort ; - lv2:index 13 ; + lv2:index 14 ; lv2:symbol "num_curves" ; lv2:name "Number of curves", "Nombre de courbes"@fr ; @@ -329,7 +338,7 @@ midnam:update a lv2:Feature . lv2:maximum 65535 ; ] , [ a lv2:OutputPort, lv2:ControlPort ; - lv2:index 14 ; + lv2:index 15 ; lv2:symbol "num_masters" ; lv2:name "Number of masters", "Nombre de maîtres"@fr ; @@ -340,7 +349,7 @@ midnam:update a lv2:Feature . lv2:maximum 65535 ; ] , [ a lv2:OutputPort, lv2:ControlPort ; - lv2:index 15 ; + lv2:index 16 ; lv2:symbol "num_groups" ; lv2:name "Number of groups", "Nombre de groupes"@fr ; @@ -351,7 +360,7 @@ midnam:update a lv2:Feature . lv2:maximum 65535 ; ] , [ a lv2:OutputPort, lv2:ControlPort ; - lv2:index 16 ; + lv2:index 17 ; lv2:symbol "num_regions" ; lv2:name "Number of regions", "Nombre de régions"@fr ; @@ -362,7 +371,7 @@ midnam:update a lv2:Feature . lv2:maximum 65535 ; ] , [ a lv2:OutputPort, lv2:ControlPort ; - lv2:index 17 ; + lv2:index 18 ; lv2:symbol "num_samples" ; lv2:name "Number of samples", "Nombre d'échantillons"@fr ; diff --git a/plugins/lv2/sfizz_lv2.h b/plugins/lv2/sfizz_lv2.h index 06c078a7..678f0c02 100644 --- a/plugins/lv2/sfizz_lv2.h +++ b/plugins/lv2/sfizz_lv2.h @@ -49,22 +49,23 @@ enum { SFIZZ_CONTROL = 0, SFIZZ_NOTIFY = 1, - SFIZZ_LEFT = 2, - SFIZZ_RIGHT = 3, - SFIZZ_VOLUME = 4, - SFIZZ_POLYPHONY = 5, - SFIZZ_OVERSAMPLING = 6, - SFIZZ_PRELOAD = 7, - SFIZZ_FREEWHEELING = 8, - SFIZZ_SCALA_ROOT_KEY = 9, - SFIZZ_TUNING_FREQUENCY = 10, - SFIZZ_STRETCH_TUNING = 11, - SFIZZ_ACTIVE_VOICES = 12, - SFIZZ_NUM_CURVES = 13, - SFIZZ_NUM_MASTERS = 14, - SFIZZ_NUM_GROUPS = 15, - SFIZZ_NUM_REGIONS = 16, - SFIZZ_NUM_SAMPLES = 17, + SFIZZ_AUTOMATE = 2, + SFIZZ_LEFT = 3, + SFIZZ_RIGHT = 4, + SFIZZ_VOLUME = 5, + SFIZZ_POLYPHONY = 6, + SFIZZ_OVERSAMPLING = 7, + SFIZZ_PRELOAD = 8, + SFIZZ_FREEWHEELING = 9, + SFIZZ_SCALA_ROOT_KEY = 10, + SFIZZ_TUNING_FREQUENCY = 11, + SFIZZ_STRETCH_TUNING = 12, + SFIZZ_ACTIVE_VOICES = 13, + SFIZZ_NUM_CURVES = 14, + SFIZZ_NUM_MASTERS = 15, + SFIZZ_NUM_GROUPS = 16, + SFIZZ_NUM_REGIONS = 17, + SFIZZ_NUM_SAMPLES = 18, }; // For use with instance-access diff --git a/plugins/lv2/sfizz_lv2_plugin.h b/plugins/lv2/sfizz_lv2_plugin.h index 5555d994..348e417d 100644 --- a/plugins/lv2/sfizz_lv2_plugin.h +++ b/plugins/lv2/sfizz_lv2_plugin.h @@ -32,6 +32,7 @@ struct sfizz_plugin_t // Ports const LV2_Atom_Sequence *control_port {}; LV2_Atom_Sequence *notify_port {}; + LV2_Atom_Sequence *automate_port {}; float *output_buffers[2] {}; const float *volume_port {}; const float *polyphony_port {}; @@ -49,7 +50,8 @@ struct sfizz_plugin_t float *num_samples_port {}; // Atom forge - LV2_Atom_Forge forge {}; ///< Forge for writing atoms in run thread + LV2_Atom_Forge forge_notify {}; ///< Forge for writing notification atoms in run thread + LV2_Atom_Forge forge_automate {}; ///< Forge for writing automation atoms in run thread LV2_Atom_Forge forge_secondary {}; ///< Forge for writing into other buffers // Logger