00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackSystemDeps.h"
00022 #include "JackServerGlobals.h"
00023 #include "JackTime.h"
00024 #include "JackFreewheelDriver.h"
00025 #include "JackThreadedDriver.h"
00026 #include "JackGlobals.h"
00027 #include "JackLockedEngine.h"
00028 #include "JackAudioDriver.h"
00029 #include "JackChannel.h"
00030 #include "JackClientControl.h"
00031 #include "JackEngineControl.h"
00032 #include "JackGraphManager.h"
00033 #include "JackInternalClient.h"
00034 #include "JackError.h"
00035 #include "JackMessageBuffer.h"
00036
00037 const char * jack_get_self_connect_mode_description(char mode);
00038
00039 namespace Jack
00040 {
00041
00042
00043
00044
00045 JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name)
00046 {
00047 if (rt) {
00048 jack_info("JACK server starting in realtime mode with priority %ld", priority);
00049 } else {
00050 jack_info("JACK server starting in non-realtime mode");
00051 }
00052
00053 jack_info("self-connect-mode is \"%s\"", jack_get_self_connect_mode_description(self_connect_mode));
00054
00055 fGraphManager = JackGraphManager::Allocate(port_max);
00056 fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name);
00057 fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl, self_connect_mode);
00058
00059
00060
00061
00062
00063 JackFreewheelDriver* freewheelDriver = new JackFreewheelDriver(fEngine, GetSynchroTable());
00064 fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver);
00065
00066 fFreewheelDriver = freewheelDriver;
00067 fDriverInfo = new JackDriverInfo();
00068 fAudioDriver = NULL;
00069 fFreewheel = false;
00070 JackServerGlobals::fInstance = this;
00071 JackServerGlobals::fUserCount = 1;
00072 JackGlobals::fVerbose = verbose;
00073 }
00074
00075 JackServer::~JackServer()
00076 {
00077 JackGraphManager::Destroy(fGraphManager);
00078 delete fDriverInfo;
00079 delete fThreadedFreewheelDriver;
00080 delete fEngine;
00081 delete fEngineControl;
00082 }
00083
00084 int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params)
00085 {
00086
00087 if (!JackMessageBuffer::Create()) {
00088 jack_error("Cannot create message buffer");
00089 }
00090
00091 if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) {
00092 jack_error("Cannot initialize driver");
00093 goto fail_close1;
00094 }
00095
00096 if (fRequestChannel.Open(fEngineControl->fServerName, this) < 0) {
00097 jack_error("Server channel open error");
00098 goto fail_close2;
00099 }
00100
00101 if (fEngine->Open() < 0) {
00102 jack_error("Cannot open engine");
00103 goto fail_close3;
00104 }
00105
00106 if (fFreewheelDriver->Open() < 0) {
00107 jack_error("Cannot open freewheel driver");
00108 goto fail_close4;
00109 }
00110
00111 if (fAudioDriver->Attach() < 0) {
00112 jack_error("Cannot attach audio driver");
00113 goto fail_close5;
00114 }
00115
00116 fFreewheelDriver->SetMaster(false);
00117 fAudioDriver->SetMaster(true);
00118 fAudioDriver->AddSlave(fFreewheelDriver);
00119 InitTime();
00120 SetClockSource(fEngineControl->fClockSource);
00121 return 0;
00122
00123 fail_close5:
00124 fFreewheelDriver->Close();
00125
00126 fail_close4:
00127 fEngine->Close();
00128
00129 fail_close3:
00130 fRequestChannel.Close();
00131
00132 fail_close2:
00133 fAudioDriver->Close();
00134
00135 fail_close1:
00136 JackMessageBuffer::Destroy();
00137 return -1;
00138 }
00139
00140 int JackServer::Close()
00141 {
00142 jack_log("JackServer::Close");
00143 fRequestChannel.Close();
00144 fAudioDriver->Detach();
00145 fAudioDriver->Close();
00146 fFreewheelDriver->Close();
00147 fEngine->Close();
00148
00149 JackMessageBuffer::Destroy();
00150 EndTime();
00151 return 0;
00152 }
00153
00154 int JackServer::Start()
00155 {
00156 jack_log("JackServer::Start");
00157 if (fAudioDriver->Start() < 0) {
00158 return -1;
00159 }
00160 return fRequestChannel.Start();
00161 }
00162
00163 int JackServer::Stop()
00164 {
00165 jack_log("JackServer::Stop");
00166 int res = -1;
00167
00168 if (fFreewheel) {
00169 if (fThreadedFreewheelDriver) {
00170 res = fThreadedFreewheelDriver->Stop();
00171 }
00172 } else {
00173 if (fAudioDriver) {
00174 res = fAudioDriver->Stop();
00175 }
00176 }
00177
00178 fEngine->NotifyQuit();
00179 fRequestChannel.Stop();
00180 fEngine->NotifyFailure(JackFailure | JackServerError, JACK_SERVER_FAILURE);
00181
00182 return res;
00183 }
00184
00185 bool JackServer::IsRunning()
00186 {
00187 jack_log("JackServer::IsRunning");
00188 assert(fAudioDriver);
00189 return fAudioDriver->IsRunning();
00190 }
00191
00192
00193
00194
00195
00196 int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status)
00197 {
00198 JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data);
00199 assert(client);
00200 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
00201 }
00202
00203 int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status)
00204 {
00205 JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters);
00206 assert(client);
00207 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
00208 }
00209
00210 int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status)
00211 {
00212
00213 *status = 0;
00214
00215
00216 if ((client->Init(so_name) < 0) || (client->Open(JackTools::DefaultServerName(), client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) {
00217 delete client;
00218 int my_status1 = *status | JackFailure;
00219 *status = (jack_status_t)my_status1;
00220 *int_ref = 0;
00221 return -1;
00222 } else {
00223 *int_ref = client->GetClientControl()->fRefNum;
00224 return 0;
00225 }
00226 }
00227
00228
00229
00230
00231
00232 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
00233 {
00234 jack_log("JackServer::SetBufferSize nframes = %ld", buffer_size);
00235 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
00236
00237 if (current_buffer_size == buffer_size) {
00238 jack_log("SetBufferSize: requirement for new buffer size equals current value");
00239 return 0;
00240 }
00241
00242 if (fAudioDriver->IsFixedBufferSize()) {
00243 jack_log("SetBufferSize: driver only supports a fixed buffer size");
00244 return -1;
00245 }
00246
00247 if (fAudioDriver->Stop() != 0) {
00248 jack_error("Cannot stop audio driver");
00249 return -1;
00250 }
00251
00252 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
00253 fEngine->NotifyBufferSize(buffer_size);
00254 return fAudioDriver->Start();
00255 } else {
00256 jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
00257 fAudioDriver->SetBufferSize(current_buffer_size);
00258 fAudioDriver->Start();
00259
00260 return -1;
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 int JackServer::SetFreewheel(bool onoff)
00277 {
00278 jack_log("JackServer::SetFreewheel is = %ld want = %ld", fFreewheel, onoff);
00279
00280 if (fFreewheel) {
00281 if (onoff) {
00282 return -1;
00283 } else {
00284 fFreewheel = false;
00285 fThreadedFreewheelDriver->Stop();
00286 fGraphManager->Restore(&fConnectionState);
00287 fEngine->NotifyFreewheel(onoff);
00288 fFreewheelDriver->SetMaster(false);
00289 fAudioDriver->SetMaster(true);
00290 return fAudioDriver->Start();
00291 }
00292 } else {
00293 if (onoff) {
00294 fFreewheel = true;
00295 fAudioDriver->Stop();
00296 fGraphManager->Save(&fConnectionState);
00297
00298 std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves();
00299 std::list<JackDriverInterface*>::const_iterator it;
00300 for (it = slave_list.begin(); it != slave_list.end(); it++) {
00301 JackDriver* slave = dynamic_cast<JackDriver*>(*it);
00302 assert(slave);
00303 fGraphManager->DisconnectAllPorts(slave->GetClientControl()->fRefNum);
00304 }
00305
00306 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
00307 fEngine->NotifyFreewheel(onoff);
00308 fAudioDriver->SetMaster(false);
00309 fFreewheelDriver->SetMaster(true);
00310 return fThreadedFreewheelDriver->Start();
00311 } else {
00312 return -1;
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321 void JackServer::Notify(int refnum, int notify, int value)
00322 {
00323 switch (notify) {
00324
00325 case kGraphOrderCallback:
00326 fEngine->NotifyGraphReorder();
00327 break;
00328
00329 case kXRunCallback:
00330 fEngine->NotifyClientXRun(refnum);
00331 break;
00332 }
00333 }
00334
00335
00336
00337
00338
00339 JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params)
00340 {
00341 JackDriverInfo* info = new JackDriverInfo();
00342 JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
00343
00344 if (!slave) {
00345 goto error1;
00346 }
00347 if (slave->Attach() < 0) {
00348 goto error2;
00349 }
00350
00351 slave->SetMaster(false);
00352 fAudioDriver->AddSlave(slave);
00353 return info;
00354
00355 error2:
00356 slave->Close();
00357
00358 error1:
00359 delete info;
00360 return NULL;
00361 }
00362
00363 void JackServer::RemoveSlave(JackDriverInfo* info)
00364 {
00365 JackDriverClientInterface* slave = info->GetBackend();
00366 fAudioDriver->RemoveSlave(slave);
00367 slave->Detach();
00368 slave->Close();
00369 }
00370
00371 int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params)
00372 {
00373 std::list<JackDriverInterface*> slave_list;
00374 std::list<JackDriverInterface*>::const_iterator it;
00375
00376
00377 fAudioDriver->Stop();
00378 fAudioDriver->Detach();
00379 fAudioDriver->Close();
00380
00381
00382 JackDriverInfo* info = new JackDriverInfo();
00383 JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
00384
00385 if (!master) {
00386 goto error;
00387 }
00388
00389
00390 slave_list = fAudioDriver->GetSlaves();
00391
00392
00393 for (it = slave_list.begin(); it != slave_list.end(); it++) {
00394 JackDriverInterface* slave = *it;
00395 master->AddSlave(slave);
00396 }
00397
00398
00399 delete fDriverInfo;
00400
00401
00402 fAudioDriver = master;
00403 fDriverInfo = info;
00404
00405 if (fAudioDriver->Attach() < 0) {
00406 goto error;
00407 }
00408
00409
00410 fEngine->NotifyBufferSize(fEngineControl->fBufferSize);
00411 fEngine->NotifySampleRate(fEngineControl->fSampleRate);
00412
00413
00414 fAudioDriver->SetMaster(true);
00415 return fAudioDriver->Start();
00416
00417 error:
00418 delete info;
00419 return -1;
00420 }
00421
00422
00423
00424
00425
00426 int JackServer::ReleaseTimebase(int refnum)
00427 {
00428 return fEngineControl->fTransport.ResetTimebase(refnum);
00429 }
00430
00431 int JackServer::SetTimebaseCallback(int refnum, int conditional)
00432 {
00433 return fEngineControl->fTransport.SetTimebaseMaster(refnum, conditional);
00434 }
00435
00436 JackLockedEngine* JackServer::GetEngine()
00437 {
00438 return fEngine;
00439 }
00440
00441 JackSynchro* JackServer::GetSynchroTable()
00442 {
00443 return fSynchroTable;
00444 }
00445
00446 JackEngineControl* JackServer::GetEngineControl()
00447 {
00448 return fEngineControl;
00449 }
00450
00451 JackGraphManager* JackServer::GetGraphManager()
00452 {
00453 return fGraphManager;
00454 }
00455
00456 }
00457