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
|
||||
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/lv2]")
|
||||
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})
|
||||
endif()
|
||||
|
||||
# Generate controllers.ttl
|
||||
sfizz_lv2_generate_controllers_ttl("${PROJECT_BINARY_DIR}/controllers.ttl")
|
||||
|
||||
# Copy resource files into the bundle
|
||||
set(LV2_RESOURCES
|
||||
DefaultInstrument.sfz
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<@LV2PLUGIN_URI@>
|
||||
a lv2:Plugin ;
|
||||
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@ 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;
|
||||
}
|
||||
|
||||
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
|
||||
instantiate(const LV2_Descriptor *descriptor,
|
||||
double rate,
|
||||
|
|
@ -476,6 +535,8 @@ instantiate(const LV2_Descriptor *descriptor,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sfizz_lv2_setup_cc_parameters(self);
|
||||
|
||||
self->synth = sfizz_create_synth();
|
||||
self->client = sfizz_create_client(self);
|
||||
self->synth_mutex = spin_mutex_create();
|
||||
|
|
@ -501,6 +562,8 @@ cleanup(LV2_Handle instance)
|
|||
spin_mutex_destroy(self->synth_mutex);
|
||||
sfizz_delete_client(self->client);
|
||||
sfizz_free(self->synth);
|
||||
delete[] self->cc_to_urid;
|
||||
delete[] self->urid_to_cc;
|
||||
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];
|
||||
} 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;
|
||||
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)
|
||||
{
|
||||
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
|
||||
|
||||
if (obj->body.otype == self->patch_set_uri)
|
||||
{
|
||||
sfizz_lv2_handle_atom_object(self, obj);
|
||||
|
|
|
|||
|
|
@ -371,4 +371,6 @@ midnam:update a lv2:Feature .
|
|||
lv2:default 0 ;
|
||||
lv2:minimum 0 ;
|
||||
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_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_synth_t *synth {};
|
||||
sfizz_client_t *client {};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue