commit ab615b89ca68bf0e4c83f5688d47ca1624340282
parent ebae08466008f83453975290aec0be25d67283bd
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date: Tue, 3 May 2022 21:57:48 +0200
More work on the plugin template
Diffstat:
5 files changed, 195 insertions(+), 2 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -18,7 +18,7 @@ add_executable(clap-compile-cpp EXCLUDE_FROM_ALL src/main.cc)
target_link_libraries(clap-compile-cpp clap-core)
set_target_properties(clap-compile-cpp PROPERTIES CXX_STANDARD 14)
-add_library(clap-plugin-template EXCLUDE_FROM_ALL src/plugin-template.c)
+add_library(clap-plugin-template MODULE EXCLUDE_FROM_ALL src/plugin-template.c)
target_link_libraries(clap-plugin-template clap-core)
set_target_properties(clap-plugin-template PROPERTIES C_STANDARD 11)
@@ -32,6 +32,26 @@ if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
target_compile_options(clap-compile-cpp PRIVATE -Werror=pragma-pack)
endif()
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ target_link_libraries(clap-plugin-template PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/linux-my_plug.version)
+ target_link_libraries(clap-plugin-template PRIVATE -Wl,-z,defs)
+ set_target_properties(clap-plugin-template PROPERTIES SUFFIX ".clap" PREFIX "")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ target_link_options(clap-plugin-template PRIVATE -exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/src/macos-symbols.txt)
+
+ set_target_properties(clap-plugin-template PROPERTIES
+ BUNDLE True
+ BUNDLE_EXTENSION clap
+ MACOSX_BUNDLE_GUI_IDENTIFIER com.my_company.my_plug
+ MACOSX_BUNDLE_BUNDLE_NAME my_plug
+ MACOSX_BUNDLE_BUNDLE_VERSION "1"
+ MACOSX_BUNDLE_SHORT_VERSION_STRING "1"
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/plugins.plist.in
+ )
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set_target_properties(clap-plugin-template PROPERTIES SUFFIX ".clap" PREFIX "")
+endif()
+
add_test(NAME test-clap-compile-c COMMAND clap-compile-c)
add_test(NAME test-clap-compile-cpp COMMAND clap-compile-cpp)
diff --git a/src/linux-my_plug.version b/src/linux-my_plug.version
@@ -0,0 +1,6 @@
+MY_PLUG_ABI_1.0 {
+ global:
+ clap_entry;
+ local:
+ *;
+};
diff --git a/src/macos-symbols.txt b/src/macos-symbols.txt
@@ -0,0 +1 @@
+_clap_entry
diff --git a/src/plugin-template.c b/src/plugin-template.c
@@ -19,6 +19,7 @@ static const clap_plugin_descriptor_t s_my_plug_desc = {
typedef struct {
clap_plugin_t plugin;
const clap_host_t *host;
+ uint32_t latency;
} my_plug_t;
/////////////////////////////
@@ -47,11 +48,39 @@ static const clap_plugin_audio_ports_t s_my_plug_audio_ports = {
.get = my_plug_audio_ports_get,
};
+////////////////////////////
+// clap_plugin_note_ports //
+////////////////////////////
+
+static uint32_t my_plug_note_ports_count(const clap_plugin_t *plugin, bool is_input) { return 1; }
+
+static bool my_plug_note_ports_get(const clap_plugin_t *plugin,
+ uint32_t index,
+ bool is_input,
+ clap_note_port_info_t *info) {
+ if (index != 1)
+ return false;
+ info->id = 0;
+ snprintf(info->name, sizeof(info->name), "%s", "My Port Name");
+ info->supported_dialects =
+ CLAP_NOTE_DIALECT_CLAP | CLAP_NOTE_DIALECT_MIDI_MPE | CLAP_NOTE_DIALECT_MIDI2;
+ info->preferred_dialect = CLAP_NOTE_DIALECT_CLAP;
+ return true;
+}
+
+static const clap_plugin_note_ports_t s_my_plug_note_ports = {
+ .count = my_plug_note_ports_count,
+ .get = my_plug_note_ports_get,
+};
+
//////////////////
// clap_latency //
//////////////////
-uint32_t my_plug_latency_get(const clap_plugin_t *plugin) { return 0; }
+uint32_t my_plug_latency_get(const clap_plugin_t *plugin) {
+ my_plug_t *plug = plugin->plugin_data;
+ return plug->latency;
+}
static const clap_plugin_latency_t s_my_plug_latency = {
.get = my_plug_latency_get,
@@ -80,8 +109,109 @@ static void my_plug_stop_processing(const struct clap_plugin *plugin) {}
static void my_plug_reset(const struct clap_plugin *plugin) {}
+static void my_plug_process_event(my_plug_t *plug, const clap_event_header_t *hdr) {
+ if (hdr->space_id == CLAP_CORE_EVENT_SPACE_ID) {
+ switch (hdr->type) {
+ case CLAP_EVENT_NOTE_ON: {
+ const clap_event_note_t *ev = (const clap_event_note_t *)hdr;
+ // TODO: handle note on
+ break;
+ }
+
+ case CLAP_EVENT_NOTE_OFF: {
+ const clap_event_note_t *ev = (const clap_event_note_t *)hdr;
+ // TODO: handle note on
+ break;
+ }
+
+ case CLAP_EVENT_NOTE_CHOKE: {
+ const clap_event_note_t *ev = (const clap_event_note_t *)hdr;
+ // TODO: handle note choke
+ break;
+ }
+
+ case CLAP_EVENT_NOTE_EXPRESSION: {
+ const clap_event_note_expression_t *ev = (const clap_event_note_expression_t *)hdr;
+ // TODO: handle note expression
+ break;
+ }
+
+ case CLAP_EVENT_PARAM_VALUE: {
+ const clap_event_param_value_t *ev = (const clap_event_param_value_t *)hdr;
+ // TODO: handle parameter change
+ break;
+ }
+
+ case CLAP_EVENT_PARAM_MOD: {
+ const clap_event_param_mod_t *ev = (const clap_event_param_mod_t *)hdr;
+ // TODO: handle parameter modulation
+ break;
+ }
+
+ case CLAP_EVENT_TRANSPORT: {
+ const clap_event_transport_t *ev = (const clap_event_transport_t *)hdr;
+ // TODO: handle transport event
+ break;
+ }
+
+ case CLAP_EVENT_MIDI: {
+ const clap_event_midi_t *ev = (const clap_event_midi_t *)hdr;
+ // TODO: handle MIDI event
+ break;
+ }
+
+ case CLAP_EVENT_MIDI_SYSEX: {
+ const clap_event_midi_sysex_t *ev = (const clap_event_midi_sysex_t *)hdr;
+ // TODO: handle MIDI Sysex event
+ break;
+ }
+
+ case CLAP_EVENT_MIDI2: {
+ const clap_event_midi2_t *ev = (const clap_event_midi2_t *)hdr;
+ // TODO: handle MIDI2 event
+ break;
+ }
+ }
+ }
+}
+
static clap_process_status my_plug_process(const struct clap_plugin *plugin,
const clap_process_t *process) {
+ my_plug_t *plug = plugin->plugin_data;
+ const uint32_t nframes = process->frames_count;
+ const uint32_t nev = process->in_events->size(process->in_events);
+ uint32_t ev_index = 0;
+ uint32_t next_ev_frame = (nev == 0 ? nframes : 0);
+
+ for (uint32_t i = 0; i < nframes;) {
+ while (ev_index < nev && next_ev_frame == i) {
+ const clap_event_header_t *hdr = process->in_events->get(process->in_events, ev_index);
+ if (hdr->time != i) {
+ next_ev_frame = hdr->time;
+ break;
+ }
+
+ my_plug_process_event(plug, hdr);
+ ++ev_index;
+ if (ev_index == nev) {
+ next_ev_frame = nframes;
+ }
+ }
+
+ const uint32_t until_frame = next_ev_frame < nframes ? next_ev_frame : nframes;
+ for (; i < until_frame; ++i) {
+ const float in_l = process->audio_inputs[0].data32[0][i];
+ const float in_r = process->audio_inputs[0].data32[1][i];
+
+ /* TODO: process samples, here we simply swap left and right channels */
+ const float out_l = in_r;
+ const float out_r = in_l;
+
+ process->audio_outputs[0].data32[0][i] = out_l;
+ process->audio_outputs[0].data32[1][i] = out_r;
+ }
+ }
+
return CLAP_PROCESS_CONTINUE;
}
@@ -90,6 +220,8 @@ static const void *my_plug_get_extension(const struct clap_plugin *plugin, const
return &s_my_plug_latency;
if (!strcmp(id, CLAP_EXT_AUDIO_PORTS))
return &s_my_plug_audio_ports;
+ if (!strcmp(id, CLAP_EXT_NOTE_PORTS))
+ return &s_my_plug_note_ports;
return NULL;
}
diff --git a/src/plugins.plist.in b/src/plugins.plist.in
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${MACOSX_BUNDLE_INFO_STRING}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+</dict>
+</plist>