summaryrefslogtreecommitdiff
path: root/common/JackTransportEngine.h
blob: 4df41ae8a1b6fb441f5f10c4e8fcb21c3886231e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
Copyright (C) 2001 Paul Davis 
Copyright (C) 2004-2008 Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __JackTransportEngine__
#define __JackTransportEngine__

#include "transport_types.h"
#include "JackClientInterface.h"
#include "JackConstants.h"
#include "JackAtomicArrayState.h"

namespace Jack
{

typedef enum {
    TransportCommandNone = 0,
    TransportCommandStart = 1,
    TransportCommandStop = 2,
} transport_command_t;

/*!
\brief The client transport structure.
 
We have:
 
	- a "current" position
	- a "pending" position prepared by the server at each cycle
	- a "request" position wanted by a client
	
	At the beginning of a cycle the server needs to select a new current position. When a request and a pending position are available,
	the resquest takes precedence on the pending one. The server atomically switches to the new position. 
	The current position can be read by clients.
	
	We use a JackAtomicArrayState pattern that allows to manage several "next" states independantly.
*/

class JackTransportEngine : public JackAtomicArrayState<jack_position_t>
{

    private:

        jack_transport_state_t fTransportState;
        volatile transport_command_t fTransportCmd;
        transport_command_t fPreviousCmd;		/* previous transport_cmd */
        jack_time_t fSyncTimeout;
        int fSyncTimeLeft;
        int fTimeBaseMaster;
        bool fPendingPos;
        SInt32 fWriteCounter;

        bool CheckOneSynching(JackClientInterface** table);
        bool CheckAllRolling(JackClientInterface** table);
        void MakeAllStarting(JackClientInterface** table);
        void SyncTimeout(jack_nframes_t frame_rate, jack_nframes_t buffer_size);

    public:

        JackTransportEngine();

        ~JackTransportEngine()
        {}

        void SetCommand(transport_command_t state)
        {
            fTransportCmd = state;
        }

        jack_transport_state_t GetState() const
        {
            return fTransportState;
        }

        int GetTimebaseMaster() const
        {
            return fTimeBaseMaster;
        }

        /*
        	\brief 
        */
        int ResetTimebase(int refnum);

        /*
        	\brief 
        */
        int SetTimebase(int refnum, bool conditionnal);

        /*
        	\brief 
        */
        void CycleBegin(jack_nframes_t frame_rate, jack_time_t time);

        /*
        	\brief 
        */
        void CycleEnd(JackClientInterface** table, jack_nframes_t frame_rate, jack_nframes_t buffer_size);

        /*
        	\brief 
        */
        void SetSyncTimeout(jack_time_t timeout)
        {
            fSyncTimeout = timeout;
        }

        void ReadCurrentPos(jack_position_t* pos);

        jack_unique_t GenerateUniqueID()
        {
            return (jack_unique_t)INC_ATOMIC(&fWriteCounter);
        }

        static void TransportCopyPosition(jack_position_t* from, jack_position_t* to);

};


} // end of namespace

#endif