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
44 // --------------------------------------------------------------------------------------------------------------------
48 typedef struct clap_audio_buffer_const
{
49 const float* const* data32
;
50 const double* const* data64
;
51 uint32_t channel_count
;
53 uint64_t constant_mask
;
54 } clap_audio_buffer_const_t
;
56 typedef struct clap_audio_buffer_extra_data
{
59 } clap_audio_buffer_extra_data_t
;
63 // --------------------------------------------------------------------------------------------------------------------
65 CARLA_BACKEND_START_NAMESPACE
67 // --------------------------------------------------------------------------------------------------------------------
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
;
140 bool clapFeaturesContainInstrument(const char* const* const features
) noexcept
142 if (features
== nullptr)
145 for (uint32_t i
=0; features
[i
] != nullptr; ++i
)
147 if (std::strcmp(features
[i
], CLAP_PLUGIN_FEATURE_INSTRUMENT
) == 0)
154 // --------------------------------------------------------------------------------------------------------------------
156 struct clap_istream_impl
: clap_istream_t
{
161 clap_istream_impl(const void* const buf
, const uint64_t bufsize
) noexcept
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
;
185 // --------------------------------------------------------------------------------------------------------------------
187 struct clap_ostream_impl
: clap_ostream_t
{
191 clap_ostream_impl() noexcept
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
);
214 std::memcpy(static_cast<uint8_t*>(self
->buffer
) + self
->size
, buffer
, size
);
220 // --------------------------------------------------------------------------------------------------------------------
222 CARLA_BACKEND_END_NAMESPACE
224 #endif // CARLA_CLAP_UTILS_HPP_INCLUDED