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"
24 #include "JackError.h"
26 #include "JackGraphManager.h"
27 #include "JackGlobals.h"
28 #include "JackEngineControl.h"
29 #include "JackClientControl.h"
30 #include "JackLockedEngine.h"
39 JackDriver::JackDriver(const char* name
, const char* alias
, JackLockedEngine
* engine
, JackSynchro
* table
)
42 assert(strlen(name
) < JACK_CLIENT_NAME_SIZE
);
43 fSynchroTable
= table
;
44 strcpy(fAliasName
, alias
);
52 JackDriver::JackDriver()
61 JackDriver::~JackDriver()
63 jack_log("~JackDriver");
66 int JackDriver::Open()
70 if (fEngine
->ClientInternalOpen(fClientControl
.fName
, &refnum
, &fEngineControl
, &fGraphManager
, this, false) != 0) {
71 jack_error("Cannot allocate internal client for driver");
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);
83 int JackDriver::Open (bool capturing
,
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
);
97 if (fEngine
->ClientInternalOpen(fClientControl
.fName
, &refnum
, &fEngineControl
, &fGraphManager
, this, false) != 0) {
98 jack_error("Cannot allocate internal client for driver");
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);
123 int JackDriver::Open(jack_nframes_t buffer_size
,
124 jack_nframes_t samplerate
,
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
);
139 if (fEngine
->ClientInternalOpen(fClientControl
.fName
, &refnum
, &fEngineControl
, &fGraphManager
, this, false) != 0) {
140 jack_error("Cannot allocate internal client for driver");
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);
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);
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
)
197 case kStartFreewheelCallback
:
198 jack_log("JackDriver::kStartFreewheel");
199 SetupDriverSync(fClientControl
.fRefNum
, true);
202 case kStopFreewheelCallback
:
203 jack_log("JackDriver::kStopFreewheel");
204 SetupDriverSync(fClientControl
.fRefNum
, false);
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
)
259 bool JackDriver::GetMaster()
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()
277 list
<JackDriverInterface
*>::const_iterator it
;
278 for (it
= fSlaveList
.begin(); it
!= fSlaveList
.end(); it
++) {
279 JackDriverInterface
* slave
= *it
;
280 if (slave
->Process() < 0)
286 int JackDriver::Process()
291 int JackDriver::ProcessNull()
296 int JackDriver::Attach()
301 int JackDriver::Detach()
306 int JackDriver::Read()
311 int JackDriver::Write()
316 int JackDriver::Start()
318 fEngineControl
->InitFrameTime();
322 int JackDriver::Stop()
327 bool JackDriver::IsFixedBufferSize()
332 int JackDriver::SetBufferSize(jack_nframes_t buffer_size
)
337 int JackDriver::SetSampleRate(jack_nframes_t sample_rate
)
342 bool JackDriver::Initialize()
348 } // end of namespace