jack2 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.

202 lines
5.4KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2004-2008 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #ifndef __JackTransportEngine__
  17. #define __JackTransportEngine__
  18. #include "JackAtomicArrayState.h"
  19. #include "JackCompilerDeps.h"
  20. #include "types.h"
  21. namespace Jack
  22. {
  23. typedef enum {
  24. TransportCommandNone = 0,
  25. TransportCommandStart = 1,
  26. TransportCommandStop = 2,
  27. } transport_command_t;
  28. /*!
  29. \brief The client transport structure.
  30. We have:
  31. - a "current" position
  32. - a "pending" position prepared by the server at each cycle
  33. - a "request" position wanted by a client
  34. At the beginning of a cycle the server needs to select a new current position. When a request and a pending position are available,
  35. the request takes precedence on the pending one. The server atomically switches to the new position.
  36. The current position can be read by clients.
  37. We use a JackAtomicArrayState pattern that allows to manage several "next" states independently.
  38. In jack1 implementation, transport code (jack_transport_cycle_end) was not called if the graph could not be locked (see jack_run_one_cycle).
  39. Here transport cycle (CycleBegin, CycleEnd) has to run in the RT thread concurrently with code executed from the "command" thread.
  40. Each client maintains a state in it's shared memory area defined by:
  41. - it's current transport state
  42. - a boolean that is "true" when slow-sync cb has to be called
  43. - a boolean that is "true" when timebase cb is called with new_pos on
  44. Several operations set the "slow-sync cb" flag to true:
  45. - setting a new cb (client)
  46. - activate (client)
  47. - transport start (server)
  48. - new pos (server)
  49. Slow-sync cb calls stops when:
  50. - the cb return true (client)
  51. - deactivate (client)
  52. - transport stop (server)
  53. Several operations set the "timebase cb" flag to true:
  54. - setting a new cb (client)
  55. - activate (client)
  56. - transport start (server) ??
  57. - new pos (server)
  58. Timebase cb "new_pos" argument calls stops when:
  59. - after one cb call with "new_pos" argument true (client)
  60. - deactivate (client)
  61. - release (client)
  62. - transport stop (server)
  63. */
  64. class JackClientInterface;
  65. PRE_PACKED_STRUCTURE
  66. class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState<jack_position_t>
  67. {
  68. private:
  69. jack_transport_state_t fTransportState;
  70. volatile transport_command_t fTransportCmd;
  71. transport_command_t fPreviousCmd; /* previous transport_cmd */
  72. jack_time_t fSyncTimeout;
  73. int fSyncTimeLeft;
  74. int fTimeBaseMaster;
  75. bool fPendingPos;
  76. bool fNetworkSync;
  77. bool fConditionnal;
  78. alignas(SInt32) SInt32 fWriteCounter;
  79. bool CheckAllRolling(JackClientInterface** table);
  80. void MakeAllStartingLocating(JackClientInterface** table);
  81. void MakeAllStopping(JackClientInterface** table);
  82. void MakeAllLocating(JackClientInterface** table);
  83. void SyncTimeout(jack_nframes_t frame_rate, jack_nframes_t buffer_size);
  84. public:
  85. JackTransportEngine();
  86. ~JackTransportEngine()
  87. {}
  88. void SetCommand(transport_command_t state)
  89. {
  90. fTransportCmd = state;
  91. }
  92. jack_transport_state_t GetState() const
  93. {
  94. return fTransportState;
  95. }
  96. void SetState(jack_transport_state_t state)
  97. {
  98. fTransportState = state;
  99. }
  100. /*
  101. \brief
  102. */
  103. int ResetTimebase(int refnum);
  104. /*
  105. \brief
  106. */
  107. int SetTimebaseMaster(int refnum, bool conditionnal);
  108. void GetTimebaseMaster(int& refnum, bool& conditionnal)
  109. {
  110. refnum = fTimeBaseMaster;
  111. conditionnal = fConditionnal;
  112. }
  113. /*
  114. \brief
  115. */
  116. void CycleBegin(jack_nframes_t frame_rate, jack_time_t time);
  117. /*
  118. \brief
  119. */
  120. void CycleEnd(JackClientInterface** table, jack_nframes_t frame_rate, jack_nframes_t buffer_size);
  121. /*
  122. \brief
  123. */
  124. void SetSyncTimeout(jack_time_t timeout)
  125. {
  126. fSyncTimeout = timeout;
  127. }
  128. void ReadCurrentPos(jack_position_t* pos);
  129. jack_unique_t GenerateUniqueID()
  130. {
  131. return (jack_unique_t)INC_ATOMIC(&fWriteCounter);
  132. }
  133. void RequestNewPos(jack_position_t* pos);
  134. jack_transport_state_t Query(jack_position_t* pos);
  135. jack_nframes_t GetCurrentFrame();
  136. static void CopyPosition(jack_position_t* from, jack_position_t* to);
  137. bool GetNetworkSync() const
  138. {
  139. return fNetworkSync;
  140. }
  141. void SetNetworkSync(bool sync)
  142. {
  143. fNetworkSync = sync;
  144. }
  145. } POST_PACKED_STRUCTURE;
  146. } // end of namespace
  147. #endif