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->ClientCheckName(fClientControl->fName)) {
00074 jack_error("client %s already registered", fClientControl->fName);
00075 return -1;
00076 }
00077
00078 if (fEngine->ClientInternalNew(fClientControl->fName, &refnum, &fEngineControl, &fGraphManager, this) != 0) {
00079 jack_error("Cannot allocate internal client for audio driver");
00080 return -1;
00081 }
00082
00083 fClientControl->fRefNum = refnum;
00084 fClientControl->fActive = true;
00085 fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum);
00086
00087
00088
00089
00090
00091 if (!fEngineControl->fSyncMode) {
00092 fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true);
00093 fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true);
00094 fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true);
00095 }
00096 return 0;
00097 }
00098
00099 int JackDriver::Open(jack_nframes_t nframes,
00100 jack_nframes_t samplerate,
00101 int capturing,
00102 int playing,
00103 int inchannels,
00104 int outchannels,
00105 bool monitor,
00106 const char* capture_driver_name,
00107 const char* playback_driver_name,
00108 jack_nframes_t capture_latency,
00109 jack_nframes_t playback_latency)
00110 {
00111 JackLog("JackDriver::Open capture_driver_name = %s\n", capture_driver_name);
00112 JackLog("JackDriver::Open playback_driver_name = %s\n", playback_driver_name);
00113 int refnum = -1;
00114
00115 if (fEngine->ClientCheckName(fClientControl->fName)) {
00116 jack_error("client %s already registered", fClientControl->fName);
00117 return -1;
00118 }
00119
00120 if (fEngine->ClientInternalNew(fClientControl->fName, &refnum, &fEngineControl, &fGraphManager, this) != 0) {
00121 jack_error("Cannot allocate internal client for audio driver");
00122 return -1;
00123 }
00124
00125 fClientControl->fRefNum = refnum;
00126 fClientControl->fActive = true;
00127 fEngineControl->fBufferSize = nframes;
00128 fEngineControl->fSampleRate = samplerate;
00129 fCaptureLatency = capture_latency;
00130 fPlaybackLatency = playback_latency;
00131
00132 assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
00133 assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);
00134
00135 strcpy(fCaptureDriverName, capture_driver_name);
00136 strcpy(fPlaybackDriverName, playback_driver_name);
00137
00138 fEngineControl->fPeriodUsecs = (jack_time_t)floor((((float)nframes) / (float)samplerate) * 1000000.0f);
00139 if (fEngineControl->fTimeOutUsecs == 0)
00140 fEngineControl->fTimeOutUsecs = (jack_time_t)(2.f * fEngineControl->fPeriodUsecs);
00141
00142 fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum);
00143
00144
00145
00146
00147
00148 if (!fEngineControl->fSyncMode) {
00149 fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true);
00150 fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true);
00151 fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true);
00152 }
00153 return 0;
00154 }
00155
00156 int JackDriver::Close()
00157 {
00158 JackLog("JackDriver::Close\n");
00159 fGraphManager->DirectDisconnect(fClientControl->fRefNum, fClientControl->fRefNum);
00160 fClientControl->fActive = false;
00161 return fEngine->ClientInternalCloseIm(fClientControl->fRefNum);
00162 }
00163
00164 bool JackDriver::IsRealTime()
00165 {
00166 return fEngineControl->fRealTime;
00167 }
00168
00169 JackClientControl* JackDriver::GetClientControl() const
00170 {
00171 return fClientControl;
00172 }
00173
00174 void JackDriver::NotifyXRun(jack_time_t callback_usecs)
00175 {
00176 fEngine->NotifyXRun(callback_usecs);
00177 }
00178
00179 void JackDriverClient::SetMaster(bool onoff)
00180 {
00181 fIsMaster = onoff;
00182 }
00183
00184 bool JackDriverClient::GetMaster()
00185 {
00186 return fIsMaster;
00187 }
00188
00189 void JackDriverClient::AddSlave(JackDriverInterface* slave)
00190 {
00191 fSlaveList.push_back(slave);
00192 }
00193
00194 void JackDriverClient::RemoveSlave(JackDriverInterface* slave)
00195 {
00196 fSlaveList.remove(slave);
00197 }
00198
00199 int JackDriverClient::ProcessSlaves()
00200 {
00201 int res = 0;
00202 list<JackDriverInterface*>::const_iterator it;
00203 for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) {
00204 JackDriverInterface* slave = *it;
00205 if (slave->Process() < 0)
00206 res = -1;
00207 }
00208 return res;
00209 }
00210
00211 }