1 /*
2 Copyright (C) 2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4 
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.
9 
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.
14 
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.
18 
19 */
20 
21 #ifndef __JackEngineControl__
22 #define __JackEngineControl__
23 
24 #include "JackShmMem.h"
25 #include "JackFrameTimer.h"
26 #include "JackTransportEngine.h"
27 #include "JackConstants.h"
28 #include "types.h"
29 #include <stdio.h>
30 
31 #ifdef JACK_MONITOR
32 #include "JackEngineProfiling.h"
33 #endif
34 
35 namespace Jack
36 {
37 
38 class JackClientInterface;
39 class JackGraphManager;
40 
41 #define JACK_ENGINE_ROLLING_COUNT 32
42 #define JACK_ENGINE_ROLLING_INTERVAL 1024
43 
44 /*!
45 \brief Engine control in shared memory.
46 */
47 
48 PRE_PACKED_STRUCTURE
49 struct SERVER_EXPORT JackEngineControl : public JackShmMem
50 {
51     // Shared state
52     jack_nframes_t fBufferSize;
53     jack_nframes_t fSampleRate;
54     bool fSyncMode;
55     bool fTemporary;
56     jack_time_t fPeriodUsecs;
57     jack_time_t fTimeOutUsecs;
58     float fMaxDelayedUsecs;
59     float fXrunDelayedUsecs;
60     bool fTimeOut;
61     bool fRealTime;
62     bool fSavedRealTime;  // RT state saved and restored during Freewheel mode
63     int fServerPriority;
64     int fClientPriority;
65     int fMaxClientPriority;
66     char fServerName[JACK_SERVER_NAME_SIZE+1];
67     JackTransportEngine fTransport;
68     jack_timer_type_t fClockSource;
69     int fDriverNum;
70     bool fVerbose;
71 
72     // CPU Load
73     jack_time_t fPrevCycleTime;
74     jack_time_t fCurCycleTime;
75     jack_time_t fSpareUsecs;
76     jack_time_t fMaxUsecs;
77     jack_time_t fRollingClientUsecs[JACK_ENGINE_ROLLING_COUNT];
78     unsigned int fRollingClientUsecsCnt;
79     int	fRollingClientUsecsIndex;
80     int	fRollingInterval;
81     float fCPULoad;
82 
83     // For OSX thread
84     UInt64 fPeriod;
85     UInt64 fComputation;
86     UInt64 fConstraint;
87 
88     // Timer
89     JackFrameTimer fFrameTimer;
90 
91 #ifdef JACK_MONITOR
92     JackEngineProfiling fProfiler;
93 #endif
94 
JackEngineControlJackEngineControl95     JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name)
96     {
97         fBufferSize = 512;
98         fSampleRate = 48000;
99         fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize);
100         fSyncMode = sync;
101         fTemporary = temporary;
102         fTimeOut = (timeout > 0);
103         fTimeOutUsecs = timeout * 1000;
104         fRealTime = rt;
105         fSavedRealTime = false;
106         fServerPriority = priority;
107 
108     #ifdef WIN32
109         fClientPriority = (rt) ? priority - 3 : 0;
110     #else
111         fClientPriority = (rt) ? priority - 5 : 0;
112     #endif
113         fMaxClientPriority = (rt) ? priority - 1 : 0;
114         fVerbose = verbose;
115         fPrevCycleTime = 0;
116         fCurCycleTime = 0;
117         fSpareUsecs = 0;
118         fMaxUsecs = 0;
119         ResetRollingUsecs();
120         strncpy(fServerName, server_name, sizeof(fServerName));
121         fServerName[sizeof(fServerName) - 1] = 0;
122         fCPULoad = 0.f;
123         fPeriod = 0;
124         fComputation = 0;
125         fConstraint = 0;
126         fMaxDelayedUsecs = 0.f;
127         fXrunDelayedUsecs = 0.f;
128         fClockSource = clock;
129         fDriverNum = 0;
130     }
131 
~JackEngineControlJackEngineControl132     ~JackEngineControl()
133     {}
134 
UpdateTimeOutJackEngineControl135     void UpdateTimeOut()
136     {
137         fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); // In microsec
138         if (!(fTimeOut && fTimeOutUsecs > 2 * fPeriodUsecs)) {
139             fTimeOutUsecs = 2 * fPeriodUsecs;
140         }
141     }
142 
143     // Cycle
CycleIncTimeJackEngineControl144     void CycleIncTime(jack_time_t callback_usecs)
145     {
146         // Timer
147         fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs);
148     }
149 
CycleBeginJackEngineControl150     void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end)
151     {
152         fTransport.CycleBegin(fSampleRate, cur_cycle_begin);
153         CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end);
154 #ifdef JACK_MONITOR
155         fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end);
156 #endif
157     }
158 
CycleEndJackEngineControl159     void CycleEnd(JackClientInterface** table)
160     {
161         fTransport.CycleEnd(table, fSampleRate, fBufferSize);
162     }
163 
164     // Timer
InitFrameTimeJackEngineControl165     void InitFrameTime()
166     {
167         fFrameTimer.InitFrameTime();
168     }
169 
ResetFrameTimeJackEngineControl170     void ResetFrameTime(jack_time_t callback_usecs)
171     {
172         fFrameTimer.ResetFrameTime(callback_usecs);
173     }
174 
ReadFrameTimeJackEngineControl175     void ReadFrameTime(JackTimer* timer)
176     {
177         fFrameTimer.ReadFrameTime(timer);
178     }
179 
180     // XRun
181     void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs);
ResetXRunJackEngineControl182     void ResetXRun()
183     {
184         fMaxDelayedUsecs = 0.f;
185     }
186 
187     // Private
188     void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end);
189     void ResetRollingUsecs();
190 
191 } POST_PACKED_STRUCTURE;
192 
193 } // end of namespace
194 
195 #endif
196