00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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);
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);
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);
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);
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 }