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 #ifdef WIN32 
00022 #pragma warning (disable : 4786)
00023 #endif
00024 
00025 #include "JackDriver.h"
00026 #include "JackTime.h"
00027 #include "JackError.h"
00028 #include "JackPort.h"
00029 #include "JackGraphManager.h"
00030 #include "JackGlobals.h"
00031 #include "JackEngineControl.h"
00032 #include "JackClientControl.h"
00033 #include "JackEngine.h"
00034 #include <math.h>
00035 #include <assert.h>
00036 
00037 using namespace std;
00038 
00039 namespace Jack
00040 {
00041 
00042 JackDriver::JackDriver(const char* name, JackEngine* engine, JackSynchro** table)
00043 {
00044     assert(strlen(name) < JACK_CLIENT_NAME_SIZE);
00045     fSynchroTable = table;
00046     fClientControl = new JackClientControl(name);
00047     fEngine = engine;
00048     fGraphManager = NULL;
00049     fLastWaitUst = 0;
00050     fIsMaster = true;
00051 }
00052 
00053 JackDriver::JackDriver()
00054 {
00055     fSynchroTable = NULL;
00056     fClientControl = NULL;
00057     fEngine = NULL;
00058     fGraphManager = NULL;
00059     fLastWaitUst = 0;
00060     fIsMaster = true;
00061 }
00062 
00063 JackDriver::~JackDriver()
00064 {
00065     JackLog("~JackDriver\n");
00066     delete fClientControl;
00067 }
00068 
00069 int JackDriver::Open()
00070 {
00071     int refnum = -1;
00072 
00073         if (fEngine->ClientInternalOpen(fClientControl->fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
00074         jack_error("Cannot allocate internal client for audio driver");
00075         return -1;
00076     }
00077 
00078     fClientControl->fRefNum = refnum;
00079     fClientControl->fActive = true;     
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(jack_nframes_t nframes,
00086                      jack_nframes_t samplerate,
00087                      bool capturing,
00088                      bool playing,
00089                      int inchannels,
00090                      int outchannels,
00091                      bool monitor,
00092                      const char* capture_driver_name,
00093                      const char* playback_driver_name,
00094                      jack_nframes_t capture_latency,
00095                      jack_nframes_t playback_latency)
00096 {
00097     JackLog("JackDriver::Open capture_driver_name = %s\n", capture_driver_name);
00098     JackLog("JackDriver::Open playback_driver_name = %s\n", playback_driver_name);
00099     int refnum = -1;
00100 
00101     if (fEngine->ClientInternalOpen(fClientControl->fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
00102         jack_error("Cannot allocate internal client for audio driver");
00103         return -1;
00104     }
00105 
00106     fClientControl->fRefNum = refnum;
00107     fClientControl->fActive = true;     
00108     fEngineControl->fBufferSize = nframes;
00109     fEngineControl->fSampleRate = samplerate;
00110     fCaptureLatency = capture_latency;
00111     fPlaybackLatency = playback_latency;
00112 
00113     assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
00114     assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
00115 
00116     strcpy(fCaptureDriverName, capture_driver_name);
00117     strcpy(fPlaybackDriverName, playback_driver_name);
00118 
00119     fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
00120     if (!fEngineControl->fTimeOut)
00121         fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
00122 
00123     fGraphManager->SetBufferSize(nframes);
00124     fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for "sync" mode
00125         SetupDriverSync(fClientControl->fRefNum, false);
00126     return 0;
00127 }
00128 
00129 int JackDriver::Close()
00130 {
00131     JackLog("JackDriver::Close\n");
00132     fGraphManager->DirectDisconnect(fClientControl->fRefNum, fClientControl->fRefNum); // Disconnect driver from itself for sync
00133     fClientControl->fActive = false;
00134     return fEngine->ClientInternalClose(fClientControl->fRefNum, false);
00135 }
00136 
00142 void JackDriver::SetupDriverSync(int ref, bool freewheel)
00143 {
00144         if (!freewheel && !fEngineControl->fSyncMode) {
00145         JackLog("JackDriver::SetupDriverSync driver sem in flush mode\n");
00146         fSynchroTable[ref]->SetFlush(true);
00147     } else {
00148         JackLog("JackDriver::SetupDriverSync driver sem in normal mode\n");
00149         fSynchroTable[ref]->SetFlush(false);
00150         }
00151 }
00152 
00153 int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2)
00154 {
00155         switch (notify) {
00156         
00157                 case kStartFreewheelCallback:
00158                         JackLog("JackDriver::kStartFreewheel\n");
00159                         SetupDriverSync(fClientControl->fRefNum, true);
00160                         break;
00161         
00162                 case kStopFreewheelCallback:
00163                         JackLog("JackDriver::kStopFreewheel\n");
00164                         SetupDriverSync(fClientControl->fRefNum, false);
00165                         break;
00166         }
00167 
00168         return 0;
00169 }
00170 
00171 bool JackDriver::IsRealTime()
00172 {
00173     return fEngineControl->fRealTime;
00174 }
00175 
00176 JackClientControl* JackDriver::GetClientControl() const
00177 {
00178     return fClientControl;
00179 }
00180 
00181 void JackDriver::NotifyXRun(jack_time_t callback_usecs)
00182 {
00183     fEngine->NotifyXRun(callback_usecs);
00184 }
00185 
00186 void JackDriverClient::SetMaster(bool onoff)
00187 {
00188     fIsMaster = onoff;
00189 }
00190 
00191 bool JackDriverClient::GetMaster()
00192 {
00193     return fIsMaster;
00194 }
00195 
00196 void JackDriverClient::AddSlave(JackDriverInterface* slave)
00197 {
00198     fSlaveList.push_back(slave);
00199 }
00200 
00201 void JackDriverClient::RemoveSlave(JackDriverInterface* slave)
00202 {
00203     fSlaveList.remove(slave);
00204 }
00205 
00206 int JackDriverClient::ProcessSlaves()
00207 {
00208         int res = 0;
00209     list<JackDriverInterface*>::const_iterator it;
00210     for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00211         JackDriverInterface* slave = *it;
00212         if (slave->Process() < 0)
00213                         res = -1;
00214     }
00215         return res;
00216 }
00217 
00218 } // end of namespace

Generated on Thu Feb 14 11:16:01 2008 for Jackdmp by  doxygen 1.5.1