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 if (fClientControl
.fRefNum
> 0) {
171 jack_log("JackDriver::Close");
172 fGraphManager
->DirectDisconnect(fClientControl
.fRefNum
, fClientControl
.fRefNum
); // Disconnect driver from itself for sync
173 fClientControl
.fActive
= false;
174 fEngineControl
->fDriverNum
--;
175 return fEngine
->ClientInternalClose(fClientControl
.fRefNum
, false);
182 In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
183 The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
184 Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel.
186 void JackDriver::SetupDriverSync(int ref
, bool freewheel
)
188 if (!freewheel
&& !fEngineControl
->fSyncMode
) {
189 jack_log("JackDriver::SetupDriverSync driver sem in flush mode");
190 fSynchroTable
[ref
].SetFlush(true);
192 jack_log("JackDriver::SetupDriverSync driver sem in normal mode");
193 fSynchroTable
[ref
].SetFlush(false);
197 int JackDriver::ClientNotify(int refnum
, const char* name
, int notify
, int sync
, const char* message
, int value1
, int value2
)
201 case kStartFreewheelCallback
:
202 jack_log("JackDriver::kStartFreewheel");
203 SetupDriverSync(fClientControl
.fRefNum
, true);
206 case kStopFreewheelCallback
:
207 jack_log("JackDriver::kStopFreewheel");
208 SetupDriverSync(fClientControl
.fRefNum
, false);
215 bool JackDriver::IsRealTime() const
217 return fEngineControl
->fRealTime
;
220 void JackDriver::CycleIncTime()
222 fEngineControl
->CycleIncTime(fBeginDateUst
);
225 void JackDriver::CycleTakeBeginTime()
227 fBeginDateUst
= GetMicroSeconds(); // Take callback date here
228 fEngineControl
->CycleIncTime(fBeginDateUst
);
231 void JackDriver::CycleTakeEndTime()
233 fEndDateUst
= GetMicroSeconds(); // Take end date here
236 JackClientControl
* JackDriver::GetClientControl() const
238 return (JackClientControl
*)&fClientControl
;
241 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin
, float delayed_usecs
)
243 fEngine
->NotifyXRun(cur_cycle_begin
, delayed_usecs
);
246 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size
)
248 fEngine
->NotifyBufferSize(buffer_size
);
249 fEngineControl
->InitFrameTime();
252 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate
)
254 fEngine
->NotifySampleRate(sample_rate
);
255 fEngineControl
->InitFrameTime();
258 void JackDriver::NotifyFailure(int code
, const char* reason
)
260 fEngine
->NotifyFailure(code
, reason
);
263 void JackDriver::SetMaster(bool onoff
)
268 bool JackDriver::GetMaster()
273 void JackDriver::AddSlave(JackDriverInterface
* slave
)
275 fSlaveList
.push_back(slave
);
278 void JackDriver::RemoveSlave(JackDriverInterface
* slave
)
280 fSlaveList
.remove(slave
);
283 int JackDriver::ProcessSlaves()
286 list
<JackDriverInterface
*>::const_iterator it
;
287 for (it
= fSlaveList
.begin(); it
!= fSlaveList
.end(); it
++) {
288 JackDriverInterface
* slave
= *it
;
289 if (slave
->Process() < 0)
295 int JackDriver::Process()
300 int JackDriver::ProcessNull()
305 int JackDriver::Attach()
310 int JackDriver::Detach()
315 int JackDriver::Read()
320 int JackDriver::Write()
325 int JackDriver::Start()
327 fEngineControl
->InitFrameTime();
331 int JackDriver::Stop()
336 bool JackDriver::IsFixedBufferSize()
341 int JackDriver::SetBufferSize(jack_nframes_t buffer_size
)
346 int JackDriver::SetSampleRate(jack_nframes_t sample_rate
)
351 bool JackDriver::Initialize()
357 } // end of namespace