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 audio driver");
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);
82 int JackDriver::Open(jack_nframes_t buffer_size
,
83 jack_nframes_t samplerate
,
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
);
98 if (fEngine
->ClientInternalOpen(fClientControl
.fName
, &refnum
, &fEngineControl
, &fGraphManager
, this, false) != 0) {
99 jack_error("Cannot allocate internal client for audio driver");
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);
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);
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
)
154 case kStartFreewheelCallback
:
155 jack_log("JackDriver::kStartFreewheel");
156 SetupDriverSync(fClientControl
.fRefNum
, true);
159 case kStopFreewheelCallback
:
160 jack_log("JackDriver::kStopFreewheel");
161 SetupDriverSync(fClientControl
.fRefNum
, false);
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
)
216 bool JackDriver::GetMaster()
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()
234 list
<JackDriverInterface
*>::const_iterator it
;
235 for (it
= fSlaveList
.begin(); it
!= fSlaveList
.end(); it
++) {
236 JackDriverInterface
* slave
= *it
;
237 if (slave
->Process() < 0)
243 int JackDriver::Process()
248 int JackDriver::ProcessNull()
253 int JackDriver::Attach()
258 int JackDriver::Detach()
263 int JackDriver::Read()
268 int JackDriver::Write()
273 int JackDriver::Start()
278 int JackDriver::Stop()
283 bool JackDriver::IsFixedBufferSize()
288 int JackDriver::SetBufferSize(jack_nframes_t buffer_size
)
293 int JackDriver::SetSampleRate(jack_nframes_t sample_rate
)
298 bool JackDriver::Init()
304 } // end of namespace