Jack2  1.9.7
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     :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