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