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 "JackServer.h"
00026 #include "JackTime.h"
00027 #include "JackFreewheelDriver.h"
00028 #include "JackLoopbackDriver.h"
00029 #include "JackThreadedDriver.h"
00030 #include "JackGlobals.h"
00031 #include "JackEngine.h"
00032 #include "JackAudioDriver.h"
00033 #include "JackChannel.h"
00034 #include "JackClientControl.h"
00035 #include "JackEngineControl.h"
00036 #include "JackSyncInterface.h"
00037 #include "JackGraphManager.h"
00038
00039 #ifdef __APPLE_
00040 #include <CoreFoundation/CFNotificationCenter.h>
00041 #endif
00042
00043 namespace Jack
00044 {
00045
00046 JackServer* JackServer::fInstance = NULL;
00047
00048 JackServer::JackServer(bool sync, long timeout, bool rt, long priority, long loopback, bool verbose)
00049 {
00050 JackGlobals::InitServer();
00051 for (int i = 0; i < CLIENT_NUM; i++)
00052 fSynchroTable[i] = JackGlobals::MakeSynchro();
00053 fGraphManager = new JackGraphManager();
00054 fEngineControl = new JackEngineControl();
00055 fSignal = JackGlobals::MakeInterProcessSync();
00056 fEngine = new JackEngine(fGraphManager, fSynchroTable, fEngineControl, fSignal, sync, timeout, rt, priority, verbose);
00057 fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver("freewheel", fEngine, fSynchroTable));
00058 fLoopbackDriver = new JackLoopbackDriver("loopback", fEngine, fSynchroTable);
00059 fChannel = JackGlobals::MakeServerChannel();
00060 fState = new JackConnectionManager();
00061 fFreewheel = false;
00062 fSyncMode = sync;
00063 fLoopback = loopback;
00064 fDriverInfo = NULL;
00065 fAudioDriver = NULL;
00066 fInstance = this;
00067 jack_verbose = verbose;
00068 }
00069
00070 JackServer::~JackServer()
00071 {
00072 for (int i = 0; i < CLIENT_NUM; i++)
00073 delete fSynchroTable[i];
00074 delete fGraphManager;
00075 delete fAudioDriver;
00076 delete fFreewheelDriver;
00077 delete fLoopbackDriver;
00078 delete fEngine;
00079 delete fChannel;
00080 delete fEngineControl;
00081 delete fSignal;
00082 delete fState;
00083 if (fDriverInfo) {
00084 UnloadDriverModule(fDriverInfo->handle);
00085 free(fDriverInfo);
00086 }
00087 JackGlobals::Destroy();
00088 }
00089
00090
00091
00092 int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params)
00093 {
00094 if (fChannel->Open(this) < 0) {
00095 jack_error("Server channel open error");
00096 return -1;
00097 }
00098
00099 if (fEngine->Open() != 0) {
00100 jack_error("Cannot open engine");
00101 return -1;
00102 }
00103
00104 if ((fDriverInfo = jack_load_driver(driver_desc)) == NULL) {
00105 return -1;
00106 }
00107
00108 if ((fAudioDriver = fDriverInfo->initialize(fEngine, fSynchroTable, driver_params)) == NULL) {
00109 jack_error("Cannot initialize driver");
00110 return -1;
00111 }
00112
00113 if (fFreewheelDriver->Open() != 0) {
00114 jack_error("Cannot open driver");
00115 return -1;
00116 }
00117
00118
00119 if (fLoopbackDriver->Open(fEngineControl->fBufferSize, fEngineControl->fSampleRate, 1, 1, fLoopback, fLoopback, false, "loopback", "loopback", 0, 0) != 0) {
00120 jack_error("Cannot open driver");
00121 return -1;
00122 }
00123
00124 if (fAudioDriver->Attach() != 0) {
00125 jack_error("Cannot attach audio driver");
00126 return -1;
00127 }
00128
00129 if (fLoopback > 0 && fLoopbackDriver->Attach() != 0) {
00130 jack_error("Cannot attach loopback driver");
00131 return -1;
00132 }
00133
00134 fFreewheelDriver->SetMaster(false);
00135 fAudioDriver->SetMaster(true);
00136 if (fLoopback > 0)
00137 fAudioDriver->AddSlave(fLoopbackDriver);
00138 fAudioDriver->AddSlave(fFreewheelDriver);
00139 InitTime();
00140
00141 #ifdef __APPLE__
00142
00143 CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
00144 CFSTR("com.grame.jackserver.start"),
00145 CFSTR("com.grame.jackserver"),
00146 NULL,
00147 true);
00148 #endif
00149
00150 return 0;
00151 }
00152
00153 int JackServer::Close()
00154 {
00155 JackLog("JackServer::Close\n");
00156 fChannel->Close();
00157 fSignal->Destroy();
00158 fAudioDriver->Detach();
00159 if (fLoopback > 0)
00160 fLoopbackDriver->Detach();
00161 fAudioDriver->Close();
00162 fFreewheelDriver->Close();
00163 fLoopbackDriver->Close();
00164 fEngine->Close();
00165
00166 #ifdef __APPLE__
00167
00168 CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
00169 CFSTR("com.grame.jackserver.stop"),
00170 CFSTR("com.grame.jackserver"),
00171 NULL,
00172 true);
00173 #endif
00174
00175 return 0;
00176 }
00177
00178 int JackServer::Start()
00179 {
00180 JackLog("JackServer::Start\n");
00181 fEngineControl->InitFrameTime();
00182 return fAudioDriver->Start();
00183 }
00184
00185 int JackServer::Stop()
00186 {
00187 JackLog("JackServer::Stop\n");
00188 return fAudioDriver->Stop();
00189 }
00190
00191 int JackServer::Activate(int refnum)
00192 {
00193 int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum;
00194 fGraphManager->DirectConnect(fw_refnum, refnum);
00195 fGraphManager->DirectConnect(refnum, fw_refnum);
00196 return fEngine->ClientActivate(refnum);
00197 }
00198
00199
00200
00201 int JackServer::Deactivate(int refnum)
00202 {
00203 int res = fEngine->ClientDeactivate(refnum);
00204 int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum;
00205
00206
00207 if (fGraphManager->IsDirectConnection(refnum, fw_refnum)) {
00208 fGraphManager->DirectDisconnect(refnum, fw_refnum);
00209 } else {
00210 JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum);
00211 }
00212
00213
00214 if (fGraphManager->IsDirectConnection(fw_refnum, refnum)) {
00215 fGraphManager->DirectDisconnect(fw_refnum, refnum);
00216 } else {
00217 JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum);
00218 }
00219
00220 return res;
00221 }
00222
00223 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
00224 {
00225 JackLog("JackServer::SetBufferSize nframes = %ld\n", buffer_size);
00226 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
00227
00228 if (fAudioDriver->Stop() != 0) {
00229 jack_error("Cannot stop audio driver");
00230 return -1;
00231 }
00232
00233 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
00234 fFreewheelDriver->SetBufferSize(buffer_size);
00235 fEngine->NotifyBufferSize(buffer_size);
00236 fEngineControl->InitFrameTime();
00237 return fAudioDriver->Start();
00238 } else {
00239 jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
00240 fFreewheelDriver->SetBufferSize(current_buffer_size);
00241 fEngineControl->InitFrameTime();
00242 return fAudioDriver->Start();
00243 }
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 int JackServer::SetFreewheel(bool onoff)
00259 {
00260 JackLog("JackServer::SetFreewheel state = %ld\n", onoff);
00261
00262 if (fFreewheel) {
00263 if (onoff) {
00264 return -1;
00265 } else {
00266 fFreewheel = false;
00267 fFreewheelDriver->Stop();
00268 fGraphManager->Restore(fState);
00269 fEngine->NotifyFreewheel(onoff);
00270 fFreewheelDriver->SetMaster(false);
00271 fEngineControl->InitFrameTime();
00272 return fAudioDriver->Start();
00273 }
00274 } else {
00275 if (onoff) {
00276 fFreewheel = true;
00277 fAudioDriver->Stop();
00278 fGraphManager->Save(fState);
00279 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
00280 fEngine->NotifyFreewheel(onoff);
00281 fFreewheelDriver->SetMaster(true);
00282 return fFreewheelDriver->Start();
00283 } else {
00284 return -1;
00285 }
00286 }
00287 }
00288
00289
00290 void JackServer::Notify(int refnum, int notify, int value)
00291 {
00292 switch (notify) {
00293
00294 case JackNotifyChannelInterface::kGraphOrderCallback:
00295 fEngine->NotifyGraphReorder();
00296 break;
00297
00298 case JackNotifyChannelInterface::kXRunCallback:
00299 fEngine->NotifyXRun(refnum);
00300 break;
00301
00302 case JackNotifyChannelInterface::kZombifyClient:
00303 fEngine->ZombifyClient(refnum);
00304 break;
00305
00306 case JackNotifyChannelInterface::kDeadClient:
00307 JackLog("JackServer: kDeadClient ref = %ld\n", refnum);
00308 Deactivate(refnum);
00309 fEngine->ClientClose(refnum);
00310 break;
00311 }
00312 }
00313
00314 JackEngine* JackServer::GetEngine()
00315 {
00316 return fEngine;
00317 }
00318
00319 JackSynchro** JackServer::GetSynchroTable()
00320 {
00321 return fSynchroTable;
00322 }
00323
00324 JackEngineControl* JackServer::GetEngineControl()
00325 {
00326 return fEngineControl;
00327 }
00328
00329 JackGraphManager* JackServer::GetGraphManager()
00330 {
00331 return fGraphManager;
00332 }
00333
00334 void JackServer::PrintState()
00335 {
00336 fAudioDriver->PrintState();
00337 fEngine->PrintState();
00338 }
00339
00340 }
00341