Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson).
[jack2.git] / common / JackTransportEngine.h
bloba1ff2b9750cd835fa3bb83056bb80bfff283f45d
1 /*
2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2008 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #ifndef __JackTransportEngine__
22 #define __JackTransportEngine__
24 #include "JackAtomicArrayState.h"
25 #include "JackCompilerDeps.h"
26 #include "types.h"
28 namespace Jack
31 typedef enum {
32 TransportCommandNone = 0,
33 TransportCommandStart = 1,
34 TransportCommandStop = 2,
35 } transport_command_t;
37 /*!
38 \brief The client transport structure.
40 We have:
42 - a "current" position
43 - a "pending" position prepared by the server at each cycle
44 - a "request" position wanted by a client
46 At the beginning of a cycle the server needs to select a new current position. When a request and a pending position are available,
47 the request takes precedence on the pending one. The server atomically switches to the new position.
48 The current position can be read by clients.
50 We use a JackAtomicArrayState pattern that allows to manage several "next" states independantly.
52 In jack1 implementation, transport code (jack_transport_cycle_end) was not called if the graph could not be locked (see jack_run_one_cycle).
53 Here transport cycle (CycleBegin, CycleEnd) has to run in the RT thread concurrently with code executed from the "command" thread.
55 Each client maintains a state in it's shared memory area defined by:
57 - it's current transport state
58 - a boolean that is "true" when slow-sync cb has to be called
59 - a boolean that is "true" when timebase cb is called with new_pos on
61 Several operations set the "slow-sync cb" flag to true:
63 - setting a new cb (client)
64 - activate (client)
65 - transport start (server)
66 - new pos (server)
68 Slow-sync cb calls stops when:
70 - the cb return true (client)
71 - desactivate (client)
72 - transport stop (server)
74 Several operations set the "timebase cb" flag to true:
76 - setting a new cb (client)
77 - activate (client)
78 - transport start (server) ??
79 - new pos (server)
81 Timebase cb "new_pos" argument calls stops when:
83 - after one cb call with "new_pos" argument true (client)
84 - desactivate (client)
85 - release (client)
86 - transport stop (server)
90 class JackClientInterface;
92 class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState<jack_position_t>
95 private:
97 jack_transport_state_t fTransportState;
98 volatile transport_command_t fTransportCmd;
99 transport_command_t fPreviousCmd; /* previous transport_cmd */
100 jack_time_t fSyncTimeout;
101 int fSyncTimeLeft;
102 int fTimeBaseMaster;
103 bool fPendingPos;
104 bool fNetworkSync;
105 bool fConditionnal;
106 SInt32 fWriteCounter;
108 bool CheckAllRolling(JackClientInterface** table);
109 void MakeAllStartingLocating(JackClientInterface** table);
110 void MakeAllStopping(JackClientInterface** table);
111 void MakeAllLocating(JackClientInterface** table);
113 void SyncTimeout(jack_nframes_t frame_rate, jack_nframes_t buffer_size);
115 public:
117 JackTransportEngine();
119 ~JackTransportEngine()
122 void SetCommand(transport_command_t state)
124 fTransportCmd = state;
127 jack_transport_state_t GetState() const
129 return fTransportState;
132 void SetState(jack_transport_state_t state)
134 fTransportState = state;
138 \brief
140 int ResetTimebase(int refnum);
143 \brief
145 int SetTimebaseMaster(int refnum, bool conditionnal);
147 void GetTimebaseMaster(int& refnum, bool& conditionnal)
149 refnum = fTimeBaseMaster;
150 conditionnal = fConditionnal;
154 \brief
156 void CycleBegin(jack_nframes_t frame_rate, jack_time_t time);
159 \brief
161 void CycleEnd(JackClientInterface** table, jack_nframes_t frame_rate, jack_nframes_t buffer_size);
164 \brief
166 void SetSyncTimeout(jack_time_t timeout)
168 fSyncTimeout = timeout;
171 void ReadCurrentPos(jack_position_t* pos);
173 jack_unique_t GenerateUniqueID()
175 return (jack_unique_t)INC_ATOMIC(&fWriteCounter);
178 void RequestNewPos(jack_position_t* pos);
180 jack_transport_state_t Query(jack_position_t* pos);
182 jack_nframes_t GetCurrentFrame();
184 static void CopyPosition(jack_position_t* from, jack_position_t* to);
186 bool GetNetworkSync() const
188 return fNetworkSync;
191 void SetNetworkSync(bool sync)
193 fNetworkSync = sync;
196 } POST_PACKED_STRUCTURE;
198 } // end of namespace
200 #endif