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" 40 JackDriver::JackDriver(
const char* name,
const char* alias, JackLockedEngine* engine, JackSynchro* table)
44 fWithMonitorPorts(false){
45 assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
46 fSynchroTable = table;
47 strcpy(fAliasName, alias);
56 JackDriver::~JackDriver()
61 int JackDriver::Open()
65 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager,
this,
false) != 0) {
66 jack_error(
"Cannot allocate internal client for driver");
70 fClientControl.fRefNum = refnum;
71 fClientControl.fActive =
true;
72 fEngineControl->fDriverNum++;
73 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
78 int JackDriver::Open(jack_nframes_t buffer_size,
79 jack_nframes_t samplerate,
85 const char* capture_driver_name,
86 const char* playback_driver_name,
87 jack_nframes_t capture_latency,
88 jack_nframes_t playback_latency)
90 jack_log(
"JackDriver::Open capture_driver_name = %s", capture_driver_name);
91 jack_log(
"JackDriver::Open playback_driver_name = %s", playback_driver_name);
93 char name_res[JACK_CLIENT_NAME_SIZE + 1];
97 if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (
int)JackNullOption, (
int*)&status) < 0) {
98 jack_error(
"Client name = %s conflits with another running client", fClientControl.fName);
101 strcpy(fClientControl.fName, name_res);
103 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager,
this,
false) != 0) {
104 jack_error(
"Cannot allocate internal client for driver");
108 fClientControl.fRefNum = refnum;
109 fClientControl.fActive =
true;
110 fEngineControl->fDriverNum++;
111 if (buffer_size > 0) {
112 fEngineControl->fBufferSize = buffer_size;
114 if (samplerate > 0) {
115 fEngineControl->fSampleRate = samplerate;
117 fCaptureLatency = capture_latency;
118 fPlaybackLatency = playback_latency;
120 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
121 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
123 strcpy(fCaptureDriverName, capture_driver_name);
124 strcpy(fPlaybackDriverName, playback_driver_name);
126 fEngineControl->UpdateTimeOut();
128 fGraphManager->SetBufferSize(buffer_size);
129 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
134 int JackDriver::Close()
136 if (fClientControl.fRefNum >= 0) {
138 fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum);
139 fClientControl.fActive =
false;
140 fEngineControl->fDriverNum--;
141 return fEngine->ClientInternalClose(fClientControl.fRefNum,
false);
154 if (!freewheel && !fEngineControl->fSyncMode) {
155 jack_log(
"JackDriver::SetupDriverSync driver sem in flush mode");
156 fSynchroTable[ref].SetFlush(
true);
158 jack_log(
"JackDriver::SetupDriverSync driver sem in normal mode");
159 fSynchroTable[ref].SetFlush(
false);
163 int JackDriver::ClientNotify(
int refnum,
const char* name,
int notify,
int sync,
const char* message,
int value1,
int value2)
165 jack_log(
"JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify);
169 case kStartFreewheelCallback:
170 jack_log(
"JackDriver::kStartFreewheel");
174 case kStopFreewheelCallback:
175 jack_log(
"JackDriver::kStopFreewheel");
183 bool JackDriver::IsRealTime()
const 185 return fEngineControl->fRealTime;
188 void JackDriver::CycleIncTime()
190 fEngineControl->CycleIncTime(fBeginDateUst);
193 void JackDriver::CycleTakeBeginTime()
195 fBeginDateUst = GetMicroSeconds();
196 fEngineControl->CycleIncTime(fBeginDateUst);
199 void JackDriver::CycleTakeEndTime()
201 fEndDateUst = GetMicroSeconds();
209 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin,
float delayed_usecs)
211 fEngineControl->NotifyXRun(cur_cycle_begin, delayed_usecs);
212 fEngine->NotifyDriverXRun();
215 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size)
217 fEngine->NotifyBufferSize(buffer_size);
218 fEngineControl->InitFrameTime();
221 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
223 fEngine->NotifySampleRate(sample_rate);
224 fEngineControl->InitFrameTime();
227 void JackDriver::NotifyFailure(
int code,
const char* reason)
229 fEngine->NotifyFailure(code, reason);
232 void JackDriver::SetMaster(
bool onoff)
237 bool JackDriver::GetMaster()
244 fSlaveList.push_back(slave);
249 fSlaveList.remove(slave);
252 int JackDriver::ProcessReadSlaves()
255 list<JackDriverInterface*>::const_iterator it;
256 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
258 if (slave->IsRunning()) {
259 if (slave->ProcessRead() < 0) {
267 int JackDriver::ProcessWriteSlaves()
270 list<JackDriverInterface*>::const_iterator it;
271 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
273 if (slave->IsRunning()) {
274 if (slave->ProcessWrite() < 0) {
282 int JackDriver::ProcessRead()
284 return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync();
287 int JackDriver::ProcessWrite()
289 return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync();
292 int JackDriver::ProcessReadSync()
297 int JackDriver::ProcessWriteSync()
302 int JackDriver::ProcessReadAsync()
307 int JackDriver::ProcessWriteAsync()
312 int JackDriver::Process()
317 int JackDriver::Attach()
322 int JackDriver::Detach()
327 int JackDriver::Read()
332 int JackDriver::Write()
337 int JackDriver::Start()
340 fEngineControl->InitFrameTime();
343 return StartSlaves();
346 int JackDriver::Stop()
352 int JackDriver::StartSlaves()
355 list<JackDriverInterface*>::const_iterator it;
356 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
358 if (slave->Start() < 0) {
368 int JackDriver::StopSlaves()
371 list<JackDriverInterface*>::const_iterator it;
372 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
374 if (slave->Stop() < 0) {
381 bool JackDriver::IsFixedBufferSize()
386 int JackDriver::SetBufferSize(jack_nframes_t buffer_size)
389 list<JackDriverInterface*>::const_iterator it;
390 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
392 if (slave->SetBufferSize(buffer_size) < 0) {
399 int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
402 list<JackDriverInterface*>::const_iterator it;
403 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
405 if (slave->SetSampleRate(sample_rate) < 0) {
412 bool JackDriver::Initialize()
417 static string RemoveLast(
const string& name)
419 return name.substr(0, name.find_last_of(
':'));
422 void JackDriver::SaveConnections(
int alias)
424 const char** connections;
425 char alias1[REAL_JACK_PORT_NAME_SIZE];
426 char alias2[REAL_JACK_PORT_NAME_SIZE];
427 char system_alias1[REAL_JACK_PORT_NAME_SIZE];
428 char system_alias2[REAL_JACK_PORT_NAME_SIZE];
430 char* system_aliases[2];
435 system_aliases[0] = system_alias1;
436 system_aliases[1] = system_alias2;
438 fConnections.clear();
440 for (
int i = 0; i < fCaptureChannels; ++i) {
441 if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fCapturePortList[i])) != 0) {
443 for (
int j = 0; connections[j]; j++) {
444 JackPort* port_id = fGraphManager->GetPort(fCapturePortList[i]);
445 fConnections.push_back(make_pair(port_id->GetType(), make_pair(port_id->GetName(), connections[j])));
446 jack_info(
"Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]);
449 int res1 = fGraphManager->GetPort(fCapturePortList[i])->GetAliases(aliases);
450 string sub_system_name;
452 sub_system_name = aliases[alias-1];
454 sub_system_name = fGraphManager->GetPort(fCapturePortList[i])->GetName();
456 for (
int j = 0; connections[j]; j++) {
457 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
458 int res2 = port_id->GetAliases(system_aliases);
461 sub_system = system_aliases[alias-1];
463 sub_system = connections[j];
465 fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_system_name, sub_system)));
466 jack_info(
"Save connection: %s %s", sub_system_name.c_str(), sub_system.c_str());
473 for (
int i = 0; i < fPlaybackChannels; ++i) {
474 if (fPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fPlaybackPortList[i])) != 0) {
476 for (
int j = 0; connections[j]; j++) {
477 JackPort* port_id = fGraphManager->GetPort(fPlaybackPortList[i]);
478 fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], port_id->GetName())));
479 jack_info(
"Save connection: %s %s", connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName());
482 int res1 = fGraphManager->GetPort(fPlaybackPortList[i])->GetAliases(aliases);
483 string sub_system_name;
485 sub_system_name = aliases[alias-1];
487 sub_system_name = fGraphManager->GetPort(fPlaybackPortList[i])->GetName();
489 for (
int j = 0; connections[j]; j++) {
490 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
491 int res2 = port_id->GetAliases(system_aliases);
494 sub_name = system_aliases[alias-1];
496 sub_name = connections[j];
498 fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_name, sub_system_name)));
499 jack_info(
"Save connection: %s %s", sub_name.c_str(), sub_system_name.c_str());
507 string JackDriver::MatchPortName(
const char* name,
const char** ports,
int alias,
const std::string& type)
509 char alias1[REAL_JACK_PORT_NAME_SIZE];
510 char alias2[REAL_JACK_PORT_NAME_SIZE];
516 for (
int i = 0; ports && ports[i]; ++i) {
518 jack_port_id_t port_id2 = fGraphManager->GetPort(ports[i]);
519 JackPort* port2 = (port_id2 != NO_PORT) ? fGraphManager->GetPort(port_id2) : NULL;
522 int res = port2->GetAliases(aliases);
525 name_str = string(aliases[alias-1]);
527 name_str = string(ports[i]);
529 string sub_name = RemoveLast(name);
530 if ((name_str.find(sub_name) != string::npos) && (type ==
string(port2->GetType()))) {
539 void JackDriver::LoadConnections(
int alias,
bool full_name)
541 list<pair<string, pair<string, string> > >::const_iterator it;
544 for (it = fConnections.begin(); it != fConnections.end(); it++) {
545 pair<string, string> connection = (*it).second;
546 jack_info(
"Load connection: %s %s", connection.first.c_str(), connection.second.c_str());
547 fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str());
550 const char** inputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsInput);
551 const char** outputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsOutput);
553 for (it = fConnections.begin(); it != fConnections.end(); it++) {
554 pair<string, string> connection = (*it).second;
555 string real_input = MatchPortName(connection.first.c_str(), outputs, alias, (*it).first);
556 string real_output = MatchPortName(connection.second.c_str(), inputs, alias, (*it).first);
557 if ((real_input !=
"") && (real_output !=
"")) {
558 jack_info(
"Load connection: %s %s", real_input.c_str(), real_output.c_str());
559 fEngine->PortConnect(fClientControl.fRefNum, real_input.c_str(), real_output.c_str());
564 if (fGraphManager->IsPendingChange()) {
565 JackSleep(
int(fEngineControl->fPeriodUsecs * 1.1f));
577 int JackDriver::ResumeRefNum()
579 return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
582 int JackDriver::SuspendRefNum()
584 return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs);
The base interface for drivers.
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
void SetupDriverSync(bool freewheel)
SERVER_EXPORT void jack_log(const char *fmt,...)
void SetupDriverSync(int ref, bool freewheel)
Client control possibly in shared memory.