Add a string parameter to server ==> client notification, add a new InfoShutdown...
[jack2.git] / common / JackDriver.cpp
blob457f7b734b0ee1e498613f8132f994326e8238c9
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 driver");
72 return -1;
75 fClientControl.fRefNum = refnum;
76 fClientControl.fActive = true;
77 fEngineControl->fDriverNum++;
78 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode
79 SetupDriverSync(fClientControl.fRefNum, false);
80 return 0;
83 int JackDriver::Open (bool capturing,
84 bool playing,
85 int inchannels,
86 int outchannels,
87 bool monitor,
88 const char* capture_driver_name,
89 const char* playback_driver_name,
90 jack_nframes_t capture_latency,
91 jack_nframes_t playback_latency)
93 jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name);
94 jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name);
95 int refnum = -1;
97 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
98 jack_error("Cannot allocate internal client for driver");
99 return -1;
102 fClientControl.fRefNum = refnum;
103 fClientControl.fActive = true;
104 fEngineControl->fDriverNum++;
105 fCaptureLatency = capture_latency;
106 fPlaybackLatency = playback_latency;
108 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
109 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
111 strcpy(fCaptureDriverName, capture_driver_name);
112 strcpy(fPlaybackDriverName, playback_driver_name);
114 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
115 if (!fEngineControl->fTimeOut)
116 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
118 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode
119 SetupDriverSync(fClientControl.fRefNum, false);
120 return 0;
123 int JackDriver::Open(jack_nframes_t buffer_size,
124 jack_nframes_t samplerate,
125 bool capturing,
126 bool playing,
127 int inchannels,
128 int outchannels,
129 bool monitor,
130 const char* capture_driver_name,
131 const char* playback_driver_name,
132 jack_nframes_t capture_latency,
133 jack_nframes_t playback_latency)
135 jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name);
136 jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name);
137 int refnum = -1;
139 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
140 jack_error("Cannot allocate internal client for driver");
141 return -1;
144 fClientControl.fRefNum = refnum;
145 fClientControl.fActive = true;
146 fEngineControl->fDriverNum++;
147 fEngineControl->fBufferSize = buffer_size;
148 fEngineControl->fSampleRate = samplerate;
149 fCaptureLatency = capture_latency;
150 fPlaybackLatency = playback_latency;
152 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
153 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
155 strcpy(fCaptureDriverName, capture_driver_name);
156 strcpy(fPlaybackDriverName, playback_driver_name);
158 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
159 if (!fEngineControl->fTimeOut)
160 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
162 fGraphManager->SetBufferSize(buffer_size);
163 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode
164 SetupDriverSync(fClientControl.fRefNum, false);
165 return 0;
168 int JackDriver::Close()
170 jack_log("JackDriver::Close");
171 fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync
172 fClientControl.fActive = false;
173 fEngineControl->fDriverNum--;
174 return fEngine->ClientInternalClose(fClientControl.fRefNum, false);
178 In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
179 The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
180 Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel.
182 void JackDriver::SetupDriverSync(int ref, bool freewheel)
184 if (!freewheel && !fEngineControl->fSyncMode) {
185 jack_log("JackDriver::SetupDriverSync driver sem in flush mode");
186 fSynchroTable[ref].SetFlush(true);
187 } else {
188 jack_log("JackDriver::SetupDriverSync driver sem in normal mode");
189 fSynchroTable[ref].SetFlush(false);
193 int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
195 switch (notify) {
197 case kStartFreewheelCallback:
198 jack_log("JackDriver::kStartFreewheel");
199 SetupDriverSync(fClientControl.fRefNum, true);
200 break;
202 case kStopFreewheelCallback:
203 jack_log("JackDriver::kStopFreewheel");
204 SetupDriverSync(fClientControl.fRefNum, false);
205 break;
208 return 0;
211 bool JackDriver::IsRealTime() const
213 return fEngineControl->fRealTime;
216 void JackDriver::CycleIncTime()
218 fEngineControl->CycleIncTime(fBeginDateUst);
221 void JackDriver::CycleTakeBeginTime()
223 fBeginDateUst = GetMicroSeconds(); // Take callback date here
224 fEngineControl->CycleIncTime(fBeginDateUst);
227 void JackDriver::CycleTakeEndTime()
229 fEndDateUst = GetMicroSeconds(); // Take end date here
232 JackClientControl* JackDriver::GetClientControl() const
234 return (JackClientControl*)&fClientControl;
237 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin, float delayed_usecs)
239 fEngine->NotifyXRun(cur_cycle_begin, delayed_usecs);
242 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size)
244 fEngine->NotifyBufferSize(buffer_size);
245 fEngineControl->InitFrameTime();
248 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
250 fEngine->NotifySampleRate(sample_rate);
251 fEngineControl->InitFrameTime();
254 void JackDriver::SetMaster(bool onoff)
256 fIsMaster = onoff;
259 bool JackDriver::GetMaster()
261 return fIsMaster;
264 void JackDriver::AddSlave(JackDriverInterface* slave)
266 fSlaveList.push_back(slave);
269 void JackDriver::RemoveSlave(JackDriverInterface* slave)
271 fSlaveList.remove(slave);
274 int JackDriver::ProcessSlaves()
276 int res = 0;
277 list<JackDriverInterface*>::const_iterator it;
278 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
279 JackDriverInterface* slave = *it;
280 if (slave->Process() < 0)
281 res = -1;
283 return res;
286 int JackDriver::Process()
288 return 0;
291 int JackDriver::ProcessNull()
293 return 0;
296 int JackDriver::Attach()
298 return 0;
301 int JackDriver::Detach()
303 return 0;
306 int JackDriver::Read()
308 return 0;
311 int JackDriver::Write()
313 return 0;
316 int JackDriver::Start()
318 fEngineControl->InitFrameTime();
319 return 0;
322 int JackDriver::Stop()
324 return 0;
327 bool JackDriver::IsFixedBufferSize()
329 return true;
332 int JackDriver::SetBufferSize(jack_nframes_t buffer_size)
334 return 0;
337 int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
339 return 0;
342 bool JackDriver::Initialize()
344 return true;
348 } // end of namespace