1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 28 сент. 2015 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef METADATA_METADATA_H_
23 #define METADATA_METADATA_H_
24 
25 #include <core/types.h>
26 #include <core/sugar.h>
27 
28 #define LSP_SITE_URL                                    "https://lsp-plug.in/"
29 #define LSP_BASE_URI                                    "http://lsp-plug.in/"
30 #define LSP_ACRONYM                                     "LSP"
31 #define LSP_PREFIX                                      "lsp"
32 #define LSP_ARTIFACT_ID                                 LSP_PREFIX "-plugins"
33 #define LSP_R3D_BACKEND_PREFIX                          LSP_ARTIFACT_ID "-r3d"
34 #define LSP_BINARY                                      LSP_ARTIFACT_ID
35 #define LSP_FULL_NAME                                   "Linux Studio Plugins Project"
36 #define LSP_COPYRIGHT                                   LSP_ACRONYM " (Linux Studio Plugins)"
37 #define LSP_PLUGIN_NAME(name, description)              LSP_ACRONYM " " name " - " description
38 #define LSP_DEVELOPERS_URI                              LSP_BASE_URI "developers/"
39 #define LSP_URI(format)                                 LSP_BASE_URI "plugins/" #format "/"
40 #define LSP_TYPE_URI(format)                            LSP_BASE_URI "types/" #format
41 #define LSP_UI_URI(format)                              LSP_BASE_URI "ui/" #format "/"
42 #define LSP_KVT_URI                                     LSP_BASE_URI "kvt"
43 #define LSP_PLUGIN_URI(format, plugin)                  LSP_BASE_URI "plugins/" #format "/" #plugin
44 #define LSP_PLUGIN_UI_URI(format, plugin)               LSP_UI_URI(format) #plugin
45 #define LSP_LADSPA_BASE                                 0x4C5350
46 #define LSP_DONATION_URL1                               "https://salt.bountysource.com/teams/" LSP_ARTIFACT_ID
47 #define LSP_DONATION_URL2                               "https://liberapay.com/sadko4u/donate"
48 #define LSP_PLUGINS_MAILBOX                             "lsp.plugin@gmail.com"
49 #define LSP_DOWNLOAD_URI                                LSP_BASE_URI "?page=download"
50 
51 // Different LV2 UI classes for different platforms
52 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
53     #define LSP_LV2UI_CLASS                                 "X11UI"
54 #elif defined(PLATFORM_WINDOWS)
55     #define LSP_LV2UI_CLASS                                 "WindowsUI"
56 #elif defined(PLATFORM_MACOSX)
57     #define LSP_LV2UI_CLASS                                 "CocoaUI"
58 #elif defined(PLATFORM_UNIX_COMPATIBLE)
59     #define LSP_LV2UI_CLASS                                 "X11UI"
60 #else
61     #error "Could not determine LV2 UI class for target platform"
62 #endif
63 
64 #define LSP_VERSION(a, b, c)                            uint32_t(((uint32_t(a) & 0xff) << 16) | ((uint32_t(b) & 0xff) << 8) | (uint32_t(c) & 0xff))
65 #define LSP_VERSION_MAJOR(v)                            (uint32_t(((v) >> 16) & 0xff))
66 #define LSP_VERSION_MINOR(v)                            (uint32_t(((v) >> 8) & 0xff))
67 #define LSP_VERSION_MICRO(v)                            (uint32_t((v) & 0xff))
68 #define LSP_MAX_PARAM_ID_BYTES                          64
69 
70 #if defined(ARCH_I386)
71     #define LSP_ARCHITECTURE                                "i586"
72 #elif defined(ARCH_X86_64)
73     #define LSP_ARCHITECTURE                                "x86_64"
74 #else
75     #define LSP_ARCHITECTURE                                "unknown"
76 #endif /* ARCH */
77 
78 #ifndef LSP_MAIN_VERSION
79     #define LSP_MAIN_VERSION                                "0.0.0"
80 #endif /* LSP_MAIN_VERSION */
81 
82 #define LSP_LV2_LATENCY_PORT                            "out_latency"
83 #define LSP_LV2_ATOM_PORT_IN                            "in_ui"
84 #define LSP_LV2_MIDI_PORT_IN                            "in_midi"
85 #define LSP_LV2_OSC_PORT_IN                             "in_osc"
86 #define LSP_LV2_ATOM_PORT_OUT                           "out_ui"
87 #define LSP_LV2_MIDI_PORT_OUT                           "out_midi"
88 #define LSP_LV2_OSC_PORT_OUT                            "out_osc"
89 
90 #ifdef LSP_INSTALL_PREFIX
91     #define LSP_LIB_PREFIX(x)       LSP_INSTALL_PREFIX x
92 #else
93     #define LSP_LIB_PREFIX(x)       x
94 #endif /* PREFIX */
95 
96 namespace lsp
97 {
98     enum unit_t
99     {
100         U_NONE,                 // Simple value
101 
102         U_BOOL,                 // Boolean: true if > 0.5, false otherwise
103         U_STRING,               // String
104         U_PERCENT,              // Something in percents
105 
106         // Distance
107         U_MM,                   // Millimeters
108         U_CM,                   // Centimeters
109         U_M,                    // Meters
110         U_INCH,                 // Inches
111         U_KM,                   // Kilometers
112 
113         // Speed
114         U_MPS,                  // Meters per second
115         U_KMPH,                 // Kilometers per hour
116 
117         // Samples
118         U_SAMPLES,              // Something in samples
119 
120         // Frequency
121         U_HZ,                   // Hertz
122         U_KHZ,                  // Kilohertz
123         U_MHZ,                  // Megahertz
124         U_BPM,                  // Beats per minute
125         U_CENT,                 // Cents
126         U_OCTAVES,              // Octaves
127         U_SEMITONES,            // Semitones
128 
129         // Time measurement
130         U_BAR,                  // Bars
131         U_BEAT,                 // Beats
132         U_MIN,                  // Minute
133         U_SEC,                  // Seconds
134         U_MSEC,                 // Milliseconds
135 
136         // Level measurement
137         U_DB,                   // Decibels
138         U_GAIN_AMP,             // Gain (amplitude amplification)
139         U_GAIN_POW,             // Gain (power amplification)
140 
141         // Degrees
142         U_DEG,                  // Degrees
143         U_DEG_CEL,              // Degrees (Celsium)
144         U_DEG_FAR,              // Degrees (Fahrenheit)
145         U_DEG_K,                // Degrees (Kelvin)
146         U_DEG_R,                // Degrees (Rankine)
147 
148         // Size units
149         U_BYTES,                // Bytes
150         U_KBYTES,               // Kilobytes
151         U_MBYTES,               // Megabytes
152         U_GBYTES,               // Gigabytes
153         U_TBYTES,               // Terabytes
154 
155         U_ENUM                  // List index
156     };
157 
158     enum role_t
159     {
160         R_UI_SYNC,              // Synchronization with UI
161         R_AUDIO,                // Audio port
162         R_CONTROL,              // Control port
163         R_METER,                // Metering port
164         R_MESH,                 // Mesh port
165         R_FBUFFER,              // Frame buffer
166         R_PATH,                 // Path to the local file
167         R_MIDI,                 // MIDI events
168         R_PORT_SET,             // Set of ports
169         R_OSC,                  // OSC events
170         R_BYPASS,               // Bypass
171         R_STREAM                // Stream
172     };
173 
174     enum flags_t
175     {
176         F_IN            = (0 << 0),     // Input port
177         F_OUT           = (1 << 0),     // Output port
178         F_UPPER         = (1 << 1),     // Upper-limit defined
179         F_LOWER         = (1 << 2),     // Lower-llmit defined
180         F_STEP          = (1 << 3),     // Step defined
181         F_LOG           = (1 << 4),     // Logarithmic scale
182         F_INT           = (1 << 5),     // Integer value
183         F_TRG           = (1 << 6),     // Trigger
184         F_GROWING       = (1 << 7),     // Proportionally growing default value (for port sets)
185         F_LOWERING      = (1 << 8),     // Proportionally lowering default value (for port sets)
186         F_PEAK          = (1 << 9),     // Peak flag
187         F_CYCLIC        = (1 << 10),    // Cyclic flag
188         F_EXT           = (1 << 11),    // Extended range
189     };
190 
191     #define IS_OUT_PORT(p)      ((p)->flags & F_OUT)
192     #define IS_IN_PORT(p)       (!((p)->flags & F_OUT))
193     #define IS_GROWING_PORT(p)  (((p)->flags & (F_GROWING | F_UPPER | F_LOWER)) == (F_GROWING | F_UPPER | F_LOWER))
194     #define IS_LOWERING_PORT(p) (((p)->flags & (F_LOWERING | F_UPPER | F_LOWER)) == (F_LOWERING | F_UPPER | F_LOWER))
195     #define IS_TRIGGER_PORT(p)  ((p)->flags & F_TRG)
196 
197     enum plugin_class_t
198     {
199         C_DELAY,
200             C_REVERB,
201         C_DISTORTION,
202             C_WAVESHAPER,
203         C_DYNAMICS,
204             C_AMPLIFIER,
205             C_COMPRESSOR,
206             C_ENVELOPE,
207             C_EXPANDER,
208             C_GATE,
209             C_LIMITER,
210         C_FILTER,
211             C_ALLPASS,
212             C_BANDPASS,
213             C_COMB,
214             C_EQ,
215                 C_MULTI_EQ,
216                 C_PARA_EQ,
217             C_HIGHPASS,
218             C_LOWPASS,
219         C_GENERATOR,
220             C_CONSTANT,
221             C_INSTRUMENT,
222             C_OSCILLATOR,
223         C_MODULATOR,
224             C_CHORUS,
225             C_FLANGER,
226             C_PHASER,
227         C_SIMULATOR,
228         C_SPATIAL,
229         C_SPECTRAL,
230             C_PITCH,
231         C_UTILITY,
232             C_ANALYSER,
233             C_CONVERTER,
234             C_FUNCTION,
235             C_MIXER
236     };
237 
238     enum plugin_extension_t
239     {
240         E_NONE                  = 0,        // No extensions
241         E_INLINE_DISPLAY        = 1 << 0,   // Supports InlineDisplay extension originally implemented in LV2 plugin format
242         E_3D_BACKEND            = 1 << 1,   // Supports 3D rendering backend
243         E_OSC                   = 1 << 2,   // Supports OSC protocol messaging
244         E_KVT_SYNC              = 1 << 3,   // KVT synchronization required
245         E_DUMP_STATE            = 1 << 4    // Support of internal state dump
246     };
247 
248     enum port_group_type_t
249     {
250         GRP_MONO,                       // Mono
251         GRP_1_0     = GRP_MONO,         // Mono
252         GRP_STEREO,                     // Stereo
253         GRP_2_0     = GRP_STEREO,       // Stereo
254         GRP_2_1     = GRP_STEREO,       // Stereo
255         GRP_MS,                         // Mid-side
256         GRP_3_0,                        // 3.0
257         GRP_4_0,                        // 4.0
258         GRP_5_0,                        // 5.0
259         GRP_5_1,                        // 5.1
260         GRP_6_1,                        // 6.1
261         GRP_7_1,                        // 7.1
262         GRP_7_1W,                       // 7.1 Wide
263     };
264 
265     enum port_group_role_t
266     {
267         PGR_CENTER,
268         PGR_CENTER_LEFT,
269         PGR_CENTER_RIGHT,
270         PGR_LEFT,
271         PGR_LO_FREQ,
272         PGR_REAR_CENTER,
273         PGR_REAR_LEFT,
274         PGR_REAR_RIGHT,
275         PGR_RIGHT,
276         PGR_SIDE_LEFT,
277         PGR_SIDE_RIGHT,
278         PGR_MS_SIDE,
279         PGR_MS_MIDDLE
280     };
281 
282     enum port_group_flags_t
283     {
284         PGF_IN          = (0 << 0),     // Input group
285         PGF_OUT         = (1 << 0),     // Output group
286         PGF_SIDECHAIN   = (1 << 1),     // Sidechain
287         PGF_MAIN        = (1 << 2),     // Main input/output group
288     };
289 
290     typedef struct port_group_item_t
291     {
292         const char         *id;
293         port_group_role_t   role;
294     } port_group_item_t;
295 
296     typedef struct port_group_t
297     {
298         const char                 *id;         // Group ID
299         const char                 *name;       // Group name
300         port_group_type_t           type;       // Group type
301         int                         flags;
302         const port_group_item_t    *items;
303         const char                 *parent_id;  // Reference to parent group
304     } port_group_t;
305 
306     typedef struct port_item_t {
307         const char             *text;           // Text to display, required
308         const char             *lc_key;         // Localized key  (optional)
309     } port_item_t;
310 
311     typedef struct port_t
312     {
313         const char             *id;             // Control ID
314         const char             *name;           // Control name
315         unit_t                  unit;           // Units
316         role_t                  role;           // Role
317         int                     flags;          // Flags
318         float                   min;            // Minimum value
319         float                   max;            // Maximum value
320         float                   start;          // Initial value
321         float                   step;           // Change step
322         const port_item_t      *items;          // Items for enum / port set
323         const port_t           *members;        // Port members for group
324     } port_t;
325 
326     typedef struct person_t
327     {
328         const char             *uid;            // UID of person
329         const char             *nick;           // Nickname
330         const char             *name;           // Name
331         const char             *mailbox;        // E-mail
332         const char             *homepage;       // Homepage
333     } person_t;
334 
335     typedef struct plugin_metadata_t
336     {
337         const char             *name;           // Plugin name
338         const char             *description;    // Plugin description
339         const char             *acronym;        // Plugin acronym
340         const person_t         *developer;      // Developer
341         const char             *lv2_uid;        // LV2 unique identifier
342         const char             *vst_uid;        // Steinberg VST ID of the plugin
343         const uint32_t          ladspa_id;      // LADSPA ID of the plugin
344         const uint32_t          version;        // Version of the plugin
345         const int              *classes;        // List of plugin classes terminated by negative value
346         const int               extensions;     // Additional extensions
347         const port_t           *ports;          // List of all ports
348         const char             *ui_resource;    // Location of the UI file resource
349         const char             *ui_presets;     // Prefix of the preset location
350         const port_group_t     *port_groups;    // List of all port groups
351     } plugin_metadata_t;
352 
353     // Atom ports' metadata for LV2 plugins
354     extern const port_t         lv2_atom_ports[];
355     extern const port_t         lv2_latency_port;
356 
357     const char     *encode_unit(size_t unit);
358     const char     *unit_lc_key(size_t code);
359     unit_t          decode_unit(const char *name);
360     bool            is_discrete_unit(size_t unit);
361     bool            is_decibel_unit(size_t unit);
362     bool            is_gain_unit(size_t unit);
363     bool            is_degree_unit(size_t unit);
364     bool            is_log_rule(const port_t *port);
365 
366     size_t          list_size(const port_item_t *list);
367     float           limit_value(const port_t *port, float value);
368 
369     void            format_float(char *buf, size_t len, const port_t *meta, float value, ssize_t precision = -1);
370     void            format_int(char *buf, size_t len, const port_t *meta, float value);
371     void            format_enum(char *buf, size_t len, const port_t *meta, float value);
372     void            format_decibels(char *buf, size_t len, const port_t *meta, float value, ssize_t precision = -1);
373     void            format_bool(char *buf, size_t len, const port_t *meta, float value);
374 
375     void            format_value(char *buf, size_t len, const port_t *meta, float value, ssize_t precision = -1);
376 
377     status_t        parse_bool(float *dst, const char *text);
378     status_t        parse_enum(float *dst, const char *text, const port_t *meta);
379     status_t        parse_decibels(float *dst, const char *text, const port_t *meta);
380     status_t        parse_int(float *dst, const char *text, const port_t *meta);
381     status_t        parse_float(float *dst, const char *text, const port_t *meta);
382     status_t        parse_value(float *dst, const char *text, const port_t *meta);
383 
384     void            get_port_parameters(const port_t *p, float *min, float *max, float *step);
385 
386     /** Clone port metadata
387      *
388      * @param metadata port list
389      * @param postfix potfix to be added to the port list, can be NULL
390      * @return cloned port metadata
391      */
392     port_t         *clone_port_metadata(const port_t *metadata, const char *postfix);
393 
394     /** Drop port metadata
395      *
396      * @param metadata port metadata to drop
397      */
398     void            drop_port_metadata(port_t *metadata);
399 
400     /** Size of port list
401      *
402      * @param metadata port list metadata
403      * @return number of elements excluding PORTS_END
404      */
405     size_t          port_list_size(const port_t *metadata);
406 }
407 
408 #endif /* METADATA_METADATA_H_ */
409