Jack2  1.9.8
JackDriver.cpp
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