jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
9.0KB

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