annotate plugin/api/dssi.h @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents fc9323a41f5a
children
rev   line source
lbajardsilogic@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
lbajardsilogic@0 2
lbajardsilogic@0 3 /* dssi.h
lbajardsilogic@0 4
lbajardsilogic@0 5 DSSI version 0.10
lbajardsilogic@0 6 Copyright (c) 2004,2005 Chris Cannam, Steve Harris and Sean Bolton
lbajardsilogic@0 7
lbajardsilogic@0 8 This library is free software; you can redistribute it and/or
lbajardsilogic@0 9 modify it under the terms of the GNU Lesser General Public License
lbajardsilogic@0 10 as published by the Free Software Foundation; either version 2.1 of
lbajardsilogic@0 11 the License, or (at your option) any later version.
lbajardsilogic@0 12
lbajardsilogic@0 13 This library is distributed in the hope that it will be useful, but
lbajardsilogic@0 14 WITHOUT ANY WARRANTY; without even the implied warranty of
lbajardsilogic@0 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
lbajardsilogic@0 16 Lesser General Public License for more details.
lbajardsilogic@0 17
lbajardsilogic@0 18 You should have received a copy of the GNU Lesser General Public
lbajardsilogic@0 19 License along with this library; if not, write to the Free Software
lbajardsilogic@0 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
lbajardsilogic@0 21 USA.
lbajardsilogic@0 22 */
lbajardsilogic@0 23
lbajardsilogic@0 24 #ifndef DSSI_INCLUDED
lbajardsilogic@0 25 #define DSSI_INCLUDED
lbajardsilogic@0 26
lbajardsilogic@0 27 #include "ladspa.h"
lbajardsilogic@0 28 #include "alsa/seq_event.h"
lbajardsilogic@0 29
lbajardsilogic@0 30 #define DSSI_VERSION "0.10"
lbajardsilogic@0 31 #define DSSI_VERSION_MAJOR 0
lbajardsilogic@0 32 #define DSSI_VERSION_MINOR 10
lbajardsilogic@0 33
lbajardsilogic@0 34 #ifdef __cplusplus
lbajardsilogic@0 35 extern "C" {
lbajardsilogic@0 36 #endif
lbajardsilogic@0 37
lbajardsilogic@0 38 /*
lbajardsilogic@0 39 There is a need for an API that supports hosted MIDI soft synths
lbajardsilogic@0 40 with GUIs in Linux audio applications. In time the GMPI initiative
lbajardsilogic@0 41 should comprehensively address this need, but the requirement for
lbajardsilogic@0 42 Linux applications to be able to support simple hosted synths is
lbajardsilogic@0 43 here now, and GMPI is not. This proposal (the "DSSI Soft Synth
lbajardsilogic@0 44 Interface" or DSSI, pronounced "dizzy") aims to provide a simple
lbajardsilogic@0 45 solution in a way that we hope will prove complete and compelling
lbajardsilogic@0 46 enough to support now, yet not so compelling as to supplant GMPI or
lbajardsilogic@0 47 any other comprehensive future proposal.
lbajardsilogic@0 48
lbajardsilogic@0 49 For simplicity and familiarity, this API is based as far as
lbajardsilogic@0 50 possible on existing work -- the LADSPA plugin API for control
lbajardsilogic@0 51 values and audio processing, and the ALSA sequencer event types for
lbajardsilogic@0 52 MIDI event communication. The GUI part of the proposal is quite
lbajardsilogic@0 53 new, but may also be applicable retroactively to LADSPA plugins
lbajardsilogic@0 54 that do not otherwise support this synth interface.
lbajardsilogic@0 55 */
lbajardsilogic@0 56
lbajardsilogic@0 57 /*
lbajardsilogic@0 58 A program wishing to use the DSSI v2 API should set the following
lbajardsilogic@0 59 symbol to 2 before including this header.
lbajardsilogic@0 60 */
lbajardsilogic@0 61 #if (!defined DSSI_API_LEVEL)
lbajardsilogic@0 62 #define DSSI_API_LEVEL 1
lbajardsilogic@0 63 #endif
lbajardsilogic@0 64
lbajardsilogic@0 65 typedef struct _DSSI_Program_Descriptor {
lbajardsilogic@0 66
lbajardsilogic@0 67 /** Bank number for this program. Note that DSSI does not support
lbajardsilogic@0 68 MIDI-style separation of bank LSB and MSB values. There is no
lbajardsilogic@0 69 restriction on the set of available banks: the numbers do not
lbajardsilogic@0 70 need to be contiguous, there does not need to be a bank 0, etc. */
lbajardsilogic@0 71 unsigned long Bank;
lbajardsilogic@0 72
lbajardsilogic@0 73 /** Program number (unique within its bank) for this program.
lbajardsilogic@0 74 There is no restriction on the set of available programs: the
lbajardsilogic@0 75 numbers do not need to be contiguous, there does not need to
lbajardsilogic@0 76 be a program 0, etc. */
lbajardsilogic@0 77 unsigned long Program;
lbajardsilogic@0 78
lbajardsilogic@0 79 /** Name of the program. */
lbajardsilogic@0 80 const char * Name;
lbajardsilogic@0 81
lbajardsilogic@0 82 } DSSI_Program_Descriptor;
lbajardsilogic@0 83
lbajardsilogic@0 84
lbajardsilogic@0 85 #define DSSI_TRANSPORT_VALID_STATE 0x01
lbajardsilogic@0 86 #define DSSI_TRANSPORT_VALID_BPM 0x02
lbajardsilogic@0 87 #define DSSI_TRANSPORT_VALID_BBT 0x10
lbajardsilogic@0 88 #define DSSI_TRANSPORT_VALID_TIME 0x20
lbajardsilogic@0 89
lbajardsilogic@0 90 #define DSSI_TRANSPORT_STATE_STOPPED 0
lbajardsilogic@0 91 #define DSSI_TRANSPORT_STATE_RUNNING 1
lbajardsilogic@0 92 #define DSSI_TRANSPORT_STATE_FREEWHEELING 2
lbajardsilogic@0 93 #define DSSI_TRANSPORT_STATE_OTHER 3 /* waiting for sync, ? */
lbajardsilogic@0 94
lbajardsilogic@0 95 typedef struct _DSSI_Transport_Info {
lbajardsilogic@0 96
lbajardsilogic@0 97 /** The value of this field indicates which of the following
lbajardsilogic@0 98 * transport information fields contain valid values. It is
lbajardsilogic@0 99 * the logical OR of the DSSI_TRANSPORT_VALID_* bits defined
lbajardsilogic@0 100 * above, and may be zero. */
lbajardsilogic@0 101 int Valid;
lbajardsilogic@0 102
lbajardsilogic@0 103
lbajardsilogic@0 104 /** This field is valid when (Valid & DSSI_TRANSPORT_VALID_STATE)
lbajardsilogic@0 105 * is true:
lbajardsilogic@0 106 *
lbajardsilogic@0 107 * ---- The current transport state, one of the DSSI_TRANSPORT_STATE_*
lbajardsilogic@0 108 * values defined above. */
lbajardsilogic@0 109 int State;
lbajardsilogic@0 110
lbajardsilogic@0 111
lbajardsilogic@0 112 /** This field is valid when (Valid & DSSI_TRANSPORT_VALID_BPM)
lbajardsilogic@0 113 * is true:
lbajardsilogic@0 114 *
lbajardsilogic@0 115 * ---- The current tempo, in beats per minute. */
lbajardsilogic@0 116 double Beats_Per_Minute;
lbajardsilogic@0 117
lbajardsilogic@0 118
lbajardsilogic@0 119 /** These six fields are valid when (Valid & DSSI_TRANSPORT_VALID_BBT)
lbajardsilogic@0 120 * is true:
lbajardsilogic@0 121 *
lbajardsilogic@0 122 * ---- The bar number at the beginning of the current process cycle. */
lbajardsilogic@0 123 unsigned long Bar;
lbajardsilogic@0 124
lbajardsilogic@0 125 /** ---- The beat within that Bar. */
lbajardsilogic@0 126 unsigned long Beat;
lbajardsilogic@0 127
lbajardsilogic@0 128 /** ---- The tick within that Beat. */
lbajardsilogic@0 129 unsigned long Tick;
lbajardsilogic@0 130
lbajardsilogic@0 131 /** ---- The (possibly fractional) tick count since transport 'start'
lbajardsilogic@0 132 * and the beginning of the current Bar. */
lbajardsilogic@0 133 double Bar_Start_Tick;
lbajardsilogic@0 134
lbajardsilogic@0 135 /** ---- The number of beats per bar. */
lbajardsilogic@0 136 float Beats_Per_Bar;
lbajardsilogic@0 137
lbajardsilogic@0 138 /** ---- The number of ticks for each beat. */
lbajardsilogic@0 139 double Ticks_Per_Beat;
lbajardsilogic@0 140
lbajardsilogic@0 141 /* [Sean says: I left out the 'beat_type' (time signature "denominator")
lbajardsilogic@0 142 * field of the jack_position_t structure, because I think it's useless
lbajardsilogic@0 143 * except to a notation program. Does anybody else feel like we need it?]
lbajardsilogic@0 144 */
lbajardsilogic@0 145
lbajardsilogic@0 146 /** These two fields are valid when (Valid & DSSI_TRANSPORT_VALID_TIME)
lbajardsilogic@0 147 * is true:
lbajardsilogic@0 148 *
lbajardsilogic@0 149 * ---- The transport time at the beginning of the current process
lbajardsilogic@0 150 * cycle, in seconds. */
lbajardsilogic@0 151 double Current_Time;
lbajardsilogic@0 152
lbajardsilogic@0 153 /** ---- The transport time at the beginning of the next process
lbajardsilogic@0 154 cycle, unless repositioning occurs. */
lbajardsilogic@0 155 double Next_Time;
lbajardsilogic@0 156
lbajardsilogic@0 157 } DSSI_Transport_Info;
lbajardsilogic@0 158
lbajardsilogic@0 159 typedef struct _DSSI_Host_Descriptor DSSI_Host_Descriptor; /* below */
lbajardsilogic@0 160
lbajardsilogic@0 161 typedef struct _DSSI_Descriptor {
lbajardsilogic@0 162
lbajardsilogic@0 163 /**
lbajardsilogic@0 164 * DSSI_API_Version
lbajardsilogic@0 165 *
lbajardsilogic@0 166 * This member indicates the DSSI API level used by this plugin.
lbajardsilogic@0 167 * All plugins must set this to 1 or 2. The version 1 API contains
lbajardsilogic@0 168 * all DSSI_Descriptor fields through run_multiple_synths_adding(),
lbajardsilogic@0 169 * while the version 2 API adds the receive_host_descriptor().
lbajardsilogic@0 170 */
lbajardsilogic@0 171 int DSSI_API_Version;
lbajardsilogic@0 172
lbajardsilogic@0 173 /**
lbajardsilogic@0 174 * LADSPA_Plugin
lbajardsilogic@0 175 *
lbajardsilogic@0 176 * A DSSI synth plugin consists of a LADSPA plugin plus an
lbajardsilogic@0 177 * additional framework for controlling program settings and
lbajardsilogic@0 178 * transmitting MIDI events. A plugin must fully implement the
lbajardsilogic@0 179 * LADSPA descriptor fields as well as the required LADSPA
lbajardsilogic@0 180 * functions including instantiate() and (de)activate(). It
lbajardsilogic@0 181 * should also implement run(), with the same behaviour as if
lbajardsilogic@0 182 * run_synth() (below) were called with no synth events.
lbajardsilogic@0 183 *
lbajardsilogic@0 184 * In order to instantiate a synth the host calls the LADSPA
lbajardsilogic@0 185 * instantiate function, passing in this LADSPA_Descriptor
lbajardsilogic@0 186 * pointer. The returned LADSPA_Handle is used as the argument
lbajardsilogic@0 187 * for the DSSI functions below as well as for the LADSPA ones.
lbajardsilogic@0 188 */
lbajardsilogic@0 189 const LADSPA_Descriptor *LADSPA_Plugin;
lbajardsilogic@0 190
lbajardsilogic@0 191 /**
lbajardsilogic@0 192 * configure()
lbajardsilogic@0 193 *
lbajardsilogic@0 194 * This member is a function pointer that sends a piece of
lbajardsilogic@0 195 * configuration data to the plugin. The key argument specifies
lbajardsilogic@0 196 * some aspect of the synth's configuration that is to be changed,
lbajardsilogic@0 197 * and the value argument specifies a new value for it. A plugin
lbajardsilogic@0 198 * that does not require this facility at all may set this member
lbajardsilogic@0 199 * to NULL.
lbajardsilogic@0 200 *
lbajardsilogic@0 201 * This call is intended to set some session-scoped aspect of a
lbajardsilogic@0 202 * plugin's behaviour, for example to tell the plugin to load
lbajardsilogic@0 203 * sample data from a particular file. The plugin should act
lbajardsilogic@0 204 * immediately on the request. The call should return NULL on
lbajardsilogic@0 205 * success, or an error string that may be shown to the user. The
lbajardsilogic@0 206 * host will free the returned value after use if it is non-NULL.
lbajardsilogic@0 207 *
lbajardsilogic@0 208 * Calls to configure() are not automated as timed events.
lbajardsilogic@0 209 * Instead, a host should remember the last value associated with
lbajardsilogic@0 210 * each key passed to configure() during a given session for a
lbajardsilogic@0 211 * given plugin instance, and should call configure() with the
lbajardsilogic@0 212 * correct value for each key the next time it instantiates the
lbajardsilogic@0 213 * "same" plugin instance, for example on reloading a project in
lbajardsilogic@0 214 * which the plugin was used before. Plugins should note that a
lbajardsilogic@0 215 * host may typically instantiate a plugin multiple times with the
lbajardsilogic@0 216 * same configuration values, and should share data between
lbajardsilogic@0 217 * instances where practical.
lbajardsilogic@0 218 *
lbajardsilogic@0 219 * Calling configure() completely invalidates the program and bank
lbajardsilogic@0 220 * information last obtained from the plugin.
lbajardsilogic@0 221 *
lbajardsilogic@0 222 * Reserved and special key prefixes
lbajardsilogic@0 223 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lbajardsilogic@0 224 * The DSSI: prefix
lbajardsilogic@0 225 * ----------------
lbajardsilogic@0 226 * Configure keys starting with DSSI: are reserved for particular
lbajardsilogic@0 227 * purposes documented in the DSSI specification. At the moment,
lbajardsilogic@0 228 * there is one such key: DSSI:PROJECT_DIRECTORY. A host may call
lbajardsilogic@0 229 * configure() passing this key and a directory path value. This
lbajardsilogic@0 230 * indicates to the plugin and its UI that a directory at that
lbajardsilogic@0 231 * path exists and may be used for project-local data. Plugins
lbajardsilogic@0 232 * may wish to use the project directory as a fallback location
lbajardsilogic@0 233 * when looking for other file data, or as a base for relative
lbajardsilogic@0 234 * paths in other configuration values.
lbajardsilogic@0 235 *
lbajardsilogic@0 236 * The GLOBAL: prefix
lbajardsilogic@0 237 * ------------------
lbajardsilogic@0 238 * Configure keys starting with GLOBAL: may be used by the plugin
lbajardsilogic@0 239 * and its UI for any purpose, but are treated specially by the
lbajardsilogic@0 240 * host. When one of these keys is used in a configure OSC call
lbajardsilogic@0 241 * from the plugin UI, the host makes the corresponding configure
lbajardsilogic@0 242 * call (preserving the GLOBAL: prefix) not only to the target
lbajardsilogic@0 243 * plugin but also to all other plugins in the same instance
lbajardsilogic@0 244 * group, as well as their UIs. Note that if any instance
lbajardsilogic@0 245 * returns non-NULL from configure to indicate error, the host
lbajardsilogic@0 246 * may stop there (and the set of plugins on which configure has
lbajardsilogic@0 247 * been called will thus depend on the host implementation).
lbajardsilogic@0 248 * See also the configure OSC call documentation in RFC.txt.
lbajardsilogic@0 249 */
lbajardsilogic@0 250 char *(*configure)(LADSPA_Handle Instance,
lbajardsilogic@0 251 const char *Key,
lbajardsilogic@0 252 const char *Value);
lbajardsilogic@0 253
lbajardsilogic@0 254 #define DSSI_RESERVED_CONFIGURE_PREFIX "DSSI:"
lbajardsilogic@0 255 #define DSSI_GLOBAL_CONFIGURE_PREFIX "GLOBAL:"
lbajardsilogic@0 256 #define DSSI_PROJECT_DIRECTORY_KEY \
lbajardsilogic@0 257 DSSI_RESERVED_CONFIGURE_PREFIX "PROJECT_DIRECTORY"
lbajardsilogic@0 258
lbajardsilogic@0 259 /**
lbajardsilogic@0 260 * get_program()
lbajardsilogic@0 261 *
lbajardsilogic@0 262 * This member is a function pointer that provides a description
lbajardsilogic@0 263 * of a program (named preset sound) available on this synth. A
lbajardsilogic@0 264 * plugin that does not support programs at all should set this
lbajardsilogic@0 265 * member to NULL.
lbajardsilogic@0 266 *
lbajardsilogic@0 267 * The Index argument is an index into the plugin's list of
lbajardsilogic@0 268 * programs, not a program number as represented by the Program
lbajardsilogic@0 269 * field of the DSSI_Program_Descriptor. (This distinction is
lbajardsilogic@0 270 * needed to support synths that use non-contiguous program or
lbajardsilogic@0 271 * bank numbers.)
lbajardsilogic@0 272 *
lbajardsilogic@0 273 * This function returns a DSSI_Program_Descriptor pointer that is
lbajardsilogic@0 274 * guaranteed to be valid only until the next call to get_program,
lbajardsilogic@0 275 * deactivate, or configure, on the same plugin instance. This
lbajardsilogic@0 276 * function must return NULL if passed an Index argument out of
lbajardsilogic@0 277 * range, so that the host can use it to query the number of
lbajardsilogic@0 278 * programs as well as their properties.
lbajardsilogic@0 279 */
lbajardsilogic@0 280 const DSSI_Program_Descriptor *(*get_program)(LADSPA_Handle Instance,
lbajardsilogic@0 281 unsigned long Index);
lbajardsilogic@0 282
lbajardsilogic@0 283 /**
lbajardsilogic@0 284 * select_program()
lbajardsilogic@0 285 *
lbajardsilogic@0 286 * This member is a function pointer that selects a new program
lbajardsilogic@0 287 * for this synth. The program change should take effect
lbajardsilogic@0 288 * immediately at the start of the next run_synth() call. (This
lbajardsilogic@0 289 * means that a host providing the capability of changing programs
lbajardsilogic@0 290 * between any two notes on a track must vary the block size so as
lbajardsilogic@0 291 * to place the program change at the right place. A host that
lbajardsilogic@0 292 * wanted to avoid this would probably just instantiate a plugin
lbajardsilogic@0 293 * for each program.)
lbajardsilogic@0 294 *
lbajardsilogic@0 295 * A plugin that does not support programs at all should set this
lbajardsilogic@0 296 * member NULL. Plugins should ignore a select_program() call
lbajardsilogic@0 297 * with an invalid bank or program.
lbajardsilogic@0 298 *
lbajardsilogic@0 299 * A plugin is not required to select any particular default
lbajardsilogic@0 300 * program on activate(): it's the host's duty to set a program
lbajardsilogic@0 301 * explicitly. The current program is invalidated by any call to
lbajardsilogic@0 302 * configure().
lbajardsilogic@0 303 *
lbajardsilogic@0 304 * A plugin is permitted to re-write the values of its input
lbajardsilogic@0 305 * control ports when select_program is called. The host should
lbajardsilogic@0 306 * re-read the input control port values and update its own
lbajardsilogic@0 307 * records appropriately. (This is the only circumstance in
lbajardsilogic@0 308 * which a DSSI plugin is allowed to modify its own input ports.)
lbajardsilogic@0 309 */
lbajardsilogic@0 310 void (*select_program)(LADSPA_Handle Instance,
lbajardsilogic@0 311 unsigned long Bank,
lbajardsilogic@0 312 unsigned long Program);
lbajardsilogic@0 313
lbajardsilogic@0 314 /**
lbajardsilogic@0 315 * get_midi_controller_for_port()
lbajardsilogic@0 316 *
lbajardsilogic@0 317 * This member is a function pointer that returns the MIDI
lbajardsilogic@0 318 * controller number or NRPN that should be mapped to the given
lbajardsilogic@0 319 * input control port. If the given port should not have any MIDI
lbajardsilogic@0 320 * controller mapped to it, the function should return DSSI_NONE.
lbajardsilogic@0 321 * The behaviour of this function is undefined if the given port
lbajardsilogic@0 322 * number does not correspond to an input control port. A plugin
lbajardsilogic@0 323 * that does not want MIDI controllers mapped to ports at all may
lbajardsilogic@0 324 * set this member NULL.
lbajardsilogic@0 325 *
lbajardsilogic@0 326 * Correct values can be got using the macros DSSI_CC(num) and
lbajardsilogic@0 327 * DSSI_NRPN(num) as appropriate, and values can be combined using
lbajardsilogic@0 328 * bitwise OR: e.g. DSSI_CC(23) | DSSI_NRPN(1069) means the port
lbajardsilogic@0 329 * should respond to CC #23 and NRPN #1069.
lbajardsilogic@0 330 *
lbajardsilogic@0 331 * The host is responsible for doing proper scaling from MIDI
lbajardsilogic@0 332 * controller and NRPN value ranges to port ranges according to
lbajardsilogic@0 333 * the plugin's LADSPA port hints. Hosts should not deliver
lbajardsilogic@0 334 * through run_synth any MIDI controller events that have already
lbajardsilogic@0 335 * been mapped to control port values.
lbajardsilogic@0 336 *
lbajardsilogic@0 337 * A plugin should not attempt to request mappings from
lbajardsilogic@0 338 * controllers 0 or 32 (MIDI Bank Select MSB and LSB).
lbajardsilogic@0 339 */
lbajardsilogic@0 340 int (*get_midi_controller_for_port)(LADSPA_Handle Instance,
lbajardsilogic@0 341 unsigned long Port);
lbajardsilogic@0 342
lbajardsilogic@0 343 /**
lbajardsilogic@0 344 * run_synth()
lbajardsilogic@0 345 *
lbajardsilogic@0 346 * This member is a function pointer that runs a synth for a
lbajardsilogic@0 347 * block. This is identical in function to the LADSPA run()
lbajardsilogic@0 348 * function, except that it also supplies events to the synth.
lbajardsilogic@0 349 *
lbajardsilogic@0 350 * A plugin may provide this function, run_multiple_synths() (see
lbajardsilogic@0 351 * below), both, or neither (if it is not in fact a synth). A
lbajardsilogic@0 352 * plugin that does not provide this function must set this member
lbajardsilogic@0 353 * to NULL. Authors of synth plugins are encouraged to provide
lbajardsilogic@0 354 * this function if at all possible.
lbajardsilogic@0 355 *
lbajardsilogic@0 356 * The Events pointer points to a block of EventCount ALSA
lbajardsilogic@0 357 * sequencer events, which is used to communicate MIDI and related
lbajardsilogic@0 358 * events to the synth. Each event is timestamped relative to the
lbajardsilogic@0 359 * start of the block, (mis)using the ALSA "tick time" field as a
lbajardsilogic@0 360 * frame count. The host is responsible for ensuring that events
lbajardsilogic@0 361 * with differing timestamps are already ordered by time.
lbajardsilogic@0 362 *
lbajardsilogic@0 363 * See also the notes on activation, port connection etc in
lbajardsilogic@0 364 * ladpsa.h, in the context of the LADSPA run() function.
lbajardsilogic@0 365 *
lbajardsilogic@0 366 * Note Events
lbajardsilogic@0 367 * ~~~~~~~~~~~
lbajardsilogic@0 368 * There are two minor requirements aimed at making the plugin
lbajardsilogic@0 369 * writer's life as simple as possible:
lbajardsilogic@0 370 *
lbajardsilogic@0 371 * 1. A host must never send events of type SND_SEQ_EVENT_NOTE.
lbajardsilogic@0 372 * Notes should always be sent as separate SND_SEQ_EVENT_NOTE_ON
lbajardsilogic@0 373 * and NOTE_OFF events. A plugin should discard any one-point
lbajardsilogic@0 374 * NOTE events it sees.
lbajardsilogic@0 375 *
lbajardsilogic@0 376 * 2. A host must not attempt to switch notes off by sending
lbajardsilogic@0 377 * zero-velocity NOTE_ON events. It should always send true
lbajardsilogic@0 378 * NOTE_OFFs. It is the host's responsibility to remap events in
lbajardsilogic@0 379 * cases where an external MIDI source has sent it zero-velocity
lbajardsilogic@0 380 * NOTE_ONs.
lbajardsilogic@0 381 *
lbajardsilogic@0 382 * Bank and Program Events
lbajardsilogic@0 383 * ~~~~~~~~~~~~~~~~~~~~~~~
lbajardsilogic@0 384 * Hosts must map MIDI Bank Select MSB and LSB (0 and 32)
lbajardsilogic@0 385 * controllers and MIDI Program Change events onto the banks and
lbajardsilogic@0 386 * programs specified by the plugin, using the DSSI select_program
lbajardsilogic@0 387 * call. No host should ever deliver a program change or bank
lbajardsilogic@0 388 * select controller to a plugin via run_synth.
lbajardsilogic@0 389 */
lbajardsilogic@0 390 void (*run_synth)(LADSPA_Handle Instance,
lbajardsilogic@0 391 unsigned long SampleCount,
lbajardsilogic@0 392 snd_seq_event_t *Events,
lbajardsilogic@0 393 unsigned long EventCount);
lbajardsilogic@0 394
lbajardsilogic@0 395 /**
lbajardsilogic@0 396 * run_synth_adding()
lbajardsilogic@0 397 *
lbajardsilogic@0 398 * This member is a function pointer that runs an instance of a
lbajardsilogic@0 399 * synth for a block, adding its outputs to the values already
lbajardsilogic@0 400 * present at the output ports. This is provided for symmetry
lbajardsilogic@0 401 * with LADSPA run_adding(), and is equally optional. A plugin
lbajardsilogic@0 402 * that does not provide it must set this member to NULL.
lbajardsilogic@0 403 */
lbajardsilogic@0 404 void (*run_synth_adding)(LADSPA_Handle Instance,
lbajardsilogic@0 405 unsigned long SampleCount,
lbajardsilogic@0 406 snd_seq_event_t *Events,
lbajardsilogic@0 407 unsigned long EventCount);
lbajardsilogic@0 408
lbajardsilogic@0 409 /**
lbajardsilogic@0 410 * run_multiple_synths()
lbajardsilogic@0 411 *
lbajardsilogic@0 412 * This member is a function pointer that runs multiple synth
lbajardsilogic@0 413 * instances for a block. This is very similar to run_synth(),
lbajardsilogic@0 414 * except that Instances, Events, and EventCounts each point to
lbajardsilogic@0 415 * arrays that hold the LADSPA handles, event buffers, and
lbajardsilogic@0 416 * event counts for each of InstanceCount instances. That is,
lbajardsilogic@0 417 * Instances points to an array of InstanceCount pointers to
lbajardsilogic@0 418 * DSSI plugin instantiations, Events points to an array of
lbajardsilogic@0 419 * pointers to each instantiation's respective event list, and
lbajardsilogic@0 420 * EventCounts points to an array containing each instantiation's
lbajardsilogic@0 421 * respective event count.
lbajardsilogic@0 422 *
lbajardsilogic@0 423 * A host using this function must guarantee that ALL active
lbajardsilogic@0 424 * instances of the plugin are represented in each call to the
lbajardsilogic@0 425 * function -- that is, a host may not call run_multiple_synths()
lbajardsilogic@0 426 * for some instances of a given plugin and then call run_synth()
lbajardsilogic@0 427 * as well for others. 'All .. instances of the plugin' means
lbajardsilogic@0 428 * every instance sharing the same LADSPA label and shared object
lbajardsilogic@0 429 * (*.so) file (rather than every instance sharing the same *.so).
lbajardsilogic@0 430 * 'Active' means any instance for which activate() has been called
lbajardsilogic@0 431 * but deactivate() has not.
lbajardsilogic@0 432 *
lbajardsilogic@0 433 * A plugin may provide this function, run_synths() (see above),
lbajardsilogic@0 434 * both, or neither (if it not in fact a synth). A plugin that
lbajardsilogic@0 435 * does not provide this function must set this member to NULL.
lbajardsilogic@0 436 * Plugin authors implementing run_multiple_synths are strongly
lbajardsilogic@0 437 * encouraged to implement run_synth as well if at all possible,
lbajardsilogic@0 438 * to aid simplistic hosts, even where it would be less efficient
lbajardsilogic@0 439 * to use it.
lbajardsilogic@0 440 */
lbajardsilogic@0 441 void (*run_multiple_synths)(unsigned long InstanceCount,
lbajardsilogic@0 442 LADSPA_Handle *Instances,
lbajardsilogic@0 443 unsigned long SampleCount,
lbajardsilogic@0 444 snd_seq_event_t **Events,
lbajardsilogic@0 445 unsigned long *EventCounts);
lbajardsilogic@0 446
lbajardsilogic@0 447 /**
lbajardsilogic@0 448 * run_multiple_synths_adding()
lbajardsilogic@0 449 *
lbajardsilogic@0 450 * This member is a function pointer that runs multiple synth
lbajardsilogic@0 451 * instances for a block, adding each synth's outputs to the
lbajardsilogic@0 452 * values already present at the output ports. This is provided
lbajardsilogic@0 453 * for symmetry with both the DSSI run_multiple_synths() and LADSPA
lbajardsilogic@0 454 * run_adding() functions, and is equally optional. A plugin
lbajardsilogic@0 455 * that does not provide it must set this member to NULL.
lbajardsilogic@0 456 */
lbajardsilogic@0 457 void (*run_multiple_synths_adding)(unsigned long InstanceCount,
lbajardsilogic@0 458 LADSPA_Handle *Instances,
lbajardsilogic@0 459 unsigned long SampleCount,
lbajardsilogic@0 460 snd_seq_event_t **Events,
lbajardsilogic@0 461 unsigned long *EventCounts);
lbajardsilogic@0 462
lbajardsilogic@0 463 #if (DSSI_API_LEVEL > 1)
lbajardsilogic@0 464
lbajardsilogic@0 465 /**
lbajardsilogic@0 466 * receive_host_descriptor()
lbajardsilogic@0 467 *
lbajardsilogic@0 468 * This member is a function pointer by which a host may provide
lbajardsilogic@0 469 * a plugin with a pointer to its DSSI_Host_Descriptor. Hosts
lbajardsilogic@0 470 * which provide host descriptor support must call this function
lbajardsilogic@0 471 * once per plugin shared object file, before any calls to
lbajardsilogic@0 472 * instantiate().
lbajardsilogic@0 473 *
lbajardsilogic@0 474 * NOTE: This field was added in version 2 of the DSSI API. Hosts
lbajardsilogic@0 475 * supporting version 2 must not access this field in a plugin
lbajardsilogic@0 476 * whose DSSI_API_Version is 1, and plugins supporting version 2
lbajardsilogic@0 477 * should behave reasonably under hosts (of any version) which do
lbajardsilogic@0 478 * not implement this function. A version 2 plugin that does not
lbajardsilogic@0 479 * provide this function must set this member to NULL.
lbajardsilogic@0 480 */
lbajardsilogic@0 481 void (*receive_host_descriptor)(const DSSI_Host_Descriptor *Descriptor);
lbajardsilogic@0 482
lbajardsilogic@0 483 #endif
lbajardsilogic@0 484
lbajardsilogic@0 485 } DSSI_Descriptor;
lbajardsilogic@0 486
lbajardsilogic@0 487 struct _DSSI_Host_Descriptor {
lbajardsilogic@0 488
lbajardsilogic@0 489 /**
lbajardsilogic@0 490 * DSSI_API_Version
lbajardsilogic@0 491 *
lbajardsilogic@0 492 * This member indicates the DSSI API level used by this host.
lbajardsilogic@0 493 * All hosts must set this to 2. Hopefully, we'll get this right
lbajardsilogic@0 494 * the first time, and this will never be needed.
lbajardsilogic@0 495 */
lbajardsilogic@0 496 int DSSI_API_Version;
lbajardsilogic@0 497
lbajardsilogic@0 498 /**
lbajardsilogic@0 499 * request_transport_information()
lbajardsilogic@0 500 *
lbajardsilogic@0 501 * This member is a function pointer by which a plugin instance may
lbajardsilogic@0 502 * request that a host begin providing transport information (if
lbajardsilogic@0 503 * Request is non-zero), or notify the host that it no longer needs
lbajardsilogic@0 504 * transport information (if Request is zero). Upon receiving a
lbajardsilogic@0 505 * non-zero request, the host should return a pointer to a
lbajardsilogic@0 506 * DSSI_Transport_Info structure if it is able to provide transport
lbajardsilogic@0 507 * information, or NULL otherwise.
lbajardsilogic@0 508 *
lbajardsilogic@0 509 * Once a plugin instance has received a non-null transport
lbajardsilogic@0 510 * information pointer, it may read from the structure at any time
lbajardsilogic@0 511 * within the execution of an audio class function (see doc/RFC.txt).
lbajardsilogic@0 512 * It should not consider the structure contents to be meaningful
lbajardsilogic@0 513 * while within a instantiation or control class function. Also,
lbajardsilogic@0 514 * since the validity of fields within the structure may change
lbajardsilogic@0 515 * between each new invocation of an audio class function, a plugin
lbajardsilogic@0 516 * instance must check the Valid field of the structure accordingly
lbajardsilogic@0 517 * before using the structure's other contents.
lbajardsilogic@0 518 *
lbajardsilogic@0 519 * A host which does not support this function must set this member
lbajardsilogic@0 520 * to NULL.
lbajardsilogic@0 521 */
lbajardsilogic@0 522 DSSI_Transport_Info *
lbajardsilogic@0 523 (*request_transport_information)(LADSPA_Handle Instance,
lbajardsilogic@0 524 int Request);
lbajardsilogic@0 525
lbajardsilogic@0 526 /**
lbajardsilogic@0 527 * request_midi_send()
lbajardsilogic@0 528 *
lbajardsilogic@0 529 * This member is a function pointer that allows a plugin to
lbajardsilogic@0 530 * request the ability to send MIDI events to the host.
lbajardsilogic@0 531 *
lbajardsilogic@0 532 * While the interpretation of plugin-generated MIDI events is
lbajardsilogic@0 533 * host implementation specific, a mechanism exists by which a
lbajardsilogic@0 534 * plugin may declare to the host the number of destination
lbajardsilogic@0 535 * 'ports' and MIDI channels it can expect will be used in the
lbajardsilogic@0 536 * plugin-generated events. Plugins which generate unchannelized
lbajardsilogic@0 537 * MIDI should supply zero for both Ports and Channels, otherwise
lbajardsilogic@0 538 * they should supply the maximum numbers for Ports and Channels
lbajardsilogic@0 539 * they expect to use.
lbajardsilogic@0 540 *
lbajardsilogic@0 541 * A plugin instance must call this function during instantiate().
lbajardsilogic@0 542 * [Sean says: this restriction seems reasonable to me, since
lbajardsilogic@0 543 * the host may need to create output ports, etc., and instantiate()
lbajardsilogic@0 544 * seems like a good place to do such things. I'm sure I haven't
lbajardsilogic@0 545 * fully thought through all the details, though....]
lbajardsilogic@0 546 *
lbajardsilogic@0 547 * The host should return a non-zero value if it is able to
lbajardsilogic@0 548 * provide MIDI send for the plugin instance, otherwise it should
lbajardsilogic@0 549 * return zero, and the plugin instance may not subsequently call
lbajardsilogic@0 550 * midi_send().
lbajardsilogic@0 551 *
lbajardsilogic@0 552 * A host which does not support the MIDI send function must set
lbajardsilogic@0 553 * both this member and (*midi_send)() below to NULL.
lbajardsilogic@0 554 */
lbajardsilogic@0 555 int (*request_midi_send)(LADSPA_Handle Instance,
lbajardsilogic@0 556 unsigned char Ports,
lbajardsilogic@0 557 unsigned char Channels);
lbajardsilogic@0 558
lbajardsilogic@0 559 /**
lbajardsilogic@0 560 * midi_send()
lbajardsilogic@0 561 *
lbajardsilogic@0 562 * This member is a function pointer by which a plugin actually
lbajardsilogic@0 563 * sends MIDI events to the host (provided it has received a non-
lbajardsilogic@0 564 * zero return from request_midi_send()). As in the run_synth()
lbajardsilogic@0 565 * functions, the Event pointer points to a block of EventCount
lbajardsilogic@0 566 * ALSA sequencer events. The dest.port and data.*.channel fields
lbajardsilogic@0 567 * of each event are used to specify destination port and channel,
lbajardsilogic@0 568 * respectively, when the plugin is supplying channelized events.
lbajardsilogic@0 569 *
lbajardsilogic@0 570 * A plugin may only call this function from within the execution
lbajardsilogic@0 571 * of the audio class run_*() or select_program() functions. When
lbajardsilogic@0 572 * called from a run_*() functions, the events are timestamped
lbajardsilogic@0 573 * relative to the start of the block, (mis)using the ALSA "tick
lbajardsilogic@0 574 * time" field as a frame count. The plugin is responsible for
lbajardsilogic@0 575 * ensuring that events with differing timestamps are already
lbajardsilogic@0 576 * ordered by time, and that timestamps across multiple calls to
lbajardsilogic@0 577 * midi_send() from within the same run_*() invocation are
lbajardsilogic@0 578 * monotonic. When midi_send() is called from within
lbajardsilogic@0 579 * select_program(), the timestamps are ignored, and the events
lbajardsilogic@0 580 * are considered to originate at the same frame time as the
lbajardsilogic@0 581 * select_program() call, if such a timing can be considered
lbajardsilogic@0 582 * meaningful.
lbajardsilogic@0 583 *
lbajardsilogic@0 584 * The memory pointed to by Event belongs to the plugin, and it is
lbajardsilogic@0 585 * the host's responsibility to copy the events as needed before
lbajardsilogic@0 586 * returning from the midi_send() call.
lbajardsilogic@0 587 *
lbajardsilogic@0 588 * A host which does not support the MIDI send function must set
lbajardsilogic@0 589 * both this member and (*request_midi_send)() above to NULL.
lbajardsilogic@0 590 */
lbajardsilogic@0 591 void (*midi_send)(LADSPA_Handle Instance,
lbajardsilogic@0 592 snd_seq_event_t *Event,
lbajardsilogic@0 593 unsigned long EventCount);
lbajardsilogic@0 594
lbajardsilogic@0 595 /**
lbajardsilogic@0 596 * . . . additional fields could follow here, possibly supporting:
lbajardsilogic@0 597 *
lbajardsilogic@0 598 * - a facility by which a plugin instance may request from a
lbajardsilogic@0 599 * host a non-realtime thread in which to do off-line
lbajardsilogic@0 600 * rendering, I/O, etc., thus (hopefully) avoiding the
lbajardsilogic@0 601 * crashes that seem to occur when plugins create their own
lbajardsilogic@0 602 * threads. I got this idea after noticing that ZynAddSubFX
lbajardsilogic@0 603 * achieves its gorgeous textures while remaining very
lbajardsilogic@0 604 * responsive by doing a lot of non-real-time rendering.
lbajardsilogic@0 605 * Several other uses for it have been mentioned on the DSSI
lbajardsilogic@0 606 * list; I forget what.
lbajardsilogic@0 607 *
lbajardsilogic@0 608 * - per-voice audio output
lbajardsilogic@0 609 */
lbajardsilogic@0 610
lbajardsilogic@0 611 int (*request_non_rt_thread)(LADSPA_Handle Instance,
lbajardsilogic@0 612 void (*RunFunction)(LADSPA_Handle Instance));
lbajardsilogic@0 613 };
lbajardsilogic@0 614
lbajardsilogic@0 615 /**
lbajardsilogic@0 616 * DSSI supports a plugin discovery method similar to that of LADSPA:
lbajardsilogic@0 617 *
lbajardsilogic@0 618 * - DSSI hosts may wish to locate DSSI plugin shared object files by
lbajardsilogic@0 619 * searching the paths contained in the DSSI_PATH and LADSPA_PATH
lbajardsilogic@0 620 * environment variables, if they are present. Both are expected
lbajardsilogic@0 621 * to be colon-separated lists of directories to be searched (in
lbajardsilogic@0 622 * order), and DSSI_PATH should be searched first if both variables
lbajardsilogic@0 623 * are set.
lbajardsilogic@0 624 *
lbajardsilogic@0 625 * - Each shared object file containing DSSI plugins must include a
lbajardsilogic@0 626 * function dssi_descriptor(), with the following function prototype
lbajardsilogic@0 627 * and C-style linkage. Hosts may enumerate the plugin types
lbajardsilogic@0 628 * available in the shared object file by repeatedly calling
lbajardsilogic@0 629 * this function with successive Index values (beginning from 0),
lbajardsilogic@0 630 * until a return value of NULL indicates no more plugin types are
lbajardsilogic@0 631 * available. Each non-NULL return is the DSSI_Descriptor
lbajardsilogic@0 632 * of a distinct plugin type.
lbajardsilogic@0 633 */
lbajardsilogic@0 634
lbajardsilogic@0 635 const DSSI_Descriptor *dssi_descriptor(unsigned long Index);
lbajardsilogic@0 636
lbajardsilogic@0 637 typedef const DSSI_Descriptor *(*DSSI_Descriptor_Function)(unsigned long Index);
lbajardsilogic@0 638
lbajardsilogic@0 639 /*
lbajardsilogic@0 640 * Macros to specify particular MIDI controllers in return values from
lbajardsilogic@0 641 * get_midi_controller_for_port()
lbajardsilogic@0 642 */
lbajardsilogic@0 643
lbajardsilogic@0 644 #define DSSI_CC_BITS 0x20000000
lbajardsilogic@0 645 #define DSSI_NRPN_BITS 0x40000000
lbajardsilogic@0 646
lbajardsilogic@0 647 #define DSSI_NONE -1
lbajardsilogic@0 648 #define DSSI_CONTROLLER_IS_SET(n) (DSSI_NONE != (n))
lbajardsilogic@0 649
lbajardsilogic@0 650 #define DSSI_CC(n) (DSSI_CC_BITS | (n))
lbajardsilogic@0 651 #define DSSI_IS_CC(n) (DSSI_CC_BITS & (n))
lbajardsilogic@0 652 #define DSSI_CC_NUMBER(n) ((n) & 0x7f)
lbajardsilogic@0 653
lbajardsilogic@0 654 #define DSSI_NRPN(n) (DSSI_NRPN_BITS | ((n) << 7))
lbajardsilogic@0 655 #define DSSI_IS_NRPN(n) (DSSI_NRPN_BITS & (n))
lbajardsilogic@0 656 #define DSSI_NRPN_NUMBER(n) (((n) >> 7) & 0x3fff)
lbajardsilogic@0 657
lbajardsilogic@0 658 #ifdef __cplusplus
lbajardsilogic@0 659 }
lbajardsilogic@0 660 #endif
lbajardsilogic@0 661
lbajardsilogic@0 662 #endif /* DSSI_INCLUDED */