Better isolation of server and clients system resources to allow starting the server...
[jack2.git] / common / JackDriver.cpp
blob79aec5996e803efe2c7e8ba49c77ca825957be38
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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "JackSystemDeps.h"
22 #include "JackDriver.h"
23 #include "JackTime.h"
24 #include "JackError.h"
25 #include "JackPort.h"
26 #include "JackGraphManager.h"
27 #include "JackGlobals.h"
28 #include "JackEngineControl.h"
29 #include "JackClientControl.h"
30 #include "JackLockedEngine.h"
31 #include <math.h>
32 #include <assert.h>
34 using namespace std;
36 namespace Jack
39 JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
40 :fClientControl(name)
42 assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
43 fSynchroTable = table;
44 strcpy(fAliasName, alias);
45 fEngine = engine;
46 fGraphManager = NULL;
47 fBeginDateUst = 0;
48 fDelayedUsecs = 0.f;
49 fIsMaster = true;
52 JackDriver::JackDriver()
54 fSynchroTable = NULL;
55 fEngine = NULL;
56 fGraphManager = NULL;
57 fBeginDateUst = 0;
58 fIsMaster = true;
61 JackDriver::~JackDriver()
63 jack_log("~JackDriver");
66 int JackDriver::Open()
68 int refnum = -1;
70 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
71 jack_error("Cannot allocate internal client for audio driver");
72 return -1;
75 fClientControl.fRefNum = refnum;
76 fClientControl.fActive = true;
77 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode
78 SetupDriverSync(fClientControl.fRefNum, false);
79 return 0;
82 int JackDriver::Open(jack_nframes_t buffer_size,
83 jack_nframes_t samplerate,
84 bool capturing,
85 bool playing,
86 int inchannels,
87 int outchannels,
88 bool monitor,
89 const char* capture_driver_name,
90 const char* playback_driver_name,
91 jack_nframes_t capture_latency,
92 jack_nframes_t playback_latency)
94 jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name);
95 jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name);
96 int refnum = -1;
98 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
99 jack_error("Cannot allocate internal client for audio driver");
100 return -1;
103 fClientControl.fRefNum = refnum;
104 fClientControl.fActive = true;
105 fEngineControl->fBufferSize = buffer_size;
106 fEngineControl->fSampleRate = samplerate;
107 fCaptureLatency = capture_latency;
108 fPlaybackLatency = playback_latency;
110 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
111 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
113 strcpy(fCaptureDriverName, capture_driver_name);
114 strcpy(fPlaybackDriverName, playback_driver_name);
116 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
117 if (!fEngineControl->fTimeOut)
118 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
120 fGraphManager->SetBufferSize(buffer_size);
121 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode
122 SetupDriverSync(fClientControl.fRefNum, false);
123 return 0;
126 int JackDriver::Close()
128 jack_log("JackDriver::Close");
129 fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync
130 fClientControl.fActive = false;
131 return fEngine->ClientInternalClose(fClientControl.fRefNum, false);
135 In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
136 The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
137 Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel.
139 void JackDriver::SetupDriverSync(int ref, bool freewheel)
141 if (!freewheel && !fEngineControl->fSyncMode) {
142 jack_log("JackDriver::SetupDriverSync driver sem in flush mode");
143 fSynchroTable[ref].SetFlush(true);
144 } else {
145 jack_log("JackDriver::SetupDriverSync driver sem in normal mode");
146 fSynchroTable[ref].SetFlush(false);
150 int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2)
152 switch (notify) {
154 case kStartFreewheelCallback:
155 jack_log("JackDriver::kStartFreewheel");
156 SetupDriverSync(fClientControl.fRefNum, true);
157 break;
159 case kStopFreewheelCallback:
160 jack_log("JackDriver::kStopFreewheel");
161 SetupDriverSync(fClientControl.fRefNum, false);
162 break;
165 return 0;
168 bool JackDriver::IsRealTime() const
170 return fEngineControl->fRealTime;
173 void JackDriver::CycleIncTime()
175 fEngineControl->CycleIncTime(fBeginDateUst);
178 void JackDriver::CycleTakeBeginTime()
180 fBeginDateUst = GetMicroSeconds(); // Take callback date here
181 fEngineControl->CycleIncTime(fBeginDateUst);
184 void JackDriver::CycleTakeEndTime()
186 fEndDateUst = GetMicroSeconds(); // Take end date here
189 JackClientControl* JackDriver::GetClientControl() const
191 return (JackClientControl*)&fClientControl;
194 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin, float delayed_usecs)
196 fEngine->NotifyXRun(cur_cycle_begin, delayed_usecs);
199 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size)
201 fEngine->NotifyBufferSize(buffer_size);
202 fEngineControl->InitFrameTime();
205 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
207 fEngine->NotifySampleRate(sample_rate);
208 fEngineControl->InitFrameTime();
211 void JackDriver::SetMaster(bool onoff)
213 fIsMaster = onoff;
216 bool JackDriver::GetMaster()
218 return fIsMaster;
221 void JackDriver::AddSlave(JackDriverInterface* slave)
223 fSlaveList.push_back(slave);
226 void JackDriver::RemoveSlave(JackDriverInterface* slave)
228 fSlaveList.remove(slave);
231 int JackDriver::ProcessSlaves()
233 int res = 0;
234 list<JackDriverInterface*>::const_iterator it;
235 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
236 JackDriverInterface* slave = *it;
237 if (slave->Process() < 0)
238 res = -1;
240 return res;
243 int JackDriver::Process()
245 return 0;
248 int JackDriver::ProcessNull()
250 return 0;
253 int JackDriver::Attach()
255 return 0;
258 int JackDriver::Detach()
260 return 0;
263 int JackDriver::Read()
265 return 0;
268 int JackDriver::Write()
270 return 0;
273 int JackDriver::Start()
275 return 0;
278 int JackDriver::Stop()
280 return 0;
283 bool JackDriver::IsFixedBufferSize()
285 return true;
288 int JackDriver::SetBufferSize(jack_nframes_t buffer_size)
290 return 0;
293 int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
295 return 0;
298 bool JackDriver::Init()
300 return true;
304 } // end of namespace