Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/src/dssi/dssi.h @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* -*- c-basic-offset: 4 -*- */ | |
2 | |
3 /* dssi.h | |
4 | |
5 DSSI version 1.0 | |
6 Copyright (c) 2004, 2009 Chris Cannam, Steve Harris and Sean Bolton | |
7 | |
8 This library is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU Lesser General Public License | |
10 as published by the Free Software Foundation; either version 2.1 of | |
11 the License, or (at your option) any later version. | |
12 | |
13 This library is distributed in the hope that it will be useful, but | |
14 WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 Lesser General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU Lesser General Public | |
19 License along with this library; if not, write to the Free Software | |
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
21 MA 02110-1301 USA | |
22 */ | |
23 | |
24 #ifndef DSSI_INCLUDED | |
25 #define DSSI_INCLUDED | |
26 | |
27 #include "../ladspa/ladspa.h" | |
28 #include "seq_event-compat.h" | |
29 | |
30 #define DSSI_VERSION "1.0" | |
31 #define DSSI_VERSION_MAJOR 1 | |
32 #define DSSI_VERSION_MINOR 0 | |
33 | |
34 #ifdef __cplusplus | |
35 extern "C" { | |
36 #endif | |
37 | |
38 #ifndef DSSI_PLUGIN_EXPORT | |
39 # define DSSI_PLUGIN_EXPORT LADSPA_PLUGIN_EXPORT | |
40 #endif | |
41 | |
42 /* | |
43 There is a need for an API that supports hosted MIDI soft synths | |
44 with GUIs in Linux audio applications. In time the GMPI initiative | |
45 should comprehensively address this need, but the requirement for | |
46 Linux applications to be able to support simple hosted synths is | |
47 here now, and GMPI is not. This proposal (the "DSSI Soft Synth | |
48 Interface" or DSSI, pronounced "dizzy") aims to provide a simple | |
49 solution in a way that we hope will prove complete and compelling | |
50 enough to support now, yet not so compelling as to supplant GMPI or | |
51 any other comprehensive future proposal. | |
52 | |
53 For simplicity and familiarity, this API is based as far as | |
54 possible on existing work -- the LADSPA plugin API for control | |
55 values and audio processing, and the ALSA sequencer event types for | |
56 MIDI event communication. The GUI part of the proposal is quite | |
57 new, but may also be applicable retroactively to LADSPA plugins | |
58 that do not otherwise support this synth interface. | |
59 */ | |
60 | |
61 typedef struct _DSSI_Program_Descriptor { | |
62 | |
63 /** Bank number for this program. Note that DSSI does not support | |
64 MIDI-style separation of bank LSB and MSB values. There is no | |
65 restriction on the set of available banks: the numbers do not | |
66 need to be contiguous, there does not need to be a bank 0, etc. */ | |
67 unsigned long Bank; | |
68 | |
69 /** Program number (unique within its bank) for this program. | |
70 There is no restriction on the set of available programs: the | |
71 numbers do not need to be contiguous, there does not need to | |
72 be a program 0, etc. */ | |
73 unsigned long Program; | |
74 | |
75 /** Name of the program. */ | |
76 const char * Name; | |
77 | |
78 } DSSI_Program_Descriptor; | |
79 | |
80 | |
81 typedef struct _DSSI_Descriptor { | |
82 | |
83 /** | |
84 * DSSI_API_Version | |
85 * | |
86 * This member indicates the DSSI API level used by this plugin. | |
87 * If we're lucky, this will never be needed. For now all plugins | |
88 * must set it to 1. | |
89 */ | |
90 int DSSI_API_Version; | |
91 | |
92 /** | |
93 * LADSPA_Plugin | |
94 * | |
95 * A DSSI synth plugin consists of a LADSPA plugin plus an | |
96 * additional framework for controlling program settings and | |
97 * transmitting MIDI events. A plugin must fully implement the | |
98 * LADSPA descriptor fields as well as the required LADSPA | |
99 * functions including instantiate() and (de)activate(). It | |
100 * should also implement run(), with the same behaviour as if | |
101 * run_synth() (below) were called with no synth events. | |
102 * | |
103 * In order to instantiate a synth the host calls the LADSPA | |
104 * instantiate function, passing in this LADSPA_Descriptor | |
105 * pointer. The returned LADSPA_Handle is used as the argument | |
106 * for the DSSI functions below as well as for the LADSPA ones. | |
107 */ | |
108 const LADSPA_Descriptor *LADSPA_Plugin; | |
109 | |
110 /** | |
111 * configure() | |
112 * | |
113 * This member is a function pointer that sends a piece of | |
114 * configuration data to the plugin. The key argument specifies | |
115 * some aspect of the synth's configuration that is to be changed, | |
116 * and the value argument specifies a new value for it. A plugin | |
117 * that does not require this facility at all may set this member | |
118 * to NULL. | |
119 * | |
120 * This call is intended to set some session-scoped aspect of a | |
121 * plugin's behaviour, for example to tell the plugin to load | |
122 * sample data from a particular file. The plugin should act | |
123 * immediately on the request. The call should return NULL on | |
124 * success, or an error string that may be shown to the user. The | |
125 * host will free the returned value after use if it is non-NULL. | |
126 * | |
127 * Calls to configure() are not automated as timed events. | |
128 * Instead, a host should remember the last value associated with | |
129 * each key passed to configure() during a given session for a | |
130 * given plugin instance, and should call configure() with the | |
131 * correct value for each key the next time it instantiates the | |
132 * "same" plugin instance, for example on reloading a project in | |
133 * which the plugin was used before. Plugins should note that a | |
134 * host may typically instantiate a plugin multiple times with the | |
135 * same configuration values, and should share data between | |
136 * instances where practical. | |
137 * | |
138 * Calling configure() completely invalidates the program and bank | |
139 * information last obtained from the plugin. | |
140 * | |
141 * Reserved and special key prefixes | |
142 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
143 * The DSSI: prefix | |
144 * ---------------- | |
145 * Configure keys starting with DSSI: are reserved for particular | |
146 * purposes documented in the DSSI specification. At the moment, | |
147 * there is one such key: DSSI:PROJECT_DIRECTORY. A host may call | |
148 * configure() passing this key and a directory path value. This | |
149 * indicates to the plugin and its UI that a directory at that | |
150 * path exists and may be used for project-local data. Plugins | |
151 * may wish to use the project directory as a fallback location | |
152 * when looking for other file data, or as a base for relative | |
153 * paths in other configuration values. | |
154 * | |
155 * The GLOBAL: prefix | |
156 * ------------------ | |
157 * Configure keys starting with GLOBAL: may be used by the plugin | |
158 * and its UI for any purpose, but are treated specially by the | |
159 * host. When one of these keys is used in a configure OSC call | |
160 * from the plugin UI, the host makes the corresponding configure | |
161 * call (preserving the GLOBAL: prefix) not only to the target | |
162 * plugin but also to all other plugins in the same instance | |
163 * group, as well as their UIs. Note that if any instance | |
164 * returns non-NULL from configure to indicate error, the host | |
165 * may stop there (and the set of plugins on which configure has | |
166 * been called will thus depend on the host implementation). | |
167 * See also the configure OSC call documentation in RFC.txt. | |
168 */ | |
169 char *(*configure)(LADSPA_Handle Instance, | |
170 const char *Key, | |
171 const char *Value); | |
172 | |
173 #define DSSI_RESERVED_CONFIGURE_PREFIX "DSSI:" | |
174 #define DSSI_GLOBAL_CONFIGURE_PREFIX "GLOBAL:" | |
175 #define DSSI_PROJECT_DIRECTORY_KEY \ | |
176 DSSI_RESERVED_CONFIGURE_PREFIX "PROJECT_DIRECTORY" | |
177 | |
178 /** | |
179 * get_program() | |
180 * | |
181 * This member is a function pointer that provides a description | |
182 * of a program (named preset sound) available on this synth. A | |
183 * plugin that does not support programs at all should set this | |
184 * member to NULL. | |
185 * | |
186 * The Index argument is an index into the plugin's list of | |
187 * programs, not a program number as represented by the Program | |
188 * field of the DSSI_Program_Descriptor. (This distinction is | |
189 * needed to support synths that use non-contiguous program or | |
190 * bank numbers.) | |
191 * | |
192 * This function returns a DSSI_Program_Descriptor pointer that is | |
193 * guaranteed to be valid only until the next call to get_program, | |
194 * deactivate, or configure, on the same plugin instance. This | |
195 * function must return NULL if passed an Index argument out of | |
196 * range, so that the host can use it to query the number of | |
197 * programs as well as their properties. | |
198 */ | |
199 const DSSI_Program_Descriptor *(*get_program)(LADSPA_Handle Instance, | |
200 unsigned long Index); | |
201 | |
202 /** | |
203 * select_program() | |
204 * | |
205 * This member is a function pointer that selects a new program | |
206 * for this synth. The program change should take effect | |
207 * immediately at the start of the next run_synth() call. (This | |
208 * means that a host providing the capability of changing programs | |
209 * between any two notes on a track must vary the block size so as | |
210 * to place the program change at the right place. A host that | |
211 * wanted to avoid this would probably just instantiate a plugin | |
212 * for each program.) | |
213 * | |
214 * A plugin that does not support programs at all should set this | |
215 * member NULL. Plugins should ignore a select_program() call | |
216 * with an invalid bank or program. | |
217 * | |
218 * A plugin is not required to select any particular default | |
219 * program on activate(): it's the host's duty to set a program | |
220 * explicitly. The current program is invalidated by any call to | |
221 * configure(). | |
222 * | |
223 * A plugin is permitted to re-write the values of its input | |
224 * control ports when select_program is called. The host should | |
225 * re-read the input control port values and update its own | |
226 * records appropriately. (This is the only circumstance in | |
227 * which a DSSI plugin is allowed to modify its own input ports.) | |
228 */ | |
229 void (*select_program)(LADSPA_Handle Instance, | |
230 unsigned long Bank, | |
231 unsigned long Program); | |
232 | |
233 /** | |
234 * get_midi_controller_for_port() | |
235 * | |
236 * This member is a function pointer that returns the MIDI | |
237 * controller number or NRPN that should be mapped to the given | |
238 * input control port. If the given port should not have any MIDI | |
239 * controller mapped to it, the function should return DSSI_NONE. | |
240 * The behaviour of this function is undefined if the given port | |
241 * number does not correspond to an input control port. A plugin | |
242 * that does not want MIDI controllers mapped to ports at all may | |
243 * set this member NULL. | |
244 * | |
245 * Correct values can be got using the macros DSSI_CC(num) and | |
246 * DSSI_NRPN(num) as appropriate, and values can be combined using | |
247 * bitwise OR: e.g. DSSI_CC(23) | DSSI_NRPN(1069) means the port | |
248 * should respond to CC #23 and NRPN #1069. | |
249 * | |
250 * The host is responsible for doing proper scaling from MIDI | |
251 * controller and NRPN value ranges to port ranges according to | |
252 * the plugin's LADSPA port hints. Hosts should not deliver | |
253 * through run_synth any MIDI controller events that have already | |
254 * been mapped to control port values. | |
255 * | |
256 * A plugin should not attempt to request mappings from | |
257 * controllers 0 or 32 (MIDI Bank Select MSB and LSB). | |
258 */ | |
259 int (*get_midi_controller_for_port)(LADSPA_Handle Instance, | |
260 unsigned long Port); | |
261 | |
262 /** | |
263 * run_synth() | |
264 * | |
265 * This member is a function pointer that runs a synth for a | |
266 * block. This is identical in function to the LADSPA run() | |
267 * function, except that it also supplies events to the synth. | |
268 * | |
269 * A plugin may provide this function, run_multiple_synths() (see | |
270 * below), both, or neither (if it is not in fact a synth). A | |
271 * plugin that does not provide this function must set this member | |
272 * to NULL. Authors of synth plugins are encouraged to provide | |
273 * this function if at all possible. | |
274 * | |
275 * The Events pointer points to a block of EventCount ALSA | |
276 * sequencer events, which is used to communicate MIDI and related | |
277 * events to the synth. Each event is timestamped relative to the | |
278 * start of the block, (mis)using the ALSA "tick time" field as a | |
279 * frame count. The host is responsible for ensuring that events | |
280 * with differing timestamps are already ordered by time. | |
281 * | |
282 * See also the notes on activation, port connection etc in | |
283 * ladpsa.h, in the context of the LADSPA run() function. | |
284 * | |
285 * Note Events | |
286 * ~~~~~~~~~~~ | |
287 * There are two minor requirements aimed at making the plugin | |
288 * writer's life as simple as possible: | |
289 * | |
290 * 1. A host must never send events of type SND_SEQ_EVENT_NOTE. | |
291 * Notes should always be sent as separate SND_SEQ_EVENT_NOTE_ON | |
292 * and NOTE_OFF events. A plugin should discard any one-point | |
293 * NOTE events it sees. | |
294 * | |
295 * 2. A host must not attempt to switch notes off by sending | |
296 * zero-velocity NOTE_ON events. It should always send true | |
297 * NOTE_OFFs. It is the host's responsibility to remap events in | |
298 * cases where an external MIDI source has sent it zero-velocity | |
299 * NOTE_ONs. | |
300 * | |
301 * Bank and Program Events | |
302 * ~~~~~~~~~~~~~~~~~~~~~~~ | |
303 * Hosts must map MIDI Bank Select MSB and LSB (0 and 32) | |
304 * controllers and MIDI Program Change events onto the banks and | |
305 * programs specified by the plugin, using the DSSI select_program | |
306 * call. No host should ever deliver a program change or bank | |
307 * select controller to a plugin via run_synth. | |
308 */ | |
309 void (*run_synth)(LADSPA_Handle Instance, | |
310 unsigned long SampleCount, | |
311 snd_seq_event_t *Events, | |
312 unsigned long EventCount); | |
313 | |
314 /** | |
315 * run_synth_adding() | |
316 * | |
317 * This member is a function pointer that runs an instance of a | |
318 * synth for a block, adding its outputs to the values already | |
319 * present at the output ports. This is provided for symmetry | |
320 * with LADSPA run_adding(), and is equally optional. A plugin | |
321 * that does not provide it must set this member to NULL. | |
322 */ | |
323 void (*run_synth_adding)(LADSPA_Handle Instance, | |
324 unsigned long SampleCount, | |
325 snd_seq_event_t *Events, | |
326 unsigned long EventCount); | |
327 | |
328 /** | |
329 * run_multiple_synths() | |
330 * | |
331 * This member is a function pointer that runs multiple synth | |
332 * instances for a block. This is very similar to run_synth(), | |
333 * except that Instances, Events, and EventCounts each point to | |
334 * arrays that hold the LADSPA handles, event buffers, and | |
335 * event counts for each of InstanceCount instances. That is, | |
336 * Instances points to an array of InstanceCount pointers to | |
337 * DSSI plugin instantiations, Events points to an array of | |
338 * pointers to each instantiation's respective event list, and | |
339 * EventCounts points to an array containing each instantiation's | |
340 * respective event count. | |
341 * | |
342 * A host using this function must guarantee that ALL active | |
343 * instances of the plugin are represented in each call to the | |
344 * function -- that is, a host may not call run_multiple_synths() | |
345 * for some instances of a given plugin and then call run_synth() | |
346 * as well for others. 'All .. instances of the plugin' means | |
347 * every instance sharing the same LADSPA label and shared object | |
348 * (*.so) file (rather than every instance sharing the same *.so). | |
349 * 'Active' means any instance for which activate() has been called | |
350 * but deactivate() has not. | |
351 * | |
352 * A plugin may provide this function, run_synths() (see above), | |
353 * both, or neither (if it not in fact a synth). A plugin that | |
354 * does not provide this function must set this member to NULL. | |
355 * Plugin authors implementing run_multiple_synths are strongly | |
356 * encouraged to implement run_synth as well if at all possible, | |
357 * to aid simplistic hosts, even where it would be less efficient | |
358 * to use it. | |
359 */ | |
360 void (*run_multiple_synths)(unsigned long InstanceCount, | |
361 LADSPA_Handle *Instances, | |
362 unsigned long SampleCount, | |
363 snd_seq_event_t **Events, | |
364 unsigned long *EventCounts); | |
365 | |
366 /** | |
367 * run_multiple_synths_adding() | |
368 * | |
369 * This member is a function pointer that runs multiple synth | |
370 * instances for a block, adding each synth's outputs to the | |
371 * values already present at the output ports. This is provided | |
372 * for symmetry with both the DSSI run_multiple_synths() and LADSPA | |
373 * run_adding() functions, and is equally optional. A plugin | |
374 * that does not provide it must set this member to NULL. | |
375 */ | |
376 void (*run_multiple_synths_adding)(unsigned long InstanceCount, | |
377 LADSPA_Handle *Instances, | |
378 unsigned long SampleCount, | |
379 snd_seq_event_t **Events, | |
380 unsigned long *EventCounts); | |
381 | |
382 /** | |
383 * set_custom_data() | |
384 */ | |
385 int (*set_custom_data)(LADSPA_Handle Instance, | |
386 void *Data, | |
387 unsigned long DataLength); | |
388 | |
389 /** | |
390 * get_custom_data() | |
391 */ | |
392 int (*get_custom_data)(LADSPA_Handle Instance, | |
393 void **Data, | |
394 unsigned long *DataLength); | |
395 | |
396 } DSSI_Descriptor; | |
397 | |
398 /** | |
399 * DSSI supports a plugin discovery method similar to that of LADSPA: | |
400 * | |
401 * - DSSI hosts may wish to locate DSSI plugin shared object files by | |
402 * searching the paths contained in the DSSI_PATH and LADSPA_PATH | |
403 * environment variables, if they are present. Both are expected | |
404 * to be colon-separated lists of directories to be searched (in | |
405 * order), and DSSI_PATH should be searched first if both variables | |
406 * are set. | |
407 * | |
408 * - Each shared object file containing DSSI plugins must include a | |
409 * function dssi_descriptor(), with the following function prototype | |
410 * and C-style linkage. Hosts may enumerate the plugin types | |
411 * available in the shared object file by repeatedly calling | |
412 * this function with successive Index values (beginning from 0), | |
413 * until a return value of NULL indicates no more plugin types are | |
414 * available. Each non-NULL return is the DSSI_Descriptor | |
415 * of a distinct plugin type. | |
416 */ | |
417 | |
418 DSSI_PLUGIN_EXPORT const DSSI_Descriptor *dssi_descriptor(unsigned long Index); | |
419 | |
420 typedef const DSSI_Descriptor *(*DSSI_Descriptor_Function)(unsigned long Index); | |
421 | |
422 /* | |
423 * Macros to specify particular MIDI controllers in return values from | |
424 * get_midi_controller_for_port() | |
425 */ | |
426 | |
427 #define DSSI_CC_BITS 0x20000000 | |
428 #define DSSI_NRPN_BITS 0x40000000 | |
429 | |
430 #define DSSI_NONE -1 | |
431 #define DSSI_CONTROLLER_IS_SET(n) (DSSI_NONE != (n)) | |
432 | |
433 #define DSSI_CC(n) (DSSI_CC_BITS | (n)) | |
434 #define DSSI_IS_CC(n) (DSSI_CC_BITS & (n)) | |
435 #define DSSI_CC_NUMBER(n) ((n) & 0x7f) | |
436 | |
437 #define DSSI_NRPN(n) (DSSI_NRPN_BITS | ((n) << 7)) | |
438 #define DSSI_IS_NRPN(n) (DSSI_NRPN_BITS & (n)) | |
439 #define DSSI_NRPN_NUMBER(n) (((n) >> 7) & 0x3fff) | |
440 | |
441 #ifdef __cplusplus | |
442 } | |
443 #endif | |
444 | |
445 #endif /* DSSI_INCLUDED */ |