Add an output string parameter for the LV2 plugin

It contains the CC used for now
This commit is contained in:
Paul Fd 2022-01-05 11:03:29 +01:00
parent 3d50afc794
commit bfdd1eb065
4 changed files with 67 additions and 22 deletions

View file

@ -117,6 +117,7 @@ sfizz_lv2_map_required_uris(sfizz_plugin_t *self)
self->state_changed_uri = map->map(map->handle, LV2_STATE__StateChanged);
self->sfizz_sfz_file_uri = map->map(map->handle, SFIZZ__sfzFile);
self->sfizz_scala_file_uri = map->map(map->handle, SFIZZ__tuningfile);
self->sfizz_description_uri = map->map(map->handle, SFIZZ__description);
self->sfizz_num_voices_uri = map->map(map->handle, SFIZZ__numVoices);
self->sfizz_preload_size_uri = map->map(map->handle, SFIZZ__preloadSize);
self->sfizz_oversampling_uri = map->map(map->handle, SFIZZ__oversampling);
@ -658,6 +659,9 @@ instantiate(const LV2_Descriptor *descriptor,
sfizz_lv2_update_timeinfo(self, 0, ~0);
self->text_description[0] = 0;
self->resend_description = false;
#if defined(SFIZZ_LV2_UI)
if (self->multi_out)
self->rms_follower.setNumOutputs(MULTI_OUTPUT_COUNT);
@ -719,6 +723,25 @@ sfizz_lv2_send_file_path(sfizz_plugin_t *self, LV2_URID verb_uri, LV2_URID urid,
lv2_atom_forge_pop(forge, &frame);
}
static void
sfizz_lv2_send_instrument_description(sfizz_plugin_t *self)
{
LV2_Atom_Forge_Frame frame;
LV2_Atom_Forge* forge = &self->forge_automate;
bool write_ok =
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, self->sfizz_description_uri) &&
lv2_atom_forge_key(forge, self->patch_value_uri) &&
lv2_atom_forge_string(forge, self->text_description,
(uint32_t)strnlen(self->text_description, sizeof(self->text_description)));
if (write_ok)
lv2_atom_forge_pop(forge, &frame);
}
static void
sfizz_lv2_send_controller(sfizz_plugin_t *self, LV2_URID verb_uri, unsigned cc, float value)
{
@ -839,12 +862,6 @@ sfizz_lv2_handle_atom_object(sfizz_plugin_t *self, int delay, const LV2_Atom_Obj
}
}
static bool
sfizz_is_sustain_or_sostenuto(sfizz_plugin_t* self, unsigned cc)
{
return (self->sustain_or_sostenuto[cc / 8] & (1 << (cc % 8)));
}
static void
sfizz_lv2_process_midi_event(sfizz_plugin_t *self, const LV2_Atom_Event *ev)
{
@ -1072,6 +1089,8 @@ run(LV2_Handle instance, uint32_t sample_count)
for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc)
sfizz_lv2_send_controller(self, self->sfizz_notify_uri, cc, self->cc_current[cc]);
sfizz_lv2_send_instrument_description(self);
}
else if (property->body == self->sfizz_sfz_file_uri)
{
@ -1081,6 +1100,10 @@ run(LV2_Handle instance, uint32_t sample_count)
{
sfizz_lv2_send_file_path(self, self->sfizz_notify_uri, self->sfizz_scala_file_uri, self->scala_file_path);
}
else if (property->body == self->sfizz_description_uri)
{
sfizz_lv2_send_instrument_description(self);
}
else
{
int cc = sfizz_lv2_ccmap_unmap(self->ccmap, property->body);
@ -1193,6 +1216,10 @@ run(LV2_Handle instance, uint32_t sample_count)
*(self->num_groups_port) = sfizz_get_num_groups(self->synth);
*(self->num_regions_port) = sfizz_get_num_regions(self->synth);
*(self->num_samples_port) = sfizz_get_num_preloaded_samples(self->synth);
if (self->resend_description) {
sfizz_lv2_send_instrument_description(self);
self->resend_description = false;
}
// Log the buffer usage
self->sample_counter += (int)sample_count;
@ -1379,15 +1406,20 @@ sfizz_lv2_update_sfz_info(sfizz_plugin_t *self)
//
const InstrumentDescription desc = parseDescriptionBlob(blob);
char *cursor = self->text_description;
char *end = self->text_description + sizeof(self->text_description);
cursor += snprintf(cursor, end - cursor, "CC used:\n");
for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) {
if (desc.ccUsed.test(cc) && !desc.sustainOrSostenuto.test(cc)) {
// Update the current CCs
self->cc_current[cc] = desc.ccValue[cc];
if (desc.ccLabel[cc].empty())
cursor += snprintf(cursor, end - cursor, "- %d\n", cc);
else
cursor += snprintf(cursor, end - cursor, "- %d: %s\n",
cc, desc.ccLabel[cc].c_str());
}
}
memcpy(self->sustain_or_sostenuto, desc.sustainOrSostenuto.data(),
sizeof(self->sustain_or_sostenuto));
}
static bool
@ -1653,15 +1685,15 @@ save(LV2_Handle instance,
}
static void
sfizz_lv2_activate_file_checking(
sfizz_plugin_t *self,
sfizz_lv2_respond_with_simple_atom(
LV2_Worker_Respond_Function respond,
LV2_Worker_Respond_Handle handle)
LV2_Worker_Respond_Handle handle,
uint32_t type_uri)
{
LV2_Atom check_modification_atom;
check_modification_atom.size = 0;
check_modification_atom.type = self->sfizz_check_modification_uri;
respond(handle, lv2_atom_total_size(&check_modification_atom), &check_modification_atom);
LV2_Atom atom;
atom.size = 0;
atom.type = type_uri;
respond(handle, lv2_atom_total_size(&atom), &atom);
}
// This runs in a lower priority thread
@ -1694,7 +1726,8 @@ work(LV2_Handle instance,
}
// Reactivate checking for file changes
sfizz_lv2_activate_file_checking(self, respond, handle);
sfizz_lv2_respond_with_simple_atom(respond, handle, self->sfizz_check_modification_uri);
sfizz_lv2_respond_with_simple_atom(respond, handle, self->sfizz_description_uri);
}
else if (atom->type == self->sfizz_scala_file_uri)
{
@ -1712,7 +1745,7 @@ work(LV2_Handle instance,
}
// Reactivate checking for file changes
sfizz_lv2_activate_file_checking(self, respond, handle);
sfizz_lv2_respond_with_simple_atom(respond, handle, self->sfizz_check_modification_uri);
}
else if (atom->type == self->sfizz_num_voices_uri)
{
@ -1777,6 +1810,8 @@ work(LV2_Handle instance,
lv2_log_error(&self->logger,
"[sfizz] Error with %s; no file should be loaded\n", self->sfz_file_path);
}
sfizz_lv2_respond_with_simple_atom(respond, handle, self->sfizz_description_uri);
}
if (sfizz_should_reload_scala(self->synth))
@ -1798,7 +1833,7 @@ work(LV2_Handle instance,
}
// Reactivate checking for file changes
sfizz_lv2_activate_file_checking(self, respond, handle);
sfizz_lv2_respond_with_simple_atom(respond, handle, self->sfizz_check_modification_uri);
}
else
{
@ -1827,6 +1862,8 @@ work_response(LV2_Handle instance,
const LV2_Atom *atom = (const LV2_Atom *)data;
if (atom->type == self->sfizz_check_modification_uri) {
self->check_modification = true; // check changes
} else if (atom->type == self->sfizz_description_uri) {
self->resend_description = true;
} else {
lv2_log_error(&self->logger, "[sfizz] Got an unexpected atom in work response\n");
if (self->unmap)

View file

@ -65,6 +65,11 @@ midnam:update a lv2:Feature .
"File Scala"@it ;
rdfs:range atom:Path .
<@LV2PLUGIN_URI@:description>
a lv2:Parameter ;
rdfs:label "Instrument description" ;
rdfs:range atom:String .
<@LV2PLUGIN_URI@>
a doap:Project, lv2:Plugin, lv2:InstrumentPlugin ;
@ -96,6 +101,7 @@ midnam:update a lv2:Feature .
patch:writable <@LV2PLUGIN_URI@:sfzfile> ,
<@LV2PLUGIN_URI@:tuningfile> ;
patch:readable <@LV2PLUGIN_URI@:description> ;
pg:mainOutput <@LV2PLUGIN_URI@#stereo_output> ;
@ -471,6 +477,7 @@ midnam:update a lv2:Feature .
patch:writable <@LV2PLUGIN_URI@:sfzfile> ,
<@LV2PLUGIN_URI@:tuningfile> ;
patch:readable <@LV2PLUGIN_URI@:description> ;
pg:mainOutput <@LV2PLUGIN_URI@#stereo_output> ;

View file

@ -42,6 +42,7 @@
#define SFIZZ__preloadSize SFIZZ_URI ":" "preload_size"
#define SFIZZ__oversampling SFIZZ_URI ":" "oversampling"
#define SFIZZ__lastKeyswitch SFIZZ_URI ":" "last_keyswitch"
#define SFIZZ__description SFIZZ_URI ":" "description"
// These ones are just for the worker
#define SFIZZ__logStatus SFIZZ_URI ":" "log_status"
#define SFIZZ__checkModification SFIZZ_URI ":" "check_modification"

View file

@ -87,6 +87,7 @@ struct sfizz_plugin_t
LV2_URID state_changed_uri {};
LV2_URID sfizz_sfz_file_uri {};
LV2_URID sfizz_scala_file_uri {};
LV2_URID sfizz_description_uri {};
LV2_URID sfizz_num_voices_uri {};
LV2_URID sfizz_preload_size_uri {};
LV2_URID sfizz_oversampling_uri {};
@ -132,9 +133,8 @@ struct sfizz_plugin_t
volatile int sfz_blob_serial {};
const uint8_t *volatile sfz_blob_data {};
volatile uint32_t sfz_blob_size {};
// Sostenuto or sustain
char sustain_or_sostenuto[16] {};
char text_description[1024];
volatile bool resend_description {};
// Current CC values in the synth (synchronized by `synth_mutex`)
// updated by hdcc or file load