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)
43 fWithMonitorPorts(false)
45 assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
46 fSynchroTable = table;
47 strcpy(fAliasName, alias);
56 JackDriver::JackDriver()
66 fPlaybackChannels = 0;
67 fWithMonitorPorts =
false;
70 JackDriver::~JackDriver()
75 int JackDriver::Open()
79 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager,
this,
false) != 0) {
80 jack_error(
"Cannot allocate internal client for driver");
84 fClientControl.fRefNum = refnum;
85 fClientControl.fActive =
true;
86 fEngineControl->fDriverNum++;
87 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
92 int JackDriver::Open(
bool capturing,
97 const char* capture_driver_name,
98 const char* playback_driver_name,
99 jack_nframes_t capture_latency,
100 jack_nframes_t playback_latency)
102 jack_log(
"JackDriver::Open capture_driver_name = %s", capture_driver_name);
103 jack_log(
"JackDriver::Open playback_driver_name = %s", playback_driver_name);
105 char name_res[JACK_CLIENT_NAME_SIZE + 1];
109 if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (
int)JackNullOption, (
int*)&status) < 0) {
110 jack_error(
"Client name = %s conflits with another running client", fClientControl.fName);
113 strcpy(fClientControl.fName, name_res);
115 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager,
this,
false) != 0) {
116 jack_error(
"Cannot allocate internal client for driver");
120 fClientControl.fRefNum = refnum;
121 fClientControl.fActive =
true;
122 fEngineControl->fDriverNum++;
123 fCaptureLatency = capture_latency;
124 fPlaybackLatency = playback_latency;
126 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
127 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
129 strcpy(fCaptureDriverName, capture_driver_name);
130 strcpy(fPlaybackDriverName, playback_driver_name);
132 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize);
133 if (!fEngineControl->fTimeOut) {
134 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
137 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
142 int JackDriver::Open(jack_nframes_t buffer_size,
143 jack_nframes_t samplerate,
149 const char* capture_driver_name,
150 const char* playback_driver_name,
151 jack_nframes_t capture_latency,
152 jack_nframes_t playback_latency)
154 jack_log(
"JackDriver::Open capture_driver_name = %s", capture_driver_name);
155 jack_log(
"JackDriver::Open playback_driver_name = %s", playback_driver_name);
157 char name_res[JACK_CLIENT_NAME_SIZE + 1];
161 if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (
int)JackNullOption, (
int*)&status) < 0) {
162 jack_error(
"Client name = %s conflits with another running client", fClientControl.fName);
165 strcpy(fClientControl.fName, name_res);
167 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager,
this,
false) != 0) {
168 jack_error(
"Cannot allocate internal client for driver");
172 fClientControl.fRefNum = refnum;
173 fClientControl.fActive =
true;
174 fEngineControl->fDriverNum++;
175 fEngineControl->fBufferSize = buffer_size;
176 fEngineControl->fSampleRate = samplerate;
177 fCaptureLatency = capture_latency;
178 fPlaybackLatency = playback_latency;
180 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
181 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
183 strcpy(fCaptureDriverName, capture_driver_name);
184 strcpy(fPlaybackDriverName, playback_driver_name);
186 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize);
187 if (!fEngineControl->fTimeOut) {
188 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
191 fGraphManager->SetBufferSize(buffer_size);
192 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
197 int JackDriver::Close()
199 if (fClientControl.fRefNum >= 0) {
201 fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum);
202 fClientControl.fActive =
false;
203 fEngineControl->fDriverNum--;
204 return fEngine->ClientInternalClose(fClientControl.fRefNum,
false);
217 if (!freewheel && !fEngineControl->fSyncMode) {
218 jack_log(
"JackDriver::SetupDriverSync driver sem in flush mode");
219 fSynchroTable[ref].SetFlush(
true);
221 jack_log(
"JackDriver::SetupDriverSync driver sem in normal mode");
222 fSynchroTable[ref].SetFlush(
false);
226 int JackDriver::ClientNotify(
int refnum,
const char* name,
int notify,
int sync,
const char* message,
int value1,
int value2)
228 jack_log(
"JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify);
232 case kStartFreewheelCallback:
233 jack_log(
"JackDriver::kStartFreewheel");
237 case kStopFreewheelCallback:
238 jack_log(
"JackDriver::kStopFreewheel");
246 bool JackDriver::IsRealTime()
const
248 return fEngineControl->fRealTime;
251 void JackDriver::CycleIncTime()
253 fEngineControl->CycleIncTime(fBeginDateUst);
256 void JackDriver::CycleTakeBeginTime()
258 fBeginDateUst = GetMicroSeconds();
259 fEngineControl->CycleIncTime(fBeginDateUst);
262 void JackDriver::CycleTakeEndTime()
264 fEndDateUst = GetMicroSeconds();
267 JackClientControl* JackDriver::GetClientControl()
const
269 return (JackClientControl*)&fClientControl;
272 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin,
float delayed_usecs)
274 fEngine->NotifyXRun(cur_cycle_begin, delayed_usecs);
277 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size)
279 fEngine->NotifyBufferSize(buffer_size);
280 fEngineControl->InitFrameTime();
283 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
285 fEngine->NotifySampleRate(sample_rate);
286 fEngineControl->InitFrameTime();
289 void JackDriver::NotifyFailure(
int code,
const char* reason)
291 fEngine->NotifyFailure(code, reason);
294 void JackDriver::SetMaster(
bool onoff)
299 bool JackDriver::GetMaster()
304 void JackDriver::AddSlave(JackDriverInterface* slave)
306 fSlaveList.push_back(slave);
309 void JackDriver::RemoveSlave(JackDriverInterface* slave)
311 fSlaveList.remove(slave);
314 int JackDriver::ProcessReadSlaves()
317 list<JackDriverInterface*>::const_iterator it;
318 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
319 JackDriverInterface* slave = *it;
320 if (slave->IsRunning()) {
321 if (slave->ProcessRead() < 0) {
329 int JackDriver::ProcessWriteSlaves()
332 list<JackDriverInterface*>::const_iterator it;
333 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
334 JackDriverInterface* slave = *it;
335 if (slave->IsRunning()) {
336 if (slave->ProcessWrite() < 0) {
344 int JackDriver::ProcessRead()
346 return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync();
349 int JackDriver::ProcessWrite()
351 return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync();
354 int JackDriver::ProcessReadSync()
359 int JackDriver::ProcessWriteSync()
364 int JackDriver::ProcessReadAsync()
369 int JackDriver::ProcessWriteAsync()
374 int JackDriver::Process()
379 int JackDriver::Attach()
384 int JackDriver::Detach()
389 int JackDriver::Read()
394 int JackDriver::Write()
399 int JackDriver::Start()
402 fEngineControl->InitFrameTime();
405 return StartSlaves();
408 int JackDriver::Stop()
414 int JackDriver::StartSlaves()
417 list<JackDriverInterface*>::const_iterator it;
418 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
419 JackDriverInterface* slave = *it;
420 if (slave->Start() < 0) {
430 int JackDriver::StopSlaves()
433 list<JackDriverInterface*>::const_iterator it;
434 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
435 JackDriverInterface* slave = *it;
436 if (slave->Stop() < 0) {
443 bool JackDriver::IsFixedBufferSize()
448 int JackDriver::SetBufferSize(jack_nframes_t buffer_size)
451 list<JackDriverInterface*>::const_iterator it;
452 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
453 JackDriverInterface* slave = *it;
454 if (slave->SetBufferSize(buffer_size) < 0) {
461 int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
464 list<JackDriverInterface*>::const_iterator it;
465 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
466 JackDriverInterface* slave = *it;
467 if (slave->SetSampleRate(sample_rate) < 0) {
474 bool JackDriver::Initialize()
479 void JackDriver::SaveConnections()
481 const char** connections;
482 fConnections.clear();
483 char alias1[REAL_JACK_PORT_NAME_SIZE];
484 char alias2[REAL_JACK_PORT_NAME_SIZE];
490 for (
int i = 0; i < fCaptureChannels; ++i) {
491 if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fCapturePortList[i])) != 0) {
492 for (
int j = 0; connections[j]; j++) {
498 fConnections.push_back(make_pair(fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]));
499 jack_info(
"Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]);
505 for (
int i = 0; i < fPlaybackChannels; ++i) {
506 if (fPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fPlaybackPortList[i])) != 0) {
507 for (
int j = 0; connections[j]; j++) {
513 fConnections.push_back(make_pair(connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName()));
514 jack_info(
"Save connection: %s %s", connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName());
521 void JackDriver::RestoreConnections()
523 list<pair<string, string> >::const_iterator it;
525 for (it = fConnections.begin(); it != fConnections.end(); it++) {
526 pair<string, string> connection = *it;
527 jack_info(
"Restore connection: %s %s", connection.first.c_str(), connection.second.c_str());
528 fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str());
532 int JackDriver::ResumeRefNum()
534 return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
537 int JackDriver::SuspendRefNum()
539 return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs);