annotate plugin/api/new_dssi_transport_patch @ 458:f60360209e5c

* Fix race condition in FFTFileCache when reading from the same FFT model from multiple threads (e.g. when applying more than one plugin at once)
author Chris Cannam
date Wed, 15 Oct 2008 12:08:02 +0000
parents da6937383da8
children
rev   line source
Chris@0 1 diff -r dssi-CVS-20051012=0.9.1/dssi/dssi.h _dssi-transport-mine-new/dssi/dssi.h
Chris@0 2 5,6c5,6
Chris@0 3 < DSSI version 0.9
Chris@0 4 < Copyright (c) 2004 Chris Cannam, Steve Harris and Sean Bolton
Chris@0 5 ---
Chris@0 6 > DSSI version 0.10
Chris@0 7 > Copyright (c) 2004,2005 Chris Cannam, Steve Harris and Sean Bolton
Chris@0 8 30c30
Chris@0 9 < #define DSSI_VERSION "0.9"
Chris@0 10 ---
Chris@0 11 > #define DSSI_VERSION "0.10"
Chris@0 12 32c32
Chris@0 13 < #define DSSI_VERSION_MINOR 9
Chris@0 14 ---
Chris@0 15 > #define DSSI_VERSION_MINOR 10
Chris@0 16 76a77,152
Chris@0 17 > #define DSSI_TRANSPORT_VALID_STATE 0x01
Chris@0 18 > #define DSSI_TRANSPORT_VALID_BPM 0x02
Chris@0 19 > #define DSSI_TRANSPORT_VALID_BBT 0x10
Chris@0 20 > #define DSSI_TRANSPORT_VALID_TIME 0x20
Chris@0 21 >
Chris@0 22 > #define DSSI_TRANSPORT_STATE_STOPPED 0
Chris@0 23 > #define DSSI_TRANSPORT_STATE_RUNNING 1
Chris@0 24 > #define DSSI_TRANSPORT_STATE_FREEWHEELING 2
Chris@0 25 > #define DSSI_TRANSPORT_STATE_OTHER 3 /* waiting for sync, ? */
Chris@0 26 >
Chris@0 27 > typedef struct _DSSI_Transport_Info {
Chris@0 28 >
Chris@0 29 > /** The value of this field indicates which of the following
Chris@0 30 > * transport information fields contain valid values. It is
Chris@0 31 > * the logical OR of the DSSI_TRANSPORT_VALID_* bits defined
Chris@0 32 > * above, and may be zero. */
Chris@0 33 > int Valid;
Chris@0 34 >
Chris@0 35 >
Chris@0 36 > /** This field is valid when (Valid & DSSI_TRANSPORT_VALID_STATE)
Chris@0 37 > * is true:
Chris@0 38 > *
Chris@0 39 > * ---- The current transport state, one of the DSSI_TRANSPORT_STATE_*
Chris@0 40 > * values defined above. */
Chris@0 41 > int State;
Chris@0 42 >
Chris@0 43 >
Chris@0 44 > /** This field is valid when (Valid & DSSI_TRANSPORT_VALID_BPM)
Chris@0 45 > * is true:
Chris@0 46 > *
Chris@0 47 > * ---- The current tempo, in beats per minute. */
Chris@0 48 > double Beats_Per_Minute;
Chris@0 49 >
Chris@0 50 >
Chris@0 51 > /** These six fields are valid when (Valid & DSSI_TRANSPORT_VALID_BBT)
Chris@0 52 > * is true:
Chris@0 53 > *
Chris@0 54 > * ---- The bar number at the beginning of the current process cycle. */
Chris@0 55 > unsigned long Bar;
Chris@0 56 >
Chris@0 57 > * ---- The beat within that Bar. */
Chris@0 58 > unsigned long Beat;
Chris@0 59 >
Chris@0 60 > /** ---- The tick within that Beat. */
Chris@0 61 > unsigned long Tick;
Chris@0 62 >
Chris@0 63 > /** ---- The (possibly fractional) tick count since transport 'start'
Chris@0 64 > * and the beginning of the current Bar. */
Chris@0 65 > double Bar_Start_Tick;
Chris@0 66 >
Chris@0 67 > /** ---- The number of beats per bar. */
Chris@0 68 > float Beats_Per_Bar;
Chris@0 69 >
Chris@0 70 > /** ---- The number of ticks for each beat. */
Chris@0 71 > double Ticks_Per_Beat;
Chris@0 72 >
Chris@0 73 > /* [Sean says: I left out the 'beat_type' (time signature "denominator")
Chris@0 74 > * field of the jack_position_t structure, because I think it's useless
Chris@0 75 > * except to a notation program. Does anybody else feel like we need it?]
Chris@0 76 >
Chris@0 77 >
Chris@0 78 > /** These two fields are valid when (Valid & DSSI_TRANSPORT_VALID_TIME)
Chris@0 79 > * is true:
Chris@0 80 > *
Chris@0 81 > * ---- The transport time at the beginning of the current process
Chris@0 82 > * cycle, in seconds. */
Chris@0 83 > double Current_Time;
Chris@0 84 >
Chris@0 85 > /** ---- The transport time at the beginning of the next process
Chris@0 86 > cycle, unless repositioning occurs. */
Chris@0 87 > double Next_Time;
Chris@0 88 >
Chris@0 89 > } DSSI_Transport_Info;
Chris@0 90 >
Chris@0 91 > typedef struct _DSSI_Host_Descriptor DSSI_Host_Descriptor; /* below */
Chris@0 92 >
Chris@0 93 83,84c159,161
Chris@0 94 < * If we're lucky, this will never be needed. For now all plugins
Chris@0 95 < * must set it to 1.
Chris@0 96 ---
Chris@0 97 > * All plugins must set this to 1 or 2. The version 1 API contains
Chris@0 98 > * all DSSI_Descriptor fields through run_multiple_synths_adding(),
Chris@0 99 > * while the version 2 API adds the receive_host_descriptor().
Chris@0 100 376a454,472
Chris@0 101 >
Chris@0 102 > /**
Chris@0 103 > * receive_host_descriptor()
Chris@0 104 > *
Chris@0 105 > * This member is a function pointer by which a host may provide
Chris@0 106 > * a plugin with a pointer to its DSSI_Host_Descriptor. Hosts
Chris@0 107 > * which provide host descriptor support must call this function
Chris@0 108 > * once per plugin shared object file, before any calls to
Chris@0 109 > * instantiate().
Chris@0 110 > *
Chris@0 111 > * NOTE: This field was added in version 2 of the DSSI API. Hosts
Chris@0 112 > * supporting version 2 must not access this field in a plugin
Chris@0 113 > * whose DSSI_API_Version is 1, and plugins supporting version 2
Chris@0 114 > * should behave reasonably under hosts (of any version) which do
Chris@0 115 > * not implement this function. A version 2 plugin that does not
Chris@0 116 > * provide this function must set this member to NULL.
Chris@0 117 > */
Chris@0 118 > void (*receive_host_descriptor)(DSSI_Host_Descriptor *Descriptor);
Chris@0 119 >
Chris@0 120 377a474,598
Chris@0 121 >
Chris@0 122 > struct _DSSI_Host_Descriptor {
Chris@0 123 >
Chris@0 124 > /**
Chris@0 125 > * DSSI_API_Version
Chris@0 126 > *
Chris@0 127 > * This member indicates the DSSI API level used by this host.
Chris@0 128 > * All hosts must set this to 2. Hopefully, we'll get this right
Chris@0 129 > * the first time, and this will never be needed.
Chris@0 130 > */
Chris@0 131 > int DSSI_API_Version;
Chris@0 132 >
Chris@0 133 > /**
Chris@0 134 > * request_tranport_information()
Chris@0 135 > *
Chris@0 136 > * This member is a function pointer by which a plugin instance may
Chris@0 137 > * request that a host begin providing transport information (if
Chris@0 138 > * Request is non-zero), or notify the host that it no longer needs
Chris@0 139 > * transport information (if Request is zero). Upon receiving a
Chris@0 140 > * non-zero request, the host should return a pointer to a
Chris@0 141 > * DSSI_Transport_Info structure if it is able to provide transport
Chris@0 142 > * information, or NULL otherwise.
Chris@0 143 > *
Chris@0 144 > * Once a plugin instance has received a non-null transport
Chris@0 145 > * information pointer, it may read from the structure at any time
Chris@0 146 > * within the execution of an audio class function (see doc/RFC.txt).
Chris@0 147 > * It should not consider the structure contents to be meaningful
Chris@0 148 > * while within a instantiation or control class function. Also,
Chris@0 149 > * since the validity of fields within the structure may change
Chris@0 150 > * between each new invocation of an audio class function, a plugin
Chris@0 151 > * instance must check the Valid field of the structure accordingly
Chris@0 152 > * before using the structure's other contents.
Chris@0 153 > *
Chris@0 154 > * A host which does not support this function must set this member
Chris@0 155 > * to NULL.
Chris@0 156 > */
Chris@0 157 > DSSI_Transport_Info *
Chris@0 158 > (*request_transport_information)(LADSPA_Handle Instance,
Chris@0 159 > int Request);
Chris@0 160 >
Chris@0 161 > /**
Chris@0 162 > * request_midi_send()
Chris@0 163 > *
Chris@0 164 > * This member is a function pointer that allows a plugin to
Chris@0 165 > * request the ability to send MIDI events to the host.
Chris@0 166 > *
Chris@0 167 > * While the interpretation of plugin-generated MIDI events is
Chris@0 168 > * host implementation specific, a mechanism exists by which a
Chris@0 169 > * plugin may declare to the host the number of destination
Chris@0 170 > * 'ports' and MIDI channels it can expect will be used in the
Chris@0 171 > * plugin-generated events. Plugins which generate unchannelized
Chris@0 172 > * MIDI should supply zero for both Ports and Channels, otherwise
Chris@0 173 > * they should supply the maximum numbers for Ports and Channels
Chris@0 174 > * they expect to use.
Chris@0 175 > *
Chris@0 176 > * A plugin instance must call this function during instantiate().
Chris@0 177 > * [Sean says: this restriction seems reasonable to me, since
Chris@0 178 > * the host may need to create output ports, etc., and instantiate()
Chris@0 179 > * seems like a good place to do such things. I'm sure I haven't
Chris@0 180 > * fully thought through all the details, though....]
Chris@0 181 > *
Chris@0 182 > * The host should return a non-zero value if it is able to
Chris@0 183 > * provide MIDI send for the plugin instance, otherwise it should
Chris@0 184 > * return zero, and the plugin instance may not subsequently call
Chris@0 185 > * midi_send().
Chris@0 186 > *
Chris@0 187 > * A host which does not support the MIDI send function must set
Chris@0 188 > * both this member and (*midi_send)() below to NULL.
Chris@0 189 > */
Chris@0 190 > int (*request_midi_send)(LADSPA_Handle Instance,
Chris@0 191 > unsigned char Ports,
Chris@0 192 > unsigned char Channels);
Chris@0 193 >
Chris@0 194 > /**
Chris@0 195 > * midi_send()
Chris@0 196 > *
Chris@0 197 > * This member is a function pointer by which a plugin actually
Chris@0 198 > * sends MIDI events to the host (provided it has received a non-
Chris@0 199 > * zero return from request_midi_send()). As in the run_synth()
Chris@0 200 > * functions, the Event pointer points to a block of EventCount
Chris@0 201 > * ALSA sequencer events. The dest.port and data.*.channel fields
Chris@0 202 > * of each event are used to specify destination port and channel,
Chris@0 203 > * respectively, when the plugin is supplying channelized events.
Chris@0 204 > *
Chris@0 205 > * A plugin may only call this function from within the execution
Chris@0 206 > * of the audio class run_*() or select_program() functions. When
Chris@0 207 > * called from a run_*() functions, the events are timestamped
Chris@0 208 > * relative to the start of the block, (mis)using the ALSA "tick
Chris@0 209 > * time" field as a frame count. The plugin is responsible for
Chris@0 210 > * ensuring that events with differing timestamps are already
Chris@0 211 > * ordered by time, and that timestamps across multiple calls to
Chris@0 212 > * midi_send() from within the same run_*() invocation are
Chris@0 213 > * monotonic. When midi_send() is called from within
Chris@0 214 > * select_program(), the timestamps are ignored, and the events
Chris@0 215 > * are considered to originate at the same frame time as the
Chris@0 216 > * select_program() call, if such a timing can be considered
Chris@0 217 > * meaningful.
Chris@0 218 > *
Chris@0 219 > * The memory pointed to by Event belongs to the plugin, and it is
Chris@0 220 > * the host's responsibility to copy the events as needed before
Chris@0 221 > * returning from the midi_send() call.
Chris@0 222 > *
Chris@0 223 > * A host which does not support the MIDI send function must set
Chris@0 224 > * both this member and (*request_midi_send)() above to NULL.
Chris@0 225 > */
Chris@0 226 > void (*midi_send)(LADSPA_Handle Instance,
Chris@0 227 > snd_seq_event_t *Event,
Chris@0 228 > unsigned long EventCount);
Chris@0 229 >
Chris@0 230 > /**
Chris@0 231 > * . . . additional fields could follow here, possibly supporting:
Chris@0 232 > *
Chris@0 233 > * - a facility by which a plugin instance may request from a
Chris@0 234 > * host a non-realtime thread in which to do off-line
Chris@0 235 > * rendering, I/O, etc., thus (hopefully) avoiding the
Chris@0 236 > * crashes that seem to occur when plugins create their own
Chris@0 237 > * threads. I got this idea after noticing that ZynAddSubFX
Chris@0 238 > * achieves its gorgeous textures while remaining very
Chris@0 239 > * responsive by doing a lot of non-real-time rendering.
Chris@0 240 > * Several other uses for it have been mentioned on the DSSI
Chris@0 241 > * list; I forget what.
Chris@0 242 > *
Chris@0 243 > * - per-voice audio output
Chris@0 244 > */
Chris@0 245 > };