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