### Iterate and Get Plugin Descriptors Example Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Shows how to iterate through all available plugins using their index, retrieve their descriptors, and print basic information like name, ID, vendor, version, and features. ```c for (uint32_t i = 0; i < factory->get_plugin_count(factory); ++i) { const clap_plugin_descriptor_t *desc = factory->get_plugin_descriptor(factory, i); if (desc) { printf("Plugin %u: %s (%s)\n", i, desc->name, desc->id); printf(" Vendor: %s\n", desc->vendor ? desc->vendor : "Unknown"); printf(" Version: %s\n", desc->version ? desc->version : "Unknown"); // Display features if (desc->features) { printf(" Features: "); for (int j = 0; desc->features[j]; ++j) { printf("%s%s", j > 0 ? ", " : "", desc->features[j]); } printf("\n"); } } } ``` -------------------------------- ### Get Plugin Count Example Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Demonstrates how to retrieve the total number of plugins available from the factory. This is typically called during plugin discovery. ```c const clap_plugin_factory_t *factory = (const clap_plugin_factory_t *)entry->get_factory(CLAP_PLUGIN_FACTORY_ID); if (factory) { uint32_t count = factory->get_plugin_count(factory); printf("Found %u plugins\n", count); } ``` -------------------------------- ### Configuration Setup Source: https://github.com/free-audio/clap/blob/main/_autodocs/COMPLETION_SUMMARY.txt Illustrates setting up plugin configuration, including audio ports and parameters. ```c // Configuration of audio ports, parameter ranges, and default values. ``` -------------------------------- ### Typical CLAP Parameter Implementation Example Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/params-extension.md Illustrates a common C-based implementation for managing plugin parameters, including data structures and functions for retrieving parameter information and values. This example shows how to define parameter properties and respond to host queries. ```c typedef struct { clap_id id; const char *name; double min_value; double max_value; double default_value; double current_value; clap_param_info_flags flags; } my_parameter_t; my_parameter_t params[] = { {1, "Volume", 0.0, 100.0, 80.0, 80.0, CLAP_PARAM_IS_AUTOMATABLE}, {2, "Filter Type", 0.0, 2.0, 0.0, 0.0, CLAP_PARAM_IS_STEPPED | CLAP_PARAM_IS_AUTOMATABLE}, {3, "Master Tune", -12.0, 12.0, 0.0, 0.0, CLAP_PARAM_IS_AUTOMATABLE | CLAP_PARAM_REQUIRES_PROCESS}, }; const uint32_t PARAM_COUNT = 3; uint32_t params_count(const clap_plugin_t *plugin) { return PARAM_COUNT; } bool params_get_info(const clap_plugin_t *plugin, uint32_t index, clap_param_info_t *info) { if (index >= PARAM_COUNT) return false; my_parameter_t *p = ¶ms[index]; info->id = p->id; info->flags = p->flags; info->cookie = p; strncpy(info->name, p->name, CLAP_NAME_SIZE - 1); info->module[0] = '\0'; info->min_value = p->min_value; info->max_value = p->max_value; info->default_value = p->default_value; return true; } bool params_get_value(const clap_plugin_t *plugin, clap_id param_id, double *out_value) { for (int i = 0; i < PARAM_COUNT; ++i) { if (params[i].id == param_id) { *out_value = params[i].current_value; return true; } } return false; } ``` -------------------------------- ### Practical Examples Source: https://github.com/free-audio/clap/blob/main/_autodocs/COMPLETION_SUMMARY.txt Offers practical usage examples for various CLAP API features, including entry points, lifecycle, and processing. ```APIDOC ## Practical Examples ### Description Illustrates common CLAP API usage patterns with realistic code examples. ### Example Scenarios - Entry point usage. - Plugin factory creation. - Plugin lifecycle sequences. - Audio processing loops. - Event handling. - Parameter management. - State save/load operations. - Configuration setup. - Complete working examples demonstrating various features. ``` -------------------------------- ### Example Note Port Configurations Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/note-ports-extension.md Illustrates different configurations for supported and preferred note dialects based on plugin capabilities. ```c // Synthesizer supporting CLAP notes natively, can fallback to MIDI supported_dialects = CLAP_NOTE_DIALECT_CLAP | CLAP_NOTE_DIALECT_MIDI; preferred_dialect = CLAP_NOTE_DIALECT_CLAP; ``` ```c // Simple MIDI-only plugin supported_dialects = CLAP_NOTE_DIALECT_MIDI; preferred_dialect = CLAP_NOTE_DIALECT_MIDI; ``` ```c // Advanced plugin with full MIDI 2.0 and MPE support supported_dialects = CLAP_NOTE_DIALECT_CLAP | CLAP_NOTE_DIALECT_MIDI | CLAP_NOTE_DIALECT_MIDI_MPE | CLAP_NOTE_DIALECT_MIDI2; preferred_dialect = CLAP_NOTE_DIALECT_CLAP; ``` -------------------------------- ### Plugin Real-Time Requirement Examples Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/render-latency-extensions.md Examples demonstrating how to implement `has_hard_realtime_requirement`. Synthesizers often need real-time safety, while effects like convolvers might be processed offline. ```c bool render_has_hard_realtime_requirement(const clap_plugin_t *plugin) { // Synthesizers typically need real-time safety return true; } // vs. bool render_has_hard_realtime_requirement(const clap_plugin_t *plugin) { // Convolver might need huge buffers - can be offline return false; } ``` -------------------------------- ### Install CLAP Target and Export Source: https://github.com/free-audio/clap/blob/main/CMakeLists.txt Installs the 'clap' target and exports it for use by other CMake projects. Includes header files in the installation. ```cmake install(TARGETS clap EXPORT clap INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") ``` -------------------------------- ### Configure and Install pkg-config File Source: https://github.com/free-audio/clap/blob/main/CMakeLists.txt Generates and installs a pkg-config file for portable library consumption. This ensures that other projects can easily find and link against the CLAP library. ```cmake configure_file(clap.pc.in "${CMAKE_CURRENT_BINARY_DIR}/clap.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/clap.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") ``` -------------------------------- ### Install CLAP Header Directory Source: https://github.com/free-audio/clap/blob/main/CMakeLists.txt Installs the 'include/clap' directory to the system's include directory during installation. ```cmake install(DIRECTORY "include/clap" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") ``` -------------------------------- ### Install CMake Configuration File Source: https://github.com/free-audio/clap/blob/main/CMakeLists.txt Installs the CMake configuration file for the 'clap' package, enabling other projects to find and use it. ```cmake install(EXPORT clap DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clap" FILE "clap-config.cmake") ``` -------------------------------- ### Create Plugin Instance Example Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Demonstrates the process of creating a plugin instance using its ID and a host instance. It includes basic host structure initialization and checks for successful plugin creation and initialization. ```c const clap_plugin_factory_t *factory = (const clap_plugin_factory_t *)entry->get_factory(CLAP_PLUGIN_FACTORY_ID); clap_host_t host = { .clap_version = CLAP_VERSION_INIT, .name = "My DAW", .vendor = "My Company", .version = "1.0.0", .get_extension = host_get_extension, .request_restart = host_request_restart, .request_process = host_request_process, .request_callback = host_request_callback, }; const clap_plugin_t *plugin = factory->create_plugin(factory, &host, "com.example.my-plugin"); if (plugin) { if (!plugin->init(plugin)) { printf("Plugin initialization failed\n"); // Host will call plugin->destroy() in its error handler } else { printf("Plugin created and initialized\n"); } } else { printf("Plugin creation failed\n"); } ``` -------------------------------- ### Host Latency Notification Example Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/render-latency-extensions.md Example demonstrating how a plugin can notify the host about a latency change, such as when an internal parameter like FFT size is modified. This ensures the host can re-evaluate its audio processing chain. ```c // Plugin allows user to change FFT size void set_fft_size(const clap_plugin_t *plugin, uint32_t new_fft_size) { plugin_t *self = (plugin_t *)plugin->plugin_data; if (self->fft_size == new_fft_size) { return; // No change } self->fft_size = new_fft_size; // Notify host that latency changed clap_host_t *host = self->host; clap_host_latency_t *latency_ext = (clap_host_latency_t *)host->get_extension(host, CLAP_EXT_LATENCY); if (latency_ext) { latency_ext->changed(host); } } ``` -------------------------------- ### Plugin Latency Examples Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/render-latency-extensions.md Illustrates how different types of plugins might report their latency. Latency is reported in samples and must be constant during activation. ```c // Simple filter with minimal latency uint32_t latency_get(const clap_plugin_t *plugin) { return 1; // 1 sample delay } // Convolver with significant latency uint32_t latency_get(const clap_plugin_t *plugin) { plugin_t *self = (plugin_t *)plugin->plugin_data; return self->convolver_fft_size / 2; // FFT overlap-add latency } // Lookahead compressor uint32_t latency_get(const clap_plugin_t *plugin) { return 2048; // 2048 samples lookahead } ``` -------------------------------- ### Install Package Version File Source: https://github.com/free-audio/clap/blob/main/CMakeLists.txt Installs the generated package version file to the CMake configuration directory. ```cmake install(FILES "${CMAKE_CURRENT_BINARY_DIR}/clap-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clap") ``` -------------------------------- ### Host Loads DSO and Gets Entry Point Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md The host application loads the plugin's Dynamic Shared Object (DSO) and obtains the entry point structure. Initialization of the DSO is crucial and must be checked. ```c // Host loads DSO and gets entry point const clap_plugin_entry_t *entry = &clap_entry; // Obtained from loaded DSO // Initialize the DSO if (!entry->init(plugin_path)) { return; // Initialization failed } ``` -------------------------------- ### Initialize CLAP Plugin Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-interface.md Use this function to initialize a CLAP plugin after it has been created by the factory. The host must destroy the plugin if initialization fails. Plugin setup, such as parameter initialization and buffer allocation, should occur here. ```c bool init(const struct clap_plugin *plugin) ``` ```c const clap_plugin_t *plugin = factory->create_plugin(factory, host, plugin_id); if (!plugin || !plugin->init(plugin)) { return NULL; // Initialization failed } ``` -------------------------------- ### CLAP Input Note Port Configuration Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/note-ports-extension.md Example of configuring an input note port for a synthesizer, specifying supported dialects like CLAP and MIDI. ```c // Simple synthesizer with MIDI input clap_note_port_info_t input = { .id = 0, .name = "MIDI In", .supported_dialects = CLAP_NOTE_DIALECT_CLAP | CLAP_NOTE_DIALECT_MIDI, .preferred_dialect = CLAP_NOTE_DIALECT_CLAP, }; ``` -------------------------------- ### Get Plugin Factory from Entry Point Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Retrieves the plugin factory interface from the entry point. If the factory is not available, the DSO must be deinitialized. ```c // Get the plugin factory from the entry point const clap_plugin_factory_t *factory = (const clap_plugin_factory_t *)entry->get_factory(CLAP_PLUGIN_FACTORY_ID); if (!factory) { // Factory not available entry->deinit(); return; } ``` -------------------------------- ### Feature Strings for Synthesizer Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Example of how to define feature strings for a synthesizer plugin. The array must be NULL-terminated. ```c // Synthesizer example const char *const synthesizer_features[] = { "instrument", "synthesizer", "mono", NULL }; ``` -------------------------------- ### CLAP Output Note Port Configuration Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/note-ports-extension.md Example of configuring an output note port for an arpeggiator or sequencer, supporting the CLAP dialect. ```c // Arpeggiator or sequencer that generates notes clap_note_port_info_t output = { .id = 0, .name = "Note Out", .supported_dialects = CLAP_NOTE_DIALECT_CLAP, .preferred_dialect = CLAP_NOTE_DIALECT_CLAP, }; ``` -------------------------------- ### Writing Audio Samples to Output Buffer Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/audio-processing.md Provides an example of writing generated audio samples to an output buffer. It iterates through all channels and frames, assigning the generated_sample value. ```c clap_audio_buffer_t *out_buffer = process->audio_outputs; for (uint32_t ch = 0; ch < out_buffer->channel_count; ++ch) { for (uint32_t i = 0; i < frames_count; ++i) { out_buffer->data32[ch][i] = generated_sample; } } ``` -------------------------------- ### Minimal CLAP Factory Implementation Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md This C code demonstrates a minimal CLAP plugin factory. It defines a single plugin descriptor and provides functions to get the plugin count, retrieve the descriptor, and create plugin instances. ```c static const clap_plugin_descriptor_t my_plugin_descriptor = { .clap_version = CLAP_VERSION_INIT, .id = "com.example.my-plugin", .name = "My Plugin", .vendor = "Example Inc.", .version = "1.0.0", .description = "A simple example plugin", .features = (const char *[]){ "audio-effect", NULL }, }; static uint32_t factory_get_plugin_count(const clap_plugin_factory_t *factory) { return 1; // We have one plugin } static const clap_plugin_descriptor_t *factory_get_plugin_descriptor( const clap_plugin_factory_t *factory, uint32_t index) { if (index != 0) return NULL; return &my_plugin_descriptor; } static const clap_plugin_t *factory_create_plugin( const clap_plugin_factory_t *factory, const clap_host_t *host, const char *plugin_id) { if (strcmp(plugin_id, my_plugin_descriptor.id) != 0) { return NULL; // Unknown plugin ID } // Allocate plugin instance plugin_t *plugin = (plugin_t *)malloc(sizeof(plugin_t)); if (!plugin) return NULL; // Initialize plugin structure plugin->clap = (clap_plugin_t){ .desc = &my_plugin_descriptor, .plugin_data = plugin, .init = plugin_init, .destroy = plugin_destroy, .activate = plugin_activate, .deactivate = plugin_deactivate, .start_processing = plugin_start_processing, .stop_processing = plugin_stop_processing, .reset = plugin_reset, .process = plugin_process, .get_extension = plugin_get_extension, .on_main_thread = plugin_on_main_thread, }; plugin->host = host; return &plugin->clap; } static const clap_plugin_factory_t my_factory = { .get_plugin_count = factory_get_plugin_count, .get_plugin_descriptor = factory_get_plugin_descriptor, .create_plugin = factory_create_plugin, }; ``` -------------------------------- ### Activate and Process Audio with Plugin Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Activates the plugin for audio processing with specified sample rate, buffer size, and latency. It then starts processing and handles audio buffers in a loop before cleanup. ```c // Activate for audio processing if (!plugin->activate(plugin, 48000.0, 256, 4096)) { plugin->destroy(plugin); return; } // Start real-time processing if (!plugin->start_processing(plugin)) { plugin->deactivate(plugin); plugin->destroy(plugin); return; } // Process audio in a loop for (size_t buffer = 0; buffer < num_buffers; ++buffer) { clap_process_t process = {0}; process.frames_count = 256; // ... fill in process context ... plugin->process(plugin, &process); } // Cleanup plugin->stop_processing(plugin); plugin->deactivate(plugin); plugin->destroy(plugin); ``` -------------------------------- ### Declare Plugin Features (Audio Processor) Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md List the capabilities of a plugin using the features array in the plugin descriptor. This example shows an audio processor. ```c // Audio processor const char *const features[] = { "audio-effect", "compressor", "analyzer", NULL }; ``` -------------------------------- ### Enumerate Plugins in DSO Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Scans the loaded DSO to get the count of available plugins and retrieves their descriptors. This metadata is stored by the host for UI display. ```c // Enumerate all plugins in the DSO uint32_t plugin_count = factory->get_plugin_count(factory); for (uint32_t i = 0; i < plugin_count; ++i) { const clap_plugin_descriptor_t *desc = factory->get_plugin_descriptor(factory, i); // Host stores plugin metadata for later UI/menu display host_register_plugin(desc); } ``` -------------------------------- ### Start Audio Processing Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-interface.md Initiates audio processing on the audio thread. Must be called after activation and before any process() calls. Ensures real-time safety and transitions the plugin to the processing state. Can fail if audio thread safety requirements are not met. ```c if (plugin->activate(plugin, 48000, 256, 4096)) { if (!plugin->start_processing(plugin)) { plugin->deactivate(plugin); return false; } } ``` -------------------------------- ### Get Parameter Information Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/params-extension.md Retrieves detailed information about a specific parameter using its index. This function is called during plugin scanning and parameter display setup. ```c bool get_info(const clap_plugin_t *plugin, uint32_t param_index, clap_param_info_t *param_info) ``` ```c clap_param_info_t info = {0}; if (params_ext->get_info(plugin, 0, &info)) { printf("Parameter: %s (ID: %u, default: %.2f)\n", info.name, info.id, info.default_value); } ``` -------------------------------- ### Plugin Factory Configuration and Usage Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Demonstrates how to access the plugin factory, query the number of available plugins, retrieve plugin descriptors, and create plugin instances. ```c // Factory ID used with entry->get_factory() #define CLAP_PLUGIN_FACTORY_ID "clap.plugin-factory" // Factory provides: const clap_plugin_factory_t *factory = entry->get_factory(CLAP_PLUGIN_FACTORY_ID); // Query available plugins uint32_t plugin_count = factory->get_plugin_count(factory); // Get plugin descriptor const clap_plugin_descriptor_t *descriptor = factory->get_plugin_descriptor(factory, index); // Create plugin instance const clap_plugin_t *plugin = factory->create_plugin(factory, host, descriptor->id); ``` -------------------------------- ### Querying Host Extensions in Plugin Initialization Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/host-interface.md Demonstrates how a plugin can query for and use host extensions during its initialization phase. This includes obtaining pointers to extension-specific function tables. ```c void plugin_init(const clap_plugin_t *plugin) { clap_host_t *host = (clap_host_t *)plugin->get_host_pointer(); // Query log extension const clap_host_log_t *log = (const clap_host_log_t *)host->get_extension(host, CLAP_EXT_LOG); if (log) { log->log(host, CLAP_LOG_INFO, "Plugin init"); } // Query params extension for parameter management const clap_host_params_t *params_ext = (const clap_host_params_t *)host->get_extension(host, CLAP_EXT_PARAMS); // ... etc ... } ``` -------------------------------- ### Instantiate a Plugin Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Creates an instance of a selected plugin from the factory. The plugin must be successfully initialized after creation. ```c // When user selects a plugin, create an instance const clap_plugin_t *plugin = factory->create_plugin(factory, host, selected_plugin_id); if (!plugin || !plugin->init(plugin)) { printf("Failed to create plugin\n"); return; } // Plugin is now ready for use ``` -------------------------------- ### Typical Host Integration Flow Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/host-interface.md A general overview of the typical integration flow between a host and a plugin in the CLAP framework, including plugin creation, initialization, and extension querying. ```c // Host creates plugin instance clap_plugin_t *plugin = factory->create_plugin(factory, host, plugin_id); if (!plugin) return; // Host passes itself to plugin initialization if (!plugin->init(plugin)) { plugin->destroy(plugin); return; } // During init, plugin can query host extensions void plugin_init(const clap_plugin_t *plugin) { clap_host_t *host = (clap_host_t *)plugin->get_host_pointer(); // Query log extension const clap_host_log_t *log = (const clap_host_log_t *)host->get_extension(host, CLAP_EXT_LOG); if (log) { log->log(host, CLAP_LOG_INFO, "Plugin init"); } // Query params extension for parameter management const clap_host_params_t *params_ext = (const clap_host_params_t *)host->get_extension(host, CLAP_EXT_PARAMS); // ... etc ... } // Plugin requests services during execution void plugin_process(const clap_plugin_t *plugin, const clap_process_t *process) { clap_host_t *host = get_host(); // If plugin state changed, request restart if (state_changed) { host->request_restart(host); } // If plugin needs GUI update, request callback if (param_changed) { host->request_callback(host); } } ``` -------------------------------- ### Feature Strings for Filter Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Example of how to define feature strings for a filter plugin. The array must be NULL-terminated. ```c // Filter example const char *const filter_features[] = { "audio-effect", "filter", NULL }; ``` -------------------------------- ### init() Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-interface.md Initializes the plugin instance after creation. This is where parameter initialization and buffer allocation should occur. The plugin transitions from an uninitialized to a deactivated state upon successful initialization. ```APIDOC ## init() ### Description Initializes the plugin instance. This function is called after the plugin has been created from a factory. The host has full access to extensions at this point. Plugin setup, such as parameter initialization and buffer allocation, should be performed here. ### Method `bool init(const struct clap_plugin *plugin)` ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c const clap_plugin_t *plugin = factory->create_plugin(factory, host, plugin_id); if (!plugin || !plugin->init(plugin)) { return NULL; // Initialization failed } ``` ### Response #### Success Response - **bool**: `true` on success; `false` on failure. #### Response Example N/A ### Notes - Called after plugin creation from factory. - Host has full access to extensions at this point. - Plugin setup (parameter initialization, buffer allocation) should occur here rather than in factory->create_plugin(). - Plugin transitions from uninitialized to deactivated state on success. ### Thread Context [main-thread] ``` -------------------------------- ### Get Audio Port Information Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/audio-ports-extension.md Retrieves detailed information about a specific audio port by its index and direction. ```c bool get(const clap_plugin_t *plugin, uint32_t index, bool is_input, clap_audio_port_info_t *info) ``` ```c clap_audio_port_info_t port_info = {0}; if (audio_ports->get(plugin, 0, false, &port_info)) { printf("Output port 0: %s (%u channels) ", port_info.name, port_info.channel_count); } ``` -------------------------------- ### Accessing Host and Plugin Extensions in C Source: https://github.com/free-audio/clap/blob/main/README.md Demonstrates how to retrieve and use host and plugin extensions. The host extension is used for logging, while the plugin extension is used to count parameters. ```C // host extension const clap_host_log *log = host->extension(host, CLAP_EXT_LOG); if (log) log->log(host, CLAP_LOG_INFO, "Hello World! ;^)"); // plugin extension const clap_plugin_params *params = plugin->extension(plugin, CLAP_EXT_PARAMS); if (params) { uint32_t paramsCount = params->count(plugin); // ... } ``` -------------------------------- ### Feature Strings for Audio Effect Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Example of how to define feature strings for an audio effect plugin. The array must be NULL-terminated. ```c // Audio effect example const char *const effect_features[] = { "audio-effect", "delay", "reverb", NULL }; ``` -------------------------------- ### Event Handling Source: https://github.com/free-audio/clap/blob/main/_autodocs/COMPLETION_SUMMARY.txt Demonstrates how to handle various events within the audio processing loop. ```c typedef struct clap_event { uint16_t type; uint32_t flags; // ... other fields } clap_event_t; // ... event processing logic ... ``` -------------------------------- ### Thread Safety Annotations Source: https://github.com/free-audio/clap/blob/main/_autodocs/COMPLETION_SUMMARY.txt Examples of CLAP's thread safety annotations used to specify thread context for functions and methods. ```c // [main-thread] annotation for functions that must only be called on the main thread. // [audio-thread] annotation for functions that can be called on the audio thread. // [thread-safe] annotation for functions that can be called from any thread. ``` -------------------------------- ### Get Total Parameter Count Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/params-extension.md Retrieves the total number of parameters available in the plugin. This is useful for iterating through all parameters using their indices. ```c uint32_t count(const clap_plugin_t *plugin) ``` ```c const clap_plugin_params_t *params_ext = plugin->get_extension(plugin, CLAP_EXT_PARAMS); if (params_ext) { uint32_t param_count = params_ext->count(plugin); for (uint32_t i = 0; i < param_count; ++i) { // Get info for parameter i } } ``` -------------------------------- ### Initialize Host Metadata Structure Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md This snippet shows how to initialize the clap_host_t structure with essential host information. Required fields include name and vendor, while URL and version are optional. ```c clap_host_t host = { .clap_version = CLAP_VERSION_INIT, // Required .name = "Bitwig Studio", .vendor = "Bitwig GmbH", // Optional .url = "https://bitwig.com", .version = "4.3.0", }; ``` -------------------------------- ### Extended Audio Port Types Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/audio-ports-extension.md Illustrates examples of extended audio port types defined in other extensions, such as surround sound and ambisonic audio. ```c // From surround.h CLAP_PORT_SURROUND[channel_config] // From ambisonic.h CLAP_PORT_AMBISONIC[order_and_norm] ``` -------------------------------- ### init() Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-entry.md Initializes the CLAP plugin DSO. This function must be called before any other CLAP functions from the DSO. It handles the plugin's initialization and can be called multiple times. ```APIDOC ## Functions ### init() ```c bool init(const char *plugin_path) ``` **Thread context:** May be called on any thread, but never simultaneously with itself or any other CLAP function from this DSO. **Parameters:** | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plugin_path | const char* | yes | Path to the DSO (Linux/Windows) or bundle (macOS) | **Returns:** true on success or if already initialized; false if initialization failed. If false is returned, the host must not call deinit() or any other CLAP symbol from this DSO. **Notes:** - Must be called first before any other CLAP function from this DSO - Should be fast to allow quick plugin scanning - Cannot display graphical user interfaces - Cannot perform user interaction - The DSO may be initialized multiple times in a single process (e.g., host + wrapper both loading it); implementations must handle reference counting as of CLAP 1.2.0 **Example:** ```c const clap_plugin_entry_t *entry = &clap_entry; if (!entry->init("/usr/lib/clap/my-plugin.clap")) return NULL; // Initialization failed ``` ``` -------------------------------- ### Recommended Plugin Descriptor Initialization Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Initializes a static CLAP plugin descriptor with required and recommended fields. Features can be specified using an array of strings. ```c static const clap_plugin_descriptor_t my_plugin_descriptor = { .clap_version = CLAP_VERSION_INIT, // Required .id = "com.example.my-synth", .name = "My Synthesizer", // Recommended .vendor = "Example Inc.", .url = "https://example.com/my-synth", .manual_url = "https://example.com/my-synth/manual", .support_url = "https://example.com/support", .version = "1.0.0", .description = "A powerful polyphonic synthesizer", // Features .features = (const char *[]){ "instrument", "synthesizer", "mono", "poly", NULL }, }; ``` -------------------------------- ### Get Current Parameter Value Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/params-extension.md Queries the current numeric value of a parameter using its ID. This is used by the host for display and state saving. ```c bool get_value(const clap_plugin_t *plugin, clap_id param_id, double *out_value) ``` ```c double current_volume; if (params_ext->get_value(plugin, PARAM_ID_VOLUME, ¤t_volume)) { printf("Volume: %.2f dB\n", current_volume); } ``` -------------------------------- ### Get Parameter Count Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Implement the count function to declare the total number of parameters the plugin exposes. This is a required callback for the params extension. ```c uint32_t count(const clap_plugin_t *plugin) { return 42; // Example: 42 parameters } ``` -------------------------------- ### Stereo Effect Plugin Audio Ports Get Implementation Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/audio-ports-extension.md Implements the audio_ports_get function to provide the details for the defined input and output ports. ```c bool audio_ports_get(const clap_plugin_t *plugin, uint32_t index, bool is_input, clap_audio_port_info_t *info) { if (index != 0) return false; *info = is_input ? input_port : output_port; return true; } ``` -------------------------------- ### start_processing Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-interface.md Initializes the plugin for audio processing on the audio thread. It transitions the plugin to a processing state and should be called before any `process()` calls. This function is designed for real-time-safe initialization. ```APIDOC ## start_processing() ### Description Initializes the plugin for audio processing on the audio thread. It transitions the plugin to a processing state and should be called before any `process()` calls. This function is designed for real-time-safe initialization. ### Method `bool start_processing(const struct clap_plugin *plugin)` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - **plugin** (`clap_plugin_t*`) - Plugin instance ### Returns - `bool` - true on success; false on failure ### Notes - Called on audio thread before any process() calls - Transitions plugin to processing state - Used for real-time-safe initialization in audio thread - May fail if audio thread safety requirements cannot be met ### Request Example ```c if (plugin->activate(plugin, 48000, 256, 4096)) { if (!plugin->start_processing(plugin)) { plugin->deactivate(plugin); return false; } } ``` ### Response #### Success Response (true) - N/A #### Response Example - N/A ``` -------------------------------- ### CLAP Plugin Entry Interface Source: https://github.com/free-audio/clap/blob/main/_autodocs/COMPLETION_SUMMARY.txt Documentation for the plugin entry point, including the `clap_plugin_entry_t` structure and its associated functions like `init`, `deinit`, and `get_factory`. ```APIDOC ## CLAP Plugin Entry Interface ### Description Documentation for the plugin entry point, including the `clap_plugin_entry_t` structure and its associated functions like `init`, `deinit`, and `get_factory`. ### Structure `clap_plugin_entry_t` ### Functions - **init()** [main-thread]: Initializes the plugin entry. - **deinit()** [main-thread]: Deinitializes the plugin entry. - **get_factory()** [thread-safe]: Retrieves the plugin factory. ### Global Symbol `Global clap_entry` ### Loading Sequence Details on the plugin loading sequence. ``` -------------------------------- ### CLAP Plugin Latency Structure Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/render-latency-extensions.md Defines the structure for the plugin's latency extension, containing a function pointer to get the current latency. ```c typedef struct clap_plugin_latency { uint32_t(CLAP_ABI *get)(const clap_plugin_t *plugin); } clap_plugin_latency_t; ``` -------------------------------- ### Typical CLAP Process Implementation Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/audio-processing.md A standard implementation of the process function for a CLAP plugin. It handles input events and renders audio in chunks based on event timing. ```c clap_process_status process(const clap_plugin_t *plugin, const clap_process_t *process) { plugin_t *self = (plugin_t *)plugin->plugin_data; // Get transport info if available const clap_event_transport_t *transport = process->transport; bool is_playing = transport && (transport->flags & CLAP_TRANSPORT_IS_PLAYING); // Process input events uint32_t event_index = 0; uint32_t next_event_sample = 0; const clap_event_header_t *event = process->in_events->get(process->in_events, event_index); // Process samples in chunks divided by events for (uint32_t sample = 0; sample < process->frames_count;) { // Process events up to next sample while (event && event->time == sample) { handle_event(self, event); event = process->in_events->get(process->in_events, ++event_index); } // Determine samples until next event uint32_t samples_to_process = event ? event->time : process->frames_count; samples_to_process -= sample; // Render audio render_audio(self, process->audio_outputs, sample, samples_to_process); sample += samples_to_process; } return CLAP_PROCESS_CONTINUE; } ``` -------------------------------- ### Declare Plugin Features (Synthesizer) Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md List the capabilities of a plugin using the features array in the plugin descriptor. This example shows a synthesizer with built-in effects. ```c // Synthesizer with built-in effects const char *const features[] = { "instrument", "synthesizer", "mono", "filter", "delay", NULL // Must be NULL-terminated }; ``` -------------------------------- ### Plugin ID Naming Convention Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Use a reverse domain notation for plugin IDs to ensure global uniqueness. Examples show the recommended pattern. ```c // Pattern: com.vendor.productname const char *id = "com.bitwig.studio.sampler"; const char *id = "org.freeplugs.wavetable"; const char *id = "de.merzpost.filter"; ``` -------------------------------- ### CLAP Plugin Lifecycle and Processing Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-interface.md Demonstrates the typical lifecycle of a CLAP plugin, from creation and activation to audio processing and cleanup. Ensure proper error handling and resource management. ```c const clap_plugin_t *plugin = factory->create_plugin(factory, host, plugin_id); if (!plugin || !plugin->init(plugin)) { return; } if (!plugin->activate(plugin, 48000.0, 256, 4096)) { plugin->destroy(plugin); return; } if (!plugin->start_processing(plugin)) { plugin->deactivate(plugin); plugin->destroy(plugin); return; } clap_process_t process = {0}; process.frames_count = 256; process.audio_inputs = audio_in; process.audio_outputs = audio_out; // ... fill in other fields clap_process_status status = plugin->process(plugin, &process); plugin->stop_processing(plugin); plugin->deactivate(plugin); plugin->destroy(plugin); ``` -------------------------------- ### Querying Latency During Activation Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/render-latency-extensions.md Demonstrates how a plugin can query its own latency from the host during the activation phase. This is useful for plugins that need to know their latency before processing audio. ```c bool plugin_activate(const clap_plugin_t *plugin, double sample_rate, uint32_t min_frames, uint32_t max_frames) { plugin_t *self = (plugin_t *)plugin->plugin_data; // During activation, query latency if needed const clap_plugin_latency_t *latency_ext = plugin->get_extension(plugin, CLAP_EXT_LATENCY); if (latency_ext) { uint32_t plugin_latency = latency_ext->get(plugin); printf("Plugin latency: %u samples\n", plugin_latency); } return true; } ``` -------------------------------- ### Get Plugin Latency Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/render-latency-extensions.md Function to retrieve the current audio latency introduced by the plugin in samples. This value must remain constant while the plugin is active. ```c uint32_t get(const clap_plugin_t *plugin) ``` -------------------------------- ### request_process Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/host-interface.md Requests the host to activate the plugin and begin processing. This is useful for plugins that need to wake up from an idle state or handle external I/O. ```APIDOC ## request_process() ### Description Requests the host to activate the plugin and begin processing. This is useful for plugins that need to wake up from an idle state or handle external I/O. ### Signature ```c void request_process(const struct clap_host *host) ``` ### Parameters #### Path Parameters - **host** (clap_host_t*) - Required - Host instance ### Notes - Plugin requests the host to activate it and begin processing. - Used if plugin has external I/O or needs to "wake up" from sleep state. - Operation may be delayed by the host. - Useful for plugins that monitor hardware input or MIDI controllers. - Can be called from any thread. ### Use Cases - Hardware synthesizer with external MIDI input - Plugin monitoring control surface changes - Waking up idle processing to handle external events ### Example ```c // Plugin monitoring hardware MIDI input and needs processing void handle_hardware_midi_input(const clap_plugin_t *plugin) { const clap_host_t *host = get_host_from_plugin(plugin); host->request_process(host); // Host will eventually call plugin->activate() and process() } ``` ``` -------------------------------- ### Get Host Extension Interface Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/host-interface.md Retrieve a pointer to a specific host extension interface. Check for NULL if the extension is not implemented by the host. This can be called from any thread. ```c const void* get_extension(const struct clap_host *host, const char *extension_id) ``` ```c const clap_host_log_t *log_ext = (const clap_host_log_t *)host->get_extension(host, CLAP_EXT_LOG); if (log_ext) { log_ext->log(host, CLAP_LOG_INFO, "Plugin initialized"); } ``` -------------------------------- ### Get Plugin Factory Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/plugin-entry.md Retrieves a factory by its ID. This function is thread-safe and can be called at any time after init(). It returns a pointer to the factory or NULL if the factory is not implemented. ```c const void* get_factory(const char *factory_id) ``` ```c const clap_plugin_factory_t *factory = (const clap_plugin_factory_t *)entry->get_factory(CLAP_PLUGIN_FACTORY_ID); if (factory) { uint32_t count = factory->get_plugin_count(factory); } ``` -------------------------------- ### Plugin Lifecycle Sequences Source: https://github.com/free-audio/clap/blob/main/_autodocs/COMPLETION_SUMMARY.txt Outlines the typical sequence of events during a plugin's lifecycle, from initialization to destruction. ```c // Initialization -> Activation -> Processing -> Deactivation -> Destruction ``` -------------------------------- ### Configure GUI Window API and Size Source: https://github.com/free-audio/clap/blob/main/_autodocs/configuration.md Declare support for a user interface and specify preferred window API and size constraints. This is for plugins with GUIs. ```c // Preferred window API const char *preferred_api = CLAP_WINDOW_API_WIN32; // or COCOA, X11, etc. bool is_floating = false; // Embedded window preferred // Size constraints bool can_resize = true; uint32_t width = 800; uint32_t height = 600; ``` -------------------------------- ### CLAP Plugin Note Ports Structure Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/note-ports-extension.md Defines the structure for the CLAP note ports extension, including functions to count and get note port information. ```c typedef struct clap_plugin_note_ports { uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input); bool(CLAP_ABI *get)(const clap_plugin_t *plugin, uint32_t index, bool is_input, clap_note_port_info_t *info); } clap_plugin_note_ports_t; ``` -------------------------------- ### Create Interface Library for CLAP Source: https://github.com/free-audio/clap/blob/main/CMakeLists.txt Defines an INTERFACE library target named 'clap'. This is used when CLAP is a submodule of a plugin, providing include directories for build and installation. ```cmake add_library(clap INTERFACE) target_include_directories(clap INTERFACE $ $) ``` -------------------------------- ### Using Note Ports Rescan in CLAP Host Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/note-ports-extension.md Demonstrates how a host can retrieve and use the note ports extension to trigger rescans for different configuration changes. ```c clap_host_note_ports_t *note_ports = (clap_host_note_ports_t *)host->get_extension(host, CLAP_EXT_NOTE_PORTS); if (note_ports) { // Rename a port note_ports->rescan(host, CLAP_NOTE_PORTS_RESCAN_NAMES); // Change port list note_ports->rescan(host, CLAP_NOTE_PORTS_RESCAN_LIST); } ``` -------------------------------- ### Typical CLAP Plugin State Save/Load Implementation in C Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/state-extension.md This C code demonstrates a typical implementation for saving and loading a CLAP plugin's state. It includes functions for writing plugin data to an output stream and reading it back from an input stream, with header validation and parameter handling. ```c typedef struct { uint32_t magic; uint32_t version; uint32_t param_count; } save_header_t; #define MAGIC 0x4D5950XX bool plugin_save(const clap_plugin_t *plugin, const clap_ostream_t *stream) { plugin_t *self = (plugin_t *)plugin->plugin_data; save_header_t header = { .magic = MAGIC, .version = 1, .param_count = self->param_count, }; if (stream->write(stream, &header, sizeof(header)) != sizeof(header)) return false; for (uint32_t i = 0; i < self->param_count; ++i) { double value = self->params[i].value; if (stream->write(stream, &value, sizeof(value)) != sizeof(value)) return false; } if (stream->write(stream, &self->dsp_state, sizeof(self->dsp_state)) != sizeof(self->dsp_state)) return false; return true; } bool plugin_load(const clap_plugin_t *plugin, const clap_istream_t *stream) { plugin_t *self = (plugin_t *)plugin->plugin_data; save_header_t header; if (stream->read(stream, &header, sizeof(header)) != sizeof(header)) return false; if (header.magic != MAGIC) return false; if (header.version != 1) return false; if (header.param_count != self->param_count) return false; for (uint32_t i = 0; i < self->param_count; ++i) { double value; if (stream->read(stream, &value, sizeof(value)) != sizeof(value)) return false; if (value < self->params[i].min || value > self->params[i].max) return false; self->params[i].value = value; } if (stream->read(stream, &self->dsp_state, sizeof(self->dsp_state)) != sizeof(self->dsp_state)) return false; return true; } ``` -------------------------------- ### create_plugin Source: https://github.com/free-audio/clap/blob/main/_autodocs/api-reference/factory.md Instantiates a new plugin instance based on its ID. The host must then initialize the created plugin. ```APIDOC ## create_plugin ### Description Creates a new plugin instance. ### Method `const clap_plugin_t *create_plugin(const clap_plugin_factory_t *factory, const clap_host_t *host, const char *plugin_id)` ### Parameters #### Factory Instance - **factory** (clap_plugin_factory_t*) - Factory instance. #### Host Instance - **host** (clap_host_t*) - Host instance (plugin stores and uses this). #### Plugin ID - **plugin_id** (const char*) - Plugin ID from `clap_plugin_descriptor_t.id`. ### Returns - `const clap_plugin_t*` - Plugin instance pointer, or NULL if plugin_id not found or creation failed. ### Notes - Creates a new plugin instance. - Plugin is in uninitialized state; host must call `plugin->init()`. - Factory passes host pointer to plugin. - Plugin stores host for later communication. - Return value must not be freed by factory. - One plugin instance per call. ### Example ```c const clap_plugin_factory_t *factory = (const clap_plugin_factory_t *)entry->get_factory(CLAP_PLUGIN_FACTORY_ID); clap_host_t host = { .clap_version = CLAP_VERSION_INIT, .name = "My DAW", .vendor = "My Company", .version = "1.0.0", .get_extension = host_get_extension, .request_restart = host_request_restart, .request_process = host_request_process, .request_callback = host_request_callback, }; const clap_plugin_t *plugin = factory->create_plugin(factory, &host, "com.example.my-plugin"); if (plugin) { if (!plugin->init(plugin)) { printf("Plugin initialization failed\n"); // Host will call plugin->destroy() in its error handler } else { printf("Plugin created and initialized\n"); } } else { printf("Plugin creation failed\n"); } ``` ```