00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackSystemDeps.h"
00022 #include "JackDriver.h"
00023 #include "JackTime.h"
00024 #include "JackError.h"
00025 #include "JackPort.h"
00026 #include "JackGraphManager.h"
00027 #include "JackGlobals.h"
00028 #include "JackEngineControl.h"
00029 #include "JackClientControl.h"
00030 #include "JackLockedEngine.h"
00031 #include "JackTime.h"
00032 #include <math.h>
00033 #include <assert.h>
00034
00035 using namespace std;
00036
00037 namespace Jack
00038 {
00039
00040 JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
00041 :fCaptureChannels(0),
00042 fPlaybackChannels(0),
00043 fClientControl(name),
00044 fWithMonitorPorts(false){
00045 assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
00046 fSynchroTable = table;
00047 strcpy(fAliasName, alias);
00048 fEngine = engine;
00049 fGraphManager = NULL;
00050 fBeginDateUst = 0;
00051 fDelayedUsecs = 0.f;
00052 fIsMaster = true;
00053 fIsRunning = false;
00054 }
00055
00056 JackDriver::~JackDriver()
00057 {
00058 jack_log("~JackDriver");
00059 }
00060
00061 int JackDriver::Open()
00062 {
00063 int refnum = -1;
00064
00065 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
00066 jack_error("Cannot allocate internal client for driver");
00067 return -1;
00068 }
00069
00070 fClientControl.fRefNum = refnum;
00071 fClientControl.fActive = true;
00072 fEngineControl->fDriverNum++;
00073 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
00074 SetupDriverSync(fClientControl.fRefNum, false);
00075 return 0;
00076 }
00077
00078 int JackDriver::Open(jack_nframes_t buffer_size,
00079 jack_nframes_t samplerate,
00080 bool capturing,
00081 bool playing,
00082 int inchannels,
00083 int outchannels,
00084 bool monitor,
00085 const char* capture_driver_name,
00086 const char* playback_driver_name,
00087 jack_nframes_t capture_latency,
00088 jack_nframes_t playback_latency)
00089 {
00090 jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name);
00091 jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name);
00092 int refnum = -1;
00093 char name_res[JACK_CLIENT_NAME_SIZE + 1];
00094 int status;
00095
00096
00097 if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) {
00098 jack_error("Client name = %s conflits with another running client", fClientControl.fName);
00099 return -1;
00100 }
00101 strcpy(fClientControl.fName, name_res);
00102
00103 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
00104 jack_error("Cannot allocate internal client for driver");
00105 return -1;
00106 }
00107
00108 fClientControl.fRefNum = refnum;
00109 fClientControl.fActive = true;
00110 fEngineControl->fDriverNum++;
00111 if (buffer_size > 0) {
00112 fEngineControl->fBufferSize = buffer_size;
00113 }
00114 if (samplerate > 0) {
00115 fEngineControl->fSampleRate = samplerate;
00116 }
00117 fCaptureLatency = capture_latency;
00118 fPlaybackLatency = playback_latency;
00119
00120 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
00121 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
00122
00123 strcpy(fCaptureDriverName, capture_driver_name);
00124 strcpy(fPlaybackDriverName, playback_driver_name);
00125
00126 fEngineControl->UpdateTimeOut();
00127
00128 fGraphManager->SetBufferSize(buffer_size);
00129 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum);
00130 SetupDriverSync(fClientControl.fRefNum, false);
00131 return 0;
00132 }
00133
00134 int JackDriver::Close()
00135 {
00136 if (fClientControl.fRefNum >= 0) {
00137 jack_log("JackDriver::Close");
00138 fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum);
00139 fClientControl.fActive = false;
00140 fEngineControl->fDriverNum--;
00141 return fEngine->ClientInternalClose(fClientControl.fRefNum, false);
00142 } else {
00143 return -1;
00144 }
00145 }
00146
00152 void JackDriver::SetupDriverSync(int ref, bool freewheel)
00153 {
00154 if (!freewheel && !fEngineControl->fSyncMode) {
00155 jack_log("JackDriver::SetupDriverSync driver sem in flush mode");
00156 fSynchroTable[ref].SetFlush(true);
00157 } else {
00158 jack_log("JackDriver::SetupDriverSync driver sem in normal mode");
00159 fSynchroTable[ref].SetFlush(false);
00160 }
00161 }
00162
00163 int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
00164 {
00165 jack_log("JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify);
00166
00167 switch (notify) {
00168
00169 case kStartFreewheelCallback:
00170 jack_log("JackDriver::kStartFreewheel");
00171 SetupDriverSync(fClientControl.fRefNum, true);
00172 break;
00173
00174 case kStopFreewheelCallback:
00175 jack_log("JackDriver::kStopFreewheel");
00176 SetupDriverSync(fClientControl.fRefNum, false);
00177 break;
00178 }
00179
00180 return 0;
00181 }
00182
00183 bool JackDriver::IsRealTime() const
00184 {
00185 return fEngineControl->fRealTime;
00186 }
00187
00188 void JackDriver::CycleIncTime()
00189 {
00190 fEngineControl->CycleIncTime(fBeginDateUst);
00191 }
00192
00193 void JackDriver::CycleTakeBeginTime()
00194 {
00195 fBeginDateUst = GetMicroSeconds();
00196 fEngineControl->CycleIncTime(fBeginDateUst);
00197 }
00198
00199 void JackDriver::CycleTakeEndTime()
00200 {
00201 fEndDateUst = GetMicroSeconds();
00202 }
00203
00204 JackClientControl* JackDriver::GetClientControl() const
00205 {
00206 return (JackClientControl*)&fClientControl;
00207 }
00208
00209 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin, float delayed_usecs)
00210 {
00211 fEngineControl->NotifyXRun(cur_cycle_begin, delayed_usecs);
00212 fEngine->NotifyDriverXRun();
00213 }
00214
00215 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size)
00216 {
00217 fEngine->NotifyBufferSize(buffer_size);
00218 fEngineControl->InitFrameTime();
00219 }
00220
00221 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
00222 {
00223 fEngine->NotifySampleRate(sample_rate);
00224 fEngineControl->InitFrameTime();
00225 }
00226
00227 void JackDriver::NotifyFailure(int code, const char* reason)
00228 {
00229 fEngine->NotifyFailure(code, reason);
00230 }
00231
00232 void JackDriver::SetMaster(bool onoff)
00233 {
00234 fIsMaster = onoff;
00235 }
00236
00237 bool JackDriver::GetMaster()
00238 {
00239 return fIsMaster;
00240 }
00241
00242 void JackDriver::AddSlave(JackDriverInterface* slave)
00243 {
00244 fSlaveList.push_back(slave);
00245 }
00246
00247 void JackDriver::RemoveSlave(JackDriverInterface* slave)
00248 {
00249 fSlaveList.remove(slave);
00250 }
00251
00252 int JackDriver::ProcessReadSlaves()
00253 {
00254 int res = 0;
00255 list<JackDriverInterface*>::const_iterator it;
00256 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00257 JackDriverInterface* slave = *it;
00258 if (slave->IsRunning()) {
00259 if (slave->ProcessRead() < 0) {
00260 res = -1;
00261 }
00262 }
00263 }
00264 return res;
00265 }
00266
00267 int JackDriver::ProcessWriteSlaves()
00268 {
00269 int res = 0;
00270 list<JackDriverInterface*>::const_iterator it;
00271 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00272 JackDriverInterface* slave = *it;
00273 if (slave->IsRunning()) {
00274 if (slave->ProcessWrite() < 0) {
00275 res = -1;
00276 }
00277 }
00278 }
00279 return res;
00280 }
00281
00282 int JackDriver::ProcessRead()
00283 {
00284 return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync();
00285 }
00286
00287 int JackDriver::ProcessWrite()
00288 {
00289 return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync();
00290 }
00291
00292 int JackDriver::ProcessReadSync()
00293 {
00294 return 0;
00295 }
00296
00297 int JackDriver::ProcessWriteSync()
00298 {
00299 return 0;
00300 }
00301
00302 int JackDriver::ProcessReadAsync()
00303 {
00304 return 0;
00305 }
00306
00307 int JackDriver::ProcessWriteAsync()
00308 {
00309 return 0;
00310 }
00311
00312 int JackDriver::Process()
00313 {
00314 return 0;
00315 }
00316
00317 int JackDriver::Attach()
00318 {
00319 return 0;
00320 }
00321
00322 int JackDriver::Detach()
00323 {
00324 return 0;
00325 }
00326
00327 int JackDriver::Read()
00328 {
00329 return 0;
00330 }
00331
00332 int JackDriver::Write()
00333 {
00334 return 0;
00335 }
00336
00337 int JackDriver::Start()
00338 {
00339 if (fIsMaster) {
00340 fEngineControl->InitFrameTime();
00341 }
00342 fIsRunning = true;
00343 return StartSlaves();
00344 }
00345
00346 int JackDriver::Stop()
00347 {
00348 fIsRunning = false;
00349 return StopSlaves();
00350 }
00351
00352 int JackDriver::StartSlaves()
00353 {
00354 int res = 0;
00355 list<JackDriverInterface*>::const_iterator it;
00356 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00357 JackDriverInterface* slave = *it;
00358 if (slave->Start() < 0) {
00359 res = -1;
00360
00361
00362 break;
00363 }
00364 }
00365 return res;
00366 }
00367
00368 int JackDriver::StopSlaves()
00369 {
00370 int res = 0;
00371 list<JackDriverInterface*>::const_iterator it;
00372 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00373 JackDriverInterface* slave = *it;
00374 if (slave->Stop() < 0) {
00375 res = -1;
00376 }
00377 }
00378 return res;
00379 }
00380
00381 bool JackDriver::IsFixedBufferSize()
00382 {
00383 return true;
00384 }
00385
00386 int JackDriver::SetBufferSize(jack_nframes_t buffer_size)
00387 {
00388 int res = 0;
00389 list<JackDriverInterface*>::const_iterator it;
00390 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00391 JackDriverInterface* slave = *it;
00392 if (slave->SetBufferSize(buffer_size) < 0) {
00393 res = -1;
00394 }
00395 }
00396 return res;
00397 }
00398
00399 int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
00400 {
00401 int res = 0;
00402 list<JackDriverInterface*>::const_iterator it;
00403 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00404 JackDriverInterface* slave = *it;
00405 if (slave->SetSampleRate(sample_rate) < 0) {
00406 res = -1;
00407 }
00408 }
00409 return res;
00410 }
00411
00412 bool JackDriver::Initialize()
00413 {
00414 return true;
00415 }
00416
00417 static string RemoveLast(const string& name)
00418 {
00419 return name.substr(0, name.find_last_of(':'));
00420 }
00421
00422 void JackDriver::SaveConnections(int alias)
00423 {
00424 const char** connections;
00425 char alias1[REAL_JACK_PORT_NAME_SIZE];
00426 char alias2[REAL_JACK_PORT_NAME_SIZE];
00427 char system_alias1[REAL_JACK_PORT_NAME_SIZE];
00428 char system_alias2[REAL_JACK_PORT_NAME_SIZE];
00429 char* aliases[2];
00430 char* system_aliases[2];
00431
00432 aliases[0] = alias1;
00433 aliases[1] = alias2;
00434
00435 system_aliases[0] = system_alias1;
00436 system_aliases[1] = system_alias2;
00437
00438 fConnections.clear();
00439
00440 for (int i = 0; i < fCaptureChannels; ++i) {
00441 if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fCapturePortList[i])) != 0) {
00442 if (alias == 0) {
00443 for (int j = 0; connections[j]; j++) {
00444 JackPort* port_id = fGraphManager->GetPort(fCapturePortList[i]);
00445 fConnections.push_back(make_pair(port_id->GetType(), make_pair(port_id->GetName(), connections[j])));
00446 jack_info("Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]);
00447 }
00448 } else {
00449 int res1 = fGraphManager->GetPort(fCapturePortList[i])->GetAliases(aliases);
00450 string sub_system_name;
00451 if (res1 >= alias) {
00452 sub_system_name = aliases[alias-1];
00453 } else {
00454 sub_system_name = fGraphManager->GetPort(fCapturePortList[i])->GetName();
00455 }
00456 for (int j = 0; connections[j]; j++) {
00457 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
00458 int res2 = port_id->GetAliases(system_aliases);
00459 string sub_system;
00460 if (res2 >= alias) {
00461 sub_system = system_aliases[alias-1];
00462 } else {
00463 sub_system = connections[j];
00464 }
00465 fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_system_name, sub_system)));
00466 jack_info("Save connection: %s %s", sub_system_name.c_str(), sub_system.c_str());
00467 }
00468 }
00469 free(connections);
00470 }
00471 }
00472
00473 for (int i = 0; i < fPlaybackChannels; ++i) {
00474 if (fPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fPlaybackPortList[i])) != 0) {
00475 if (alias == 0) {
00476 for (int j = 0; connections[j]; j++) {
00477 JackPort* port_id = fGraphManager->GetPort(fPlaybackPortList[i]);
00478 fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], port_id->GetName())));
00479 jack_info("Save connection: %s %s", connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName());
00480 }
00481 } else {
00482 int res1 = fGraphManager->GetPort(fPlaybackPortList[i])->GetAliases(aliases);
00483 string sub_system_name;
00484 if (res1 >= alias) {
00485 sub_system_name = aliases[alias-1];
00486 } else {
00487 sub_system_name = fGraphManager->GetPort(fPlaybackPortList[i])->GetName();
00488 }
00489 for (int j = 0; connections[j]; j++) {
00490 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
00491 int res2 = port_id->GetAliases(system_aliases);
00492 string sub_name;
00493 if (res2 >= alias) {
00494 sub_name = system_aliases[alias-1];
00495 } else {
00496 sub_name = connections[j];
00497 }
00498 fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_name, sub_system_name)));
00499 jack_info("Save connection: %s %s", sub_name.c_str(), sub_system_name.c_str());
00500 }
00501 }
00502 free(connections);
00503 }
00504 }
00505 }
00506
00507 string JackDriver::MatchPortName(const char* name, const char** ports, int alias, const std::string& type)
00508 {
00509 char alias1[REAL_JACK_PORT_NAME_SIZE];
00510 char alias2[REAL_JACK_PORT_NAME_SIZE];
00511 char* aliases[2];
00512
00513 aliases[0] = alias1;
00514 aliases[1] = alias2;
00515
00516 for (int i = 0; ports && ports[i]; ++i) {
00517
00518 jack_port_id_t port_id2 = fGraphManager->GetPort(ports[i]);
00519 JackPort* port2 = (port_id2 != NO_PORT) ? fGraphManager->GetPort(port_id2) : NULL;
00520
00521 if (port2) {
00522 int res = port2->GetAliases(aliases);
00523 string name_str;
00524 if (res >= alias) {
00525 name_str = string(aliases[alias-1]);
00526 } else {
00527 name_str = string(ports[i]);
00528 }
00529 string sub_name = RemoveLast(name);
00530 if ((name_str.find(sub_name) != string::npos) && (type == string(port2->GetType()))) {
00531 return name_str;
00532 }
00533 }
00534 }
00535
00536 return "";
00537 }
00538
00539 void JackDriver::LoadConnections(int alias, bool full_name)
00540 {
00541 list<pair<string, pair<string, string> > >::const_iterator it;
00542
00543 if (full_name) {
00544 for (it = fConnections.begin(); it != fConnections.end(); it++) {
00545 pair<string, string> connection = (*it).second;
00546 jack_info("Load connection: %s %s", connection.first.c_str(), connection.second.c_str());
00547 fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str());
00548 }
00549 } else {
00550 const char** inputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsInput);
00551 const char** outputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsOutput);
00552
00553 for (it = fConnections.begin(); it != fConnections.end(); it++) {
00554 pair<string, string> connection = (*it).second;
00555 string real_input = MatchPortName(connection.first.c_str(), outputs, alias, (*it).first);
00556 string real_output = MatchPortName(connection.second.c_str(), inputs, alias, (*it).first);
00557 if ((real_input != "") && (real_output != "")) {
00558 jack_info("Load connection: %s %s", real_input.c_str(), real_output.c_str());
00559 fEngine->PortConnect(fClientControl.fRefNum, real_input.c_str(), real_output.c_str());
00560 }
00561 }
00562
00563
00564 if (fGraphManager->IsPendingChange()) {
00565 JackSleep(int(fEngineControl->fPeriodUsecs * 1.1f));
00566 }
00567
00568 if (inputs) {
00569 free(inputs);
00570 }
00571 if (outputs) {
00572 free(outputs);
00573 }
00574 }
00575 }
00576
00577 int JackDriver::ResumeRefNum()
00578 {
00579 return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
00580 }
00581
00582 int JackDriver::SuspendRefNum()
00583 {
00584 return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs);
00585 }
00586
00587 }