Rename a pipe method, add docs
[carla.git] / source / utils / CarlaClapUtils.hpp
bloba7a08c90a11b2878431b30aa490fa28f9c7a49a7
1 /*
2 * Carla CLAP utils
3 * Copyright (C) 2022 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_CLAP_UTILS_HPP_INCLUDED
19 #define CARLA_CLAP_UTILS_HPP_INCLUDED
21 #include "CarlaBackend.h"
22 #include "CarlaUtils.hpp"
24 #include "clap/entry.h"
25 #include "clap/plugin-factory.h"
26 #include "clap/plugin-features.h"
27 #include "clap/ext/audio-ports.h"
28 #include "clap/ext/latency.h"
29 #include "clap/ext/gui.h"
30 #include "clap/ext/note-ports.h"
31 #include "clap/ext/params.h"
32 #include "clap/ext/posix-fd-support.h"
33 #include "clap/ext/state.h"
34 #include "clap/ext/timer-support.h"
36 #if defined(CARLA_OS_WIN)
37 # define CLAP_WINDOW_API_NATIVE CLAP_WINDOW_API_WIN32
38 #elif defined(CARLA_OS_MAC)
39 # define CLAP_WINDOW_API_NATIVE CLAP_WINDOW_API_COCOA
40 #elif defined(HAVE_X11)
41 # define CLAP_WINDOW_API_NATIVE CLAP_WINDOW_API_X11
42 #endif
44 // --------------------------------------------------------------------------------------------------------------------
46 extern "C" {
48 typedef struct clap_audio_buffer_const {
49 const float* const* data32;
50 const double* const* data64;
51 uint32_t channel_count;
52 uint32_t latency;
53 uint64_t constant_mask;
54 } clap_audio_buffer_const_t;
56 typedef struct clap_audio_buffer_extra_data {
57 uint16_t offset;
58 bool isMain;
59 } clap_audio_buffer_extra_data_t;
63 // --------------------------------------------------------------------------------------------------------------------
65 CARLA_BACKEND_START_NAMESPACE
67 // --------------------------------------------------------------------------------------------------------------------
69 static inline
70 PluginCategory getPluginCategoryFromClapFeatures(const char* const* const features) noexcept
72 // 1st pass for main categories
73 for (uint32_t i=0; features[i] != nullptr; ++i)
75 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_INSTRUMENT) == 0)
76 return PLUGIN_CATEGORY_SYNTH;
77 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_NOTE_EFFECT) == 0)
78 return PLUGIN_CATEGORY_UTILITY;
79 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_ANALYZER) == 0)
80 return PLUGIN_CATEGORY_UTILITY;
83 // 2nd pass for FX sub categories
85 #define CLAP_PLUGIN_FEATURE_DEESSER "de-esser"
86 #define CLAP_PLUGIN_FEATURE_PHASE_VOCODER "phase-vocoder"
87 #define CLAP_PLUGIN_FEATURE_GRANULAR "granular"
88 #define CLAP_PLUGIN_FEATURE_FREQUENCY_SHIFTER "frequency-shifter"
89 #define CLAP_PLUGIN_FEATURE_PITCH_SHIFTER "pitch-shifter"
90 #define CLAP_PLUGIN_FEATURE_TREMOLO "tremolo"
91 #define CLAP_PLUGIN_FEATURE_GLITCH "glitch"
93 for (uint32_t i=0; features[i] != nullptr; ++i)
95 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_DELAY) == 0 ||
96 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_REVERB) == 0)
98 return PLUGIN_CATEGORY_DELAY;
100 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_EQUALIZER) == 0)
102 return PLUGIN_CATEGORY_EQ;
104 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_FILTER) == 0)
106 return PLUGIN_CATEGORY_FILTER;
108 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_DISTORTION) == 0)
110 return PLUGIN_CATEGORY_DISTORTION;
112 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_COMPRESSOR) == 0 ||
113 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_LIMITER) == 0 ||
114 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_MASTERING) == 0 ||
115 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_MIXING) == 0 ||
116 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_TRANSIENT_SHAPER) == 0)
118 return PLUGIN_CATEGORY_DYNAMICS;
120 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_CHORUS) == 0 ||
121 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_FLANGER) == 0 ||
122 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_PHASER) == 0
125 return PLUGIN_CATEGORY_MODULATOR;
127 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_PITCH_CORRECTION) == 0 ||
128 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_RESTORATION) == 0 ||
129 std::strcmp(features[i], CLAP_PLUGIN_FEATURE_UTILITY) == 0
132 return PLUGIN_CATEGORY_UTILITY;
136 return PLUGIN_CATEGORY_OTHER;
139 static inline
140 bool clapFeaturesContainInstrument(const char* const* const features) noexcept
142 if (features == nullptr)
143 return false;
145 for (uint32_t i=0; features[i] != nullptr; ++i)
147 if (std::strcmp(features[i], CLAP_PLUGIN_FEATURE_INSTRUMENT) == 0)
148 return true;
151 return false;
154 // --------------------------------------------------------------------------------------------------------------------
156 struct clap_istream_impl : clap_istream_t {
157 const void* buffer;
158 const uint64_t size;
159 uint64_t readPos;
161 clap_istream_impl(const void* const buf, const uint64_t bufsize) noexcept
162 : buffer(buf),
163 size(bufsize),
164 readPos(0)
166 ctx = this;
167 read = read_impl;
170 static int64_t CLAP_ABI read_impl(const clap_istream_t* const stream, void* const buffer, const uint64_t size) noexcept
172 clap_istream_impl* const self = static_cast<clap_istream_impl*>(stream->ctx);
174 if (const uint64_t bytesRead = std::min(self->size - self->readPos, size))
176 std::memcpy(buffer, static_cast<const uint8_t*>(self->buffer) + self->readPos, bytesRead);
177 self->readPos += bytesRead;
178 return bytesRead;
181 return 0;
185 // --------------------------------------------------------------------------------------------------------------------
187 struct clap_ostream_impl : clap_ostream_t {
188 void* buffer;
189 uint64_t size;
191 clap_ostream_impl() noexcept
192 : buffer(nullptr),
193 size(0)
195 ctx = this;
196 write = write_impl;
199 static int64_t CLAP_ABI write_impl(const clap_ostream* const stream, const void* const buffer, const uint64_t size) noexcept
201 CARLA_SAFE_ASSERT_RETURN(size != 0, 0);
203 clap_ostream_impl* const self = static_cast<clap_ostream_impl*>(stream->ctx);
205 void* const oldBuffer = self->buffer;
206 self->buffer = std::realloc(self->buffer, self->size + size);
208 if (self->buffer == nullptr)
210 std::free(oldBuffer);
211 return -1;
214 std::memcpy(static_cast<uint8_t*>(self->buffer) + self->size, buffer, size);
215 self->size += size;
216 return size;
220 // --------------------------------------------------------------------------------------------------------------------
222 CARLA_BACKEND_END_NAMESPACE
224 #endif // CARLA_CLAP_UTILS_HPP_INCLUDED