Jack2 1.9.8
|
00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Copyright (C) 2004-2008 Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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); // Connect driver to itself for "sync" mode 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 // Check name and possibly rename 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); // in microsec 00133 if (!fEngineControl->fTimeOut) { 00134 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); 00135 } 00136 00137 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode 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 // Check name and possibly rename 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); // in microsec 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); // Connect driver to itself for "sync" mode 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); // Disconnect driver from itself for sync 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(); // Take callback date here 00259 fEngineControl->CycleIncTime(fBeginDateUst); 00260 } 00261 00262 void JackDriver::CycleTakeEndTime() 00263 { 00264 fEndDateUst = GetMicroSeconds(); // Take end date here 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 // XXX: We should attempt to stop all of the slaves that we've 00423 // started here. 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 fGraphManager->GetPort(fCapturePortList[i])->GetAliases(aliases); 00495 fConnections.push_back(make_pair(aliases[0], connections[j])); 00496 jack_info("Save connection: %s %s", aliases[0], connections[j]); 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 fGraphManager->GetPort(fPlaybackPortList[i])->GetAliases(aliases); 00510 fConnections.push_back(make_pair(connections[j], aliases[0])); 00511 jack_info("Save connection: %s %s", connections[j], aliases[0]); 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 } // end of namespace