Jack2 1.9.7
|
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 :fClientControl(name) 00041 { 00042 assert(strlen(name) < JACK_CLIENT_NAME_SIZE); 00043 fSynchroTable = table; 00044 strcpy(fAliasName, alias); 00045 fEngine = engine; 00046 fGraphManager = NULL; 00047 fBeginDateUst = 0; 00048 fDelayedUsecs = 0.f; 00049 fIsMaster = true; 00050 fIsRunning = false; 00051 } 00052 00053 JackDriver::JackDriver() 00054 { 00055 fSynchroTable = NULL; 00056 fEngine = NULL; 00057 fGraphManager = NULL; 00058 fBeginDateUst = 0; 00059 fIsMaster = true; 00060 fIsRunning = false; 00061 } 00062 00063 JackDriver::~JackDriver() 00064 { 00065 jack_log("~JackDriver"); 00066 } 00067 00068 int JackDriver::Open() 00069 { 00070 int refnum = -1; 00071 00072 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { 00073 jack_error("Cannot allocate internal client for driver"); 00074 return -1; 00075 } 00076 00077 fClientControl.fRefNum = refnum; 00078 fClientControl.fActive = true; 00079 fEngineControl->fDriverNum++; 00080 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode 00081 SetupDriverSync(fClientControl.fRefNum, false); 00082 return 0; 00083 } 00084 00085 int JackDriver::Open(bool capturing, 00086 bool playing, 00087 int inchannels, 00088 int outchannels, 00089 bool monitor, 00090 const char* capture_driver_name, 00091 const char* playback_driver_name, 00092 jack_nframes_t capture_latency, 00093 jack_nframes_t playback_latency) 00094 { 00095 jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); 00096 jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); 00097 int refnum = -1; 00098 char name_res[JACK_CLIENT_NAME_SIZE + 1]; 00099 int status; 00100 00101 // Check name and possibly rename 00102 if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { 00103 jack_error("Client name = %s conflits with another running client", fClientControl.fName); 00104 return -1; 00105 } 00106 strcpy(fClientControl.fName, name_res); 00107 00108 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { 00109 jack_error("Cannot allocate internal client for driver"); 00110 return -1; 00111 } 00112 00113 fClientControl.fRefNum = refnum; 00114 fClientControl.fActive = true; 00115 fEngineControl->fDriverNum++; 00116 fCaptureLatency = capture_latency; 00117 fPlaybackLatency = playback_latency; 00118 00119 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE); 00120 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE); 00121 00122 strcpy(fCaptureDriverName, capture_driver_name); 00123 strcpy(fPlaybackDriverName, playback_driver_name); 00124 00125 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec 00126 if (!fEngineControl->fTimeOut) 00127 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); 00128 00129 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode 00130 SetupDriverSync(fClientControl.fRefNum, false); 00131 return 0; 00132 } 00133 00134 int JackDriver::Open(jack_nframes_t buffer_size, 00135 jack_nframes_t samplerate, 00136 bool capturing, 00137 bool playing, 00138 int inchannels, 00139 int outchannels, 00140 bool monitor, 00141 const char* capture_driver_name, 00142 const char* playback_driver_name, 00143 jack_nframes_t capture_latency, 00144 jack_nframes_t playback_latency) 00145 { 00146 jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); 00147 jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); 00148 int refnum = -1; 00149 char name_res[JACK_CLIENT_NAME_SIZE + 1]; 00150 int status; 00151 00152 // Check name and possibly rename 00153 if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { 00154 jack_error("Client name = %s conflits with another running client", fClientControl.fName); 00155 return -1; 00156 } 00157 strcpy(fClientControl.fName, name_res); 00158 00159 if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { 00160 jack_error("Cannot allocate internal client for driver"); 00161 return -1; 00162 } 00163 00164 fClientControl.fRefNum = refnum; 00165 fClientControl.fActive = true; 00166 fEngineControl->fDriverNum++; 00167 fEngineControl->fBufferSize = buffer_size; 00168 fEngineControl->fSampleRate = samplerate; 00169 fCaptureLatency = capture_latency; 00170 fPlaybackLatency = playback_latency; 00171 00172 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE); 00173 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE); 00174 00175 strcpy(fCaptureDriverName, capture_driver_name); 00176 strcpy(fPlaybackDriverName, playback_driver_name); 00177 00178 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec 00179 if (!fEngineControl->fTimeOut) 00180 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); 00181 00182 fGraphManager->SetBufferSize(buffer_size); 00183 fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode 00184 SetupDriverSync(fClientControl.fRefNum, false); 00185 return 0; 00186 } 00187 00188 int JackDriver::Close() 00189 { 00190 if (fClientControl.fRefNum >= 0) { 00191 jack_log("JackDriver::Close"); 00192 fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync 00193 fClientControl.fActive = false; 00194 fEngineControl->fDriverNum--; 00195 return fEngine->ClientInternalClose(fClientControl.fRefNum, false); 00196 } else { 00197 return -1; 00198 } 00199 } 00200 00206 void JackDriver::SetupDriverSync(int ref, bool freewheel) 00207 { 00208 if (!freewheel && !fEngineControl->fSyncMode) { 00209 jack_log("JackDriver::SetupDriverSync driver sem in flush mode"); 00210 fSynchroTable[ref].SetFlush(true); 00211 } else { 00212 jack_log("JackDriver::SetupDriverSync driver sem in normal mode"); 00213 fSynchroTable[ref].SetFlush(false); 00214 } 00215 } 00216 00217 int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) 00218 { 00219 switch (notify) { 00220 00221 case kStartFreewheelCallback: 00222 jack_log("JackDriver::kStartFreewheel"); 00223 SetupDriverSync(fClientControl.fRefNum, true); 00224 break; 00225 00226 case kStopFreewheelCallback: 00227 jack_log("JackDriver::kStopFreewheel"); 00228 SetupDriverSync(fClientControl.fRefNum, false); 00229 break; 00230 } 00231 00232 return 0; 00233 } 00234 00235 bool JackDriver::IsRealTime() const 00236 { 00237 return fEngineControl->fRealTime; 00238 } 00239 00240 void JackDriver::CycleIncTime() 00241 { 00242 fEngineControl->CycleIncTime(fBeginDateUst); 00243 } 00244 00245 void JackDriver::CycleTakeBeginTime() 00246 { 00247 fBeginDateUst = GetMicroSeconds(); // Take callback date here 00248 fEngineControl->CycleIncTime(fBeginDateUst); 00249 } 00250 00251 void JackDriver::CycleTakeEndTime() 00252 { 00253 fEndDateUst = GetMicroSeconds(); // Take end date here 00254 } 00255 00256 JackClientControl* JackDriver::GetClientControl() const 00257 { 00258 return (JackClientControl*)&fClientControl; 00259 } 00260 00261 void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin, float delayed_usecs) 00262 { 00263 fEngine->NotifyXRun(cur_cycle_begin, delayed_usecs); 00264 } 00265 00266 void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size) 00267 { 00268 fEngine->NotifyBufferSize(buffer_size); 00269 fEngineControl->InitFrameTime(); 00270 } 00271 00272 void JackDriver::NotifySampleRate(jack_nframes_t sample_rate) 00273 { 00274 fEngine->NotifySampleRate(sample_rate); 00275 fEngineControl->InitFrameTime(); 00276 } 00277 00278 void JackDriver::NotifyFailure(int code, const char* reason) 00279 { 00280 fEngine->NotifyFailure(code, reason); 00281 } 00282 00283 void JackDriver::SetMaster(bool onoff) 00284 { 00285 fIsMaster = onoff; 00286 } 00287 00288 bool JackDriver::GetMaster() 00289 { 00290 return fIsMaster; 00291 } 00292 00293 void JackDriver::AddSlave(JackDriverInterface* slave) 00294 { 00295 fSlaveList.push_back(slave); 00296 } 00297 00298 void JackDriver::RemoveSlave(JackDriverInterface* slave) 00299 { 00300 fSlaveList.remove(slave); 00301 } 00302 00303 int JackDriver::ProcessSlaves() 00304 { 00305 int res = 0; 00306 list<JackDriverInterface*>::const_iterator it; 00307 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { 00308 JackDriverInterface* slave = *it; 00309 if (slave->Process() < 0) 00310 res = -1; 00311 00312 } 00313 return res; 00314 } 00315 00316 int JackDriver::Process() 00317 { 00318 return 0; 00319 } 00320 00321 int JackDriver::ProcessNull() 00322 { 00323 return 0; 00324 } 00325 00326 int JackDriver::Attach() 00327 { 00328 return 0; 00329 } 00330 00331 int JackDriver::Detach() 00332 { 00333 return 0; 00334 } 00335 00336 int JackDriver::Read() 00337 { 00338 return 0; 00339 } 00340 00341 int JackDriver::Write() 00342 { 00343 return 0; 00344 } 00345 00346 int JackDriver::Start() 00347 { 00348 if (fIsMaster) { 00349 fEngineControl->InitFrameTime(); 00350 } 00351 fIsRunning = true; 00352 return 0; 00353 } 00354 00355 int JackDriver::StartSlaves() 00356 { 00357 int res = 0; 00358 list<JackDriverInterface*>::const_iterator it; 00359 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { 00360 JackDriverInterface* slave = *it; 00361 if (slave->Start() < 0) { 00362 res = -1; 00363 00364 // XXX: We should attempt to stop all of the slaves that we've 00365 // started here. 00366 00367 break; 00368 } 00369 } 00370 return res; 00371 } 00372 00373 int JackDriver::Stop() 00374 { 00375 fIsRunning = false; 00376 return 0; 00377 } 00378 00379 int JackDriver::StopSlaves() 00380 { 00381 int res = 0; 00382 list<JackDriverInterface*>::const_iterator it; 00383 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { 00384 JackDriverInterface* slave = *it; 00385 if (slave->Stop() < 0) 00386 res = -1; 00387 } 00388 return res; 00389 } 00390 00391 bool JackDriver::IsFixedBufferSize() 00392 { 00393 return true; 00394 } 00395 00396 int JackDriver::SetBufferSize(jack_nframes_t buffer_size) 00397 { 00398 return 0; 00399 } 00400 00401 int JackDriver::SetSampleRate(jack_nframes_t sample_rate) 00402 { 00403 return 0; 00404 } 00405 00406 bool JackDriver::Initialize() 00407 { 00408 return true; 00409 } 00410 00411 00412 } // end of namespace