CC as parameters for LV2
This commit is contained in:
parent
55fe026143
commit
1c3104800a
7 changed files with 139 additions and 3 deletions
|
|
@ -40,3 +40,46 @@ else()
|
||||||
set(LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/lv2" CACHE STRING
|
set(LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/lv2" CACHE STRING
|
||||||
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/lv2]")
|
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/lv2]")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(StringUtility)
|
||||||
|
|
||||||
|
function(sfizz_lv2_generate_controllers_ttl FILE)
|
||||||
|
file(WRITE "${FILE}" "# LV2 parameters for SFZ controllers
|
||||||
|
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
@prefix sfizz: <${LV2PLUGIN_URI}#> .
|
||||||
|
")
|
||||||
|
math(EXPR _j "${SFIZZ_NUM_CCS}-1")
|
||||||
|
foreach(_i RANGE "${_j}")
|
||||||
|
string_left_pad(_i "${_i}" 3 0)
|
||||||
|
file(APPEND "${FILE}" "
|
||||||
|
sfizz:cc${_i}
|
||||||
|
a lv2:Parameter ;
|
||||||
|
rdfs:label \"Controller ${_i}\" ;
|
||||||
|
rdfs:range atom:Float .
|
||||||
|
")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
file(APPEND "${FILE}" "
|
||||||
|
<${LV2PLUGIN_URI}>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
")
|
||||||
|
|
||||||
|
file(APPEND "${FILE}" " patch:readable sfizz:cc000")
|
||||||
|
foreach(_i RANGE 1 "${_j}")
|
||||||
|
string_left_pad(_i "${_i}" 3 0)
|
||||||
|
file(APPEND "${FILE}" ", sfizz:cc${_i}")
|
||||||
|
endforeach()
|
||||||
|
file(APPEND "${FILE}" " ;
|
||||||
|
")
|
||||||
|
|
||||||
|
file(APPEND "${FILE}" " patch:writable sfizz:cc000")
|
||||||
|
foreach(_i RANGE 1 "${_j}")
|
||||||
|
string_left_pad(_i "${_i}" 3 0)
|
||||||
|
file(APPEND "${FILE}" ", sfizz:cc${_i}")
|
||||||
|
endforeach()
|
||||||
|
file(APPEND "${FILE}" " .
|
||||||
|
")
|
||||||
|
endfunction()
|
||||||
|
|
|
||||||
11
cmake/StringUtility.cmake
Normal file
11
cmake/StringUtility.cmake
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
function(string_left_pad VAR INPUT LENGTH FILLCHAR)
|
||||||
|
set(_output "${INPUT}")
|
||||||
|
string(LENGTH "${_output}" _length)
|
||||||
|
while(_length LESS "${LENGTH}")
|
||||||
|
string(PREPEND _output "${FILLCHAR}")
|
||||||
|
string(LENGTH "${_output}" _length)
|
||||||
|
endwhile()
|
||||||
|
set("${VAR}" "${_output}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
@ -82,6 +82,9 @@ if(SFIZZ_USE_VCPKG OR SFIZZ_STATIC_DEPENDENCIES OR CMAKE_CXX_COMPILER_ID MATCHES
|
||||||
file(COPY "lgpl-3.0.txt" DESTINATION ${PROJECT_BINARY_DIR})
|
file(COPY "lgpl-3.0.txt" DESTINATION ${PROJECT_BINARY_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Generate controllers.ttl
|
||||||
|
sfizz_lv2_generate_controllers_ttl("${PROJECT_BINARY_DIR}/controllers.ttl")
|
||||||
|
|
||||||
# Copy resource files into the bundle
|
# Copy resource files into the bundle
|
||||||
set(LV2_RESOURCES
|
set(LV2_RESOURCES
|
||||||
DefaultInstrument.sfz
|
DefaultInstrument.sfz
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<@LV2PLUGIN_URI@>
|
<@LV2PLUGIN_URI@>
|
||||||
a lv2:Plugin ;
|
a lv2:Plugin ;
|
||||||
lv2:binary <Contents/Binary/@PROJECT_NAME@@CMAKE_SHARED_MODULE_SUFFIX@> ;
|
lv2:binary <Contents/Binary/@PROJECT_NAME@@CMAKE_SHARED_MODULE_SUFFIX@> ;
|
||||||
rdfs:seeAlso <@PROJECT_NAME@.ttl> .
|
rdfs:seeAlso <@PROJECT_NAME@.ttl>, <controllers.ttl> .
|
||||||
|
|
||||||
@LV2PLUGIN_IF_ENABLE_UI@<@LV2PLUGIN_URI@#ui>
|
@LV2PLUGIN_IF_ENABLE_UI@<@LV2PLUGIN_URI@#ui>
|
||||||
@LV2PLUGIN_IF_ENABLE_UI@ a ui:@LV2_UI_TYPE@ ;
|
@LV2PLUGIN_IF_ENABLE_UI@ a ui:@LV2_UI_TYPE@ ;
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,65 @@ sfizz_lv2_receive_message(void* data, int delay, const char* path, const char* s
|
||||||
(void)write_ok;
|
(void)write_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sfizz_lv2_setup_cc_parameters(sfizz_plugin_t* self)
|
||||||
|
{
|
||||||
|
// store the associations between CC number and parameter URID
|
||||||
|
// construct it trivially in the form of a tabulated perfect hash function
|
||||||
|
|
||||||
|
LV2_URID* cc_to_urid = new LV2_URID[sfz::config::numCCs];
|
||||||
|
int* urid_to_cc;
|
||||||
|
int urid_to_cc_size;
|
||||||
|
|
||||||
|
LV2_URID min_cc_urid {};
|
||||||
|
LV2_URID max_cc_urid {};
|
||||||
|
for (int cc = 0; cc < sfz::config::numCCs; ++cc) {
|
||||||
|
char name[256];
|
||||||
|
sprintf(name, SFIZZ_URI "#cc%03d", cc);
|
||||||
|
LV2_URID urid = self->map->map(self->map->handle, name);
|
||||||
|
if (cc == 0) {
|
||||||
|
min_cc_urid = urid;
|
||||||
|
max_cc_urid = urid;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
min_cc_urid = (urid < min_cc_urid) ? urid : min_cc_urid;
|
||||||
|
max_cc_urid = (urid > max_cc_urid) ? urid : max_cc_urid;
|
||||||
|
}
|
||||||
|
cc_to_urid[cc] = urid;
|
||||||
|
}
|
||||||
|
|
||||||
|
urid_to_cc_size = max_cc_urid - min_cc_urid + 1;
|
||||||
|
urid_to_cc = new int[urid_to_cc_size];
|
||||||
|
|
||||||
|
for (int i = 0; i < urid_to_cc_size; ++i)
|
||||||
|
urid_to_cc[i] = -1;
|
||||||
|
|
||||||
|
for (int cc = 0; cc < sfz::config::numCCs; ++cc) {
|
||||||
|
LV2_URID urid = cc_to_urid[cc];
|
||||||
|
urid_to_cc[urid - min_cc_urid] = cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->cc_to_urid = cc_to_urid;
|
||||||
|
self->urid_to_cc = urid_to_cc;
|
||||||
|
self->min_cc_urid = min_cc_urid;
|
||||||
|
self->max_cc_urid = max_cc_urid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sfizz_lv2_get_cc_from_parameter_urid(const sfizz_plugin_t* self, LV2_URID urid)
|
||||||
|
{
|
||||||
|
int cc = -1;
|
||||||
|
if (urid >= self->min_cc_urid && urid <= self->max_cc_urid)
|
||||||
|
cc = self->urid_to_cc[urid - self->min_cc_urid];
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_URID
|
||||||
|
sfizz_lv2_get_parameter_urid_from_cc(const sfizz_plugin_t* self, int cc)
|
||||||
|
{
|
||||||
|
return self->cc_to_urid[cc];
|
||||||
|
}
|
||||||
|
|
||||||
static LV2_Handle
|
static LV2_Handle
|
||||||
instantiate(const LV2_Descriptor *descriptor,
|
instantiate(const LV2_Descriptor *descriptor,
|
||||||
double rate,
|
double rate,
|
||||||
|
|
@ -476,6 +535,8 @@ instantiate(const LV2_Descriptor *descriptor,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sfizz_lv2_setup_cc_parameters(self);
|
||||||
|
|
||||||
self->synth = sfizz_create_synth();
|
self->synth = sfizz_create_synth();
|
||||||
self->client = sfizz_create_client(self);
|
self->client = sfizz_create_client(self);
|
||||||
self->synth_mutex = spin_mutex_create();
|
self->synth_mutex = spin_mutex_create();
|
||||||
|
|
@ -501,6 +562,8 @@ cleanup(LV2_Handle instance)
|
||||||
spin_mutex_destroy(self->synth_mutex);
|
spin_mutex_destroy(self->synth_mutex);
|
||||||
sfizz_delete_client(self->client);
|
sfizz_delete_client(self->client);
|
||||||
sfizz_free(self->synth);
|
sfizz_free(self->synth);
|
||||||
|
delete[] self->cc_to_urid;
|
||||||
|
delete[] self->urid_to_cc;
|
||||||
delete self;
|
delete self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -575,7 +638,14 @@ sfizz_lv2_handle_atom_object(sfizz_plugin_t *self, const LV2_Atom_Object *obj)
|
||||||
char body[MAX_PATH_SIZE];
|
char body[MAX_PATH_SIZE];
|
||||||
} sfizz_path_atom_buffer_t;
|
} sfizz_path_atom_buffer_t;
|
||||||
|
|
||||||
if (key == self->sfizz_sfz_file_uri)
|
int cc = sfizz_lv2_get_cc_from_parameter_urid(self, key);
|
||||||
|
if (cc != -1) {
|
||||||
|
if (atom->type == self->atom_float_uri && atom->size == sizeof(float)) {
|
||||||
|
float value = *(const float *)LV2_ATOM_BODY_CONST(atom);
|
||||||
|
// TODO: CC parameter arrived
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key == self->sfizz_sfz_file_uri)
|
||||||
{
|
{
|
||||||
LV2_Atom_Forge *forge = &self->forge_secondary;
|
LV2_Atom_Forge *forge = &self->forge_secondary;
|
||||||
sfizz_path_atom_buffer_t buffer;
|
sfizz_path_atom_buffer_t buffer;
|
||||||
|
|
@ -796,6 +866,7 @@ run(LV2_Handle instance, uint32_t sample_count)
|
||||||
if (ev->body.type == self->atom_object_uri || ev->body.type == self->atom_blank_uri)
|
if (ev->body.type == self->atom_object_uri || ev->body.type == self->atom_blank_uri)
|
||||||
{
|
{
|
||||||
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
|
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
|
||||||
|
|
||||||
if (obj->body.otype == self->patch_set_uri)
|
if (obj->body.otype == self->patch_set_uri)
|
||||||
{
|
{
|
||||||
sfizz_lv2_handle_atom_object(self, obj);
|
sfizz_lv2_handle_atom_object(self, obj);
|
||||||
|
|
|
||||||
|
|
@ -371,4 +371,6 @@ midnam:update a lv2:Feature .
|
||||||
lv2:default 0 ;
|
lv2:default 0 ;
|
||||||
lv2:minimum 0 ;
|
lv2:minimum 0 ;
|
||||||
lv2:maximum 65535 ;
|
lv2:maximum 65535 ;
|
||||||
] .
|
] ;
|
||||||
|
|
||||||
|
rdfs:seeAlso <controllers.ttl> .
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,12 @@ struct sfizz_plugin_t
|
||||||
LV2_URID time_beats_per_minute_uri {};
|
LV2_URID time_beats_per_minute_uri {};
|
||||||
LV2_URID time_speed_uri {};
|
LV2_URID time_speed_uri {};
|
||||||
|
|
||||||
|
// CC parameters
|
||||||
|
LV2_URID* cc_to_urid {};
|
||||||
|
int* urid_to_cc {};
|
||||||
|
LV2_URID min_cc_urid {};
|
||||||
|
LV2_URID max_cc_urid {};
|
||||||
|
|
||||||
// Sfizz related data
|
// Sfizz related data
|
||||||
sfizz_synth_t *synth {};
|
sfizz_synth_t *synth {};
|
||||||
sfizz_client_t *client {};
|
sfizz_client_t *client {};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue