~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
JACK/doc/transport.dox


  1 /*
  2  * This file documents the JACK transport design.  It is part of the
  3  * JACK reference manual, built using doxygen.
  4  */
  5 
  6 /**
  7 
  8 @page transport-design JACK Transport Design
  9 
 10 The @ref index provides simple transport interfaces for starting,
 11 stopping and repositioning a set of clients.  This document describes
 12 the overall design of these interfaces, their detailed specifications
 13 are in <jack/transport.h>
 14 
 15   - @ref requirements
 16   - @ref overview
 17   - @ref timebase
 18   - @ref transportcontrol
 19   - @ref transportclients
 20   - @ref compatibility
 21   - @ref issues
 22 
 23 
 24 @subsection requirements Requirements
 25 
 26   - We need sample-level accuracy for transport control.  This implies
 27   that the transport client logic has to be part of the realtime
 28   process chain.
 29 
 30   - We don't want to add another context switch.  So, the transport
 31   client logic has to run in the context of the client's process
 32   thread.  To avoid making an extra pass through the process graph, no
 33   transport changes take effect until the following process cycle.
 34   That way, the transport info is stable throughout each cycle.
 35 
 36   - We want to allow multiple clients to change the transport state.
 37   This is mostly a usability issue.  Any client can start or stop
 38   playback, or seek to a new location.  The user need not switch
 39   windows to accomplish these tasks.
 40 
 41   - We want a way for clients with heavyweight state to sync up when
 42   the user presses "play", before the transport starts rolling.
 43 
 44   - We want to provide for ongoing binary compatibility as the
 45   transport design evolves.
 46 
 47 
 48 @subsection overview Overview
 49 
 50 The former transport master role has been divided into two layers:
 51 
 52   - @ref timebase - counting beats, frames, etc. on every cycle.
 53   - @ref transportcontrol - start, stop and reposition the playback.  
 54 
 55 Existing transport clients continue to work in compatibility mode.
 56 But, old-style timebase masters will no longer control the transport.
 57 
 58 
 59 @subsection timebase Timebase Master
 60 
 61 The timebase master continuously updates extended position
 62 information, counting beats, timecode, etc.  Without this extended
 63 information, there is no need for this function.  There is at most one
 64 master active at a time.  If no client is registered as timebase
 65 master, frame numbers will be the only position information available.
 66 
 67 The timebase master registers a callback that updates position
 68 information while the transport is rolling.  Its output affects the
 69 following process cycle.  This function is called immediately after
 70 the process callback in the same thread whenever the transport is
 71 rolling, or when any client has set a new position in the previous
 72 cycle.  The first cycle after jack_set_timebase_callback() is also
 73 treated as a new position, or the first cycle after jack_activate() if
 74 the client had been inactive.
 75 
 76 @code
 77   typedef int  (*JackTimebaseCallback)(jack_transport_state_t state,
 78                                        jack_nframes_t nframes,
 79                                        jack_position_t *pos,
 80                                        int new_pos,
 81                                        void *arg);
 82 @endcode
 83 
 84 When a new client takes over, the former timebase callback is no
 85 longer called.  Taking over the timebase may be done conditionally, in
 86 which case the takeover fails when there is a master already.  The
 87 existing master can release it voluntarily, if desired.
 88 
 89 @code
 90   int  jack_set_timebase_callback (jack_client_t *client,
 91                                    int conditional,
 92                                    JackTimebaseCallback timebase_callback,
 93                                    void *arg);
 94 
 95   int  jack_release_timebase(jack_client_t *client);
 96 @endcode
 97 
 98 If the timebase master releases the timebase or exits the JACK graph
 99 for any reason, the JACK engine takes over at the start of the next
100 process cycle.  The transport state does not change.  If rolling, it
101 continues to play, with frame numbers as the only available position
102 information.
103 
104 
105 @subsection transportcontrol Transport Control
106 
107 The JACK engine itself manages stopping and starting of the transport.
108 Any client can make transport control requests at any time.  These
109 requests take effect no sooner than the next process cycle, sometimes
110 later.  The transport state is always valid, initially it is
111 ::JackTransportStopped.
112 
113 @code
114   void jack_transport_start (jack_client_t *client);
115   void jack_transport_stop (jack_client_t *client);
116 @endcode
117 
118 The engine handles polling of slow-sync clients.  When someone calls
119 jack_transport_start(), the engine resets the poll bits and changes to
120 a new state, ::JackTransportStarting.  The @a sync_callback function
121 for each slow-sync client will be invoked in the JACK process thread
122 while the transport is starting.  If it has not already done so, the
123 client needs to initiate a seek to reach the starting position.  The
124 @a sync_callback returns false until the seek completes and the client
125 is ready to play.  When all slow-sync clients are ready, the state
126 changes to ::JackTransportRolling.
127 
128 @code
129   typedef int  (*JackSyncCallback)(jack_transport_state_t state,
130                                    jack_position_t *pos, void *arg);
131 @endcode
132 
133 This callback is a realtime function that runs in the JACK process
134 thread.
135 
136 @code
137   int  jack_set_sync_callback (jack_client_t *client,
138                                JackSyncCallback sync_callback, void *arg);
139 @endcode
140 
141 Clients that don't declare a @a sync_callback are assumed to be ready
142 immediately, any time the transport wants to start.  If a client no
143 longer requires slow-sync processing, it can set its @a sync_callback
144 to NULL.
145 
146 @code
147   int  jack_set_sync_timeout (jack_client_t *client,
148                               jack_time_t usecs);
149 @endcode
150 
151 There must be a @a timeout to prevent unresponsive slow-sync clients
152 from completely halting the transport mechanism.  Two seconds is the
153 default.  When this @a timeout expires, the transport will start
154 rolling, even if some slow-sync clients are still unready.  The @a
155 sync_callback for these clients continues being invoked, giving them
156 an opportunity to catch up.
157 
158 @code
159   int  jack_transport_reposition (jack_client_t *client,
160                                   jack_position_t *pos);
161   int  jack_transport_locate (jack_client_t *client,
162                               jack_nframes_t frame);
163 @endcode
164 
165 These request a new transport position.  They can be called at any
166 time by any client.  Even the timebase master must use them.  If the
167 request is valid, it goes into effect in two process cycles.  If there
168 are slow-sync clients and the transport is already rolling, it will
169 enter the ::JackTransportStarting state and begin invoking their @a
170 sync_callbacks until ready.
171 
172 
173 @image html     fsm.png "Transport State Transition Diagram"
174 @image latex    fsm.eps "Transport State Transition Diagram"
175 
176 
177 @subsection transportclients Transport Clients
178 
179 Transport clients were formerly known as "transport slaves".  We want
180 to make it easy for almost every JACK client to be a transport client.
181 
182 @code
183    jack_transport_state_t jack_transport_query (jack_client_t *client,
184                                                 jack_position_t *pos);
185 @endcode
186 
187 This function can be called from any thread.  If called from the
188 process thread, @a pos corresponds to the first frame of the current
189 cycle and the state returned is valid for the entire cycle.
190 
191 
192 @subsection compatibility Compatibility
193 
194 During the transition period we will support the old-style interfaces
195 in compatibility mode as deprecated interfaces.  This compatibility is
196 not 100%, there are limitations.  
197 
198 The main reasons for doing this are:
199 
200   - facilitate testing with clients that already have transport
201   support
202   - provide a clean migration path, so application developers are
203   not discouraged from supporting the transport interface
204 
205 These deprecated interfaces continue to work:
206 
207 @code
208   typedef struct jack_transport_info_t;
209 
210   void jack_get_transport_info (jack_client_t *client,
211                                 jack_transport_info_t *tinfo);
212 @endcode
213 
214 Unfortunately, the old-style timebase master interface cannot coexist
215 cleanly with such new features as jack_transport_locate() and
216 slow-sync clients.  So, these interfaces are only present as stubs:
217 
218 @code
219   void jack_set_transport_info (jack_client_t *client,
220                                 jack_transport_info_t *tinfo);
221   int  jack_engine_takeover_timebase (jack_client_t *);
222 @endcode
223 
224 For compatibility with future changes, it would be good to avoid
225 structures entirely.  Nevertheless, the jack_position_t structure
226 provides a convenient way to collect timebase information in several
227 formats that clearly all refer to a single moment.  To minimize future
228 binary compatibility problems, this structure has some padding at the
229 end, making it possible to extend it without necessarily breaking
230 compatibility.  New fields can be allocated from the padding area,
231 with access controlled by newly defined valid bits, all of which are
232 currently forced to zero.  That allows the structure size and offsets
233 to remain constant.
234 
235 
236 @subsection issues Issues Not Addressed
237 
238 This design currently does not address several issues. This means they
239 will probably not be included in JACK release 1.0.
240 
241   - variable speed
242   - reverse play
243   - looping
244 */

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.