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