1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
/*
* Copyright (C) 2022 Linux Studio Plugins Project <https://lsp-plug.in/>
* (C) 2022 Vladimir Sadovnikov <sadko4u@gmail.com>
*
* This file is part of lsp-plugin-fw
* Created on: 24 дек. 2022 г.
*
* lsp-plugin-fw is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* lsp-plugin-fw is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with lsp-plugin-fw. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LSP_PLUG_IN_PLUG_FW_WRAP_CLAP_WRAPPER_H_
#define LSP_PLUG_IN_PLUG_FW_WRAP_CLAP_WRAPPER_H_
#include <lsp-plug.in/plug-fw/version.h>
#include <clap/clap.h>
#include <lsp-plug.in/common/status.h>
#include <lsp-plug.in/ipc/Mutex.h>
#include <lsp-plug.in/lltl/parray.h>
#include <lsp-plug.in/plug-fw/core/SamplePlayer.h>
#include <lsp-plug.in/plug-fw/meta/manifest.h>
#include <lsp-plug.in/plug-fw/wrap/clap/extensions.h>
#include <lsp-plug.in/plug-fw/wrap/clap/helpers.h>
#include <lsp-plug.in/plug-fw/wrap/clap/ports.h>
#include <lsp-plug.in/plug-fw/wrap/clap/ui_wrapper.h>
#include <lsp-plug.in/plug-fw/plug.h>
namespace lsp
{
namespace clap
{
class UIWrapper;
/**
* CLAP plugin wrapper interface
*/
class Wrapper: public plug::IWrapper
{
protected:
typedef struct audio_group_t
{
meta::port_group_type_t nType; // Type of the group (MONO, STEREO, etc)
size_t nFlags; // Flags to return to the CLAP host
ssize_t nInPlace; // CLAP host optimizations: in-place pair
const char *sName; // Pointer to the group name
size_t nPorts; // Number of ports in the group
AudioPort *vPorts[]; // List of ports in the audio port group
} audio_group_t;
protected:
const clap_host_t *pHost; // Host interface
const meta::package_t *pPackage; // Package metadata
const meta::plugin_t *pUIMetadata; // UI metadata
void *pUIFactory; // UI factory
clap::UIWrapper *pUIWrapper; // UI wrapper
clap::HostExtensions *pExt; // CLAP Extensions
ipc::IExecutor *pExecutor; // Executor service
ssize_t nLatency; // The actual plugin latency
uatomic_t nDumpReq; // State dump request counter
uatomic_t nDumpResp; // State dump response counter
lltl::parray<audio_group_t> vAudioIn; // Input audio ports
lltl::parray<audio_group_t> vAudioOut; // Output audio ports
lltl::parray<ParameterPort> vParamPorts; // List of parameters sorted by clap_id
lltl::parray<MidiInputPort> vMidiIn; // Midi input ports
lltl::parray<MidiOutputPort> vMidiOut; // Midi output ports
lltl::parray<clap::Port> vAllPorts; // List of all available ports
lltl::parray<clap::Port> vSortedPorts; // List of ports sorted by metadata identifier
lltl::parray<meta::port_t> vGenMetadata; // Generated metadata for virtual ports
core::KVTStorage sKVT; // KVT storage
ipc::Mutex sKVTMutex; // KVT storage access mutex
bool bUIActive; // UI is active
bool bRestartRequested; // Flag that indicates that the plugin restart was requested
bool bUpdateSettings; // Trigger settings update for the nearest run
core::SamplePlayer *pSamplePlayer; // Sample player
protected:
static audio_group_t *alloc_audio_group(size_t ports);
static audio_group_t *create_audio_group(
const meta::port_group_t *meta,
lltl::parray<plug::IPort> * ins,
lltl::parray<plug::IPort> * outs);
static audio_group_t *create_audio_group(plug::IPort *port);
static void destroy_audio_group(audio_group_t *grp);
static plug::IPort *find_port(const char *id, lltl::parray<plug::IPort> *list);
static ssize_t compare_ports_by_clap_id(const ParameterPort *a, const ParameterPort *b);
static ssize_t compare_ports_by_id(const clap::Port *a, const clap::Port *b);
static status_t read_value(const clap_istream_t *is, const char *name, core::kvt_param_t *p);
static void destroy_value(core::kvt_param_t *p);
protected:
void lookup_ui_factory();
void create_port(lltl::parray<plug::IPort> *plugin_ports, const meta::port_t *port, const char *postfix);
status_t create_ports(lltl::parray<plug::IPort> *plugin_ports, const meta::plugin_t *meta);
status_t generate_audio_port_groups(const meta::plugin_t *meta);
clap::ParameterPort *find_param(clap_id param_id);
size_t prepare_block(size_t *ev_index, size_t offset, const clap_process_t *process);
void generate_output_events(size_t offset, const clap_process_t *process);
public:
explicit Wrapper(
plug::Module *module,
const meta::package_t *package,
resource::ILoader *loader,
const clap_host_t *host);
virtual ~Wrapper() override;
public:
// CLAP public API functions
status_t init();
void destroy();
status_t activate(double sample_rate, size_t min_frames_count, size_t max_frames_count);
void deactivate();
status_t start_processing();
void stop_processing();
void reset();
clap_process_status process(const clap_process_t *process);
const void *get_extension(const char *id);
void on_main_thread();
public:
// CLAP parameter extension
size_t params_count() const;
status_t param_info(clap_param_info_t *info, size_t index);
status_t get_param_value(double *value, clap_id param_id);
status_t format_param_value(char *buffer, size_t buf_size, clap_id param_id, double value);
status_t parse_param_value(double *value, clap_id param_id, const char *text);
void flush_param_events(const clap_input_events_t *in, const clap_output_events_t *out);
public:
// CLAP latency extension
size_t latency() const;
public:
// CLAP audio port extension
size_t audio_ports_count(bool is_input) const;
status_t audio_port_info(clap_audio_port_info_t *info, size_t index, bool is_input) const;
public:
// CLAP note port extension
size_t has_note_ports() const;
size_t note_ports_count(bool is_input) const;
status_t note_port_info(clap_note_port_info_t *info, size_t index, bool is_input) const;
public:
// CLAP state extension
status_t save_state(const clap_ostream_t *os);
status_t load_state(const clap_istream_t *is);
public:
// plug::IWrapper methods
virtual ipc::IExecutor *executor() override;
virtual core::KVTStorage *kvt_lock() override;
virtual core::KVTStorage *kvt_trylock() override;
virtual bool kvt_release() override;
virtual const meta::package_t *package() const override;
virtual void state_changed() override;
public:
// Miscellaneous functions
clap::Port *find_by_id(const char *id);
inline core::SamplePlayer *sample_player();
void request_state_dump();
inline UIWrapper *ui_wrapper();
UIWrapper *create_ui();
void destroy_ui();
inline HostExtensions *extensions();
bool ui_provided();
};
} /* namespace clap */
} /* namespace lsp */
#endif /* LSP_PLUG_IN_PLUG_FW_WRAP_CLAP_WRAPPER_H_ */
|